diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2013-09-30 10:42:05 +0200 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2013-09-30 10:42:05 +0200 |
commit | 629faf6d343e7906322d125718f97d3ac2f9569b (patch) | |
tree | 199d65b12eb3b09931de62d0302f9715ae294a41 | |
parent | 5462e199d391a1e4c9858bfd8444366a1047fa7f (diff) | |
parent | 5899485ca17045e93528c29d1ed63b02192c4191 (diff) | |
download | nextcloud-server-629faf6d343e7906322d125718f97d3ac2f9569b.tar.gz nextcloud-server-629faf6d343e7906322d125718f97d3ac2f9569b.zip |
Merge branch 'master' into appframework-master
-rw-r--r-- | lib/connector/sabre/directory.php | 8 | ||||
-rw-r--r-- | lib/connector/sabre/file.php | 9 | ||||
-rw-r--r-- | lib/connector/sabre/node.php | 11 | ||||
-rw-r--r-- | lib/connector/sabre/objecttree.php | 44 | ||||
-rw-r--r-- | lib/preview/txt.php | 10 | ||||
-rwxr-xr-x | lib/util.php | 9 | ||||
-rw-r--r-- | tests/data/testcal.ics | 13 | ||||
-rw-r--r-- | tests/data/testcontact.vcf | 6 | ||||
-rw-r--r-- | tests/lib/connector/sabre/objecttree.php | 87 | ||||
-rw-r--r-- | tests/lib/preview.php | 43 |
10 files changed, 225 insertions, 15 deletions
diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 3181a4b310f..a50098df793 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -88,7 +88,13 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa } // rename to correct path - \OC\Files\Filesystem::rename($partpath, $newPath); + $renameOkay = \OC\Files\Filesystem::rename($partpath, $newPath); + $fileExists = \OC\Files\Filesystem::file_exists($newPath); + if ($renameOkay === false || $fileExists === false) { + \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); + \OC\Files\Filesystem::unlink($partpath); + throw new Sabre_DAV_Exception(); + } // allow sync clients to send the mtime along in a header $mtime = OC_Request::hasModificationTime(); diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index 61bdcd5e0ae..433b1148552 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -74,7 +74,14 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D } // rename to correct path - \OC\Files\Filesystem::rename($partpath, $this->path); + $renameOkay = \OC\Files\Filesystem::rename($partpath, $this->path); + $fileExists = \OC\Files\Filesystem::file_exists($this->path); + if ($renameOkay === false || $fileExists === false) { + \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); + \OC\Files\Filesystem::unlink($partpath); + throw new Sabre_DAV_Exception(); + } + //allow sync clients to send the mtime along in a header $mtime = OC_Request::hasModificationTime(); diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index 0bffa58af78..29b7f9e53a5 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -78,6 +78,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr */ public function setName($name) { + // rename is only allowed if the update privilege is granted + if (!\OC\Files\Filesystem::isUpdatable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); @@ -135,6 +140,12 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * Even if the modification time is set to a custom value the access time is set to now. */ public function touch($mtime) { + + // touch is only allowed if the update privilege is granted + if (!\OC\Files\Filesystem::isUpdatable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + \OC\Files\Filesystem::touch($this->path, $mtime); } diff --git a/lib/connector/sabre/objecttree.php b/lib/connector/sabre/objecttree.php index acff45ed5e2..80c3840b99d 100644 --- a/lib/connector/sabre/objecttree.php +++ b/lib/connector/sabre/objecttree.php @@ -11,6 +11,14 @@ namespace OC\Connector\Sabre; use OC\Files\Filesystem; class ObjectTree extends \Sabre_DAV_ObjectTree { + + /** + * keep this public to allow mock injection during unit test + * + * @var \OC\Files\View + */ + public $fileView; + /** * Returns the INode object for the requested path * @@ -21,14 +29,16 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { public function getNodeForPath($path) { $path = trim($path, '/'); - if (isset($this->cache[$path])) return $this->cache[$path]; + if (isset($this->cache[$path])) { + return $this->cache[$path]; + } // Is it the root node? if (!strlen($path)) { return $this->rootNode; } - $info = Filesystem::getFileInfo($path); + $info = $this->getFileView()->getFileInfo($path); if (!$info) { throw new \Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located'); @@ -64,7 +74,25 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { list($sourceDir,) = \Sabre_DAV_URLUtil::splitPath($sourcePath); list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destinationPath); - Filesystem::rename($sourcePath, $destinationPath); + // check update privileges + $fs = $this->getFileView(); + if (!$fs->isUpdatable($sourcePath)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + if ($sourceDir !== $destinationDir) { + // for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir + if (!$fs->isUpdatable($sourceDir)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + if (!$fs->isUpdatable($destinationDir)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + } + + $renameOkay = $fs->rename($sourcePath, $destinationPath); + if (!$renameOkay) { + throw new \Sabre_DAV_Exception_Forbidden(''); + } $this->markDirty($sourceDir); $this->markDirty($destinationDir); @@ -101,4 +129,14 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destination); $this->markDirty($destinationDir); } + + /** + * @return \OC\Files\View + */ + public function getFileView() { + if (is_null($this->fileView)) { + $this->fileView = \OC\Files\Filesystem::getView(); + } + return $this->fileView; + } } diff --git a/lib/preview/txt.php b/lib/preview/txt.php index a487330691e..77e728eb364 100644 --- a/lib/preview/txt.php +++ b/lib/preview/txt.php @@ -9,11 +9,21 @@ namespace OC\Preview; class TXT extends Provider { + private static $blacklist = array( + 'text/calendar', + 'text/vcard', + ); + public function getMimeType() { return '/text\/.*/'; } public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + $mimetype = $fileview->getMimeType($path); + if(in_array($mimetype, self::$blacklist)) { + return false; + } + $content = $fileview->fopen($path, 'r'); $content = stream_get_contents($content); diff --git a/lib/util.php b/lib/util.php index 41f5f1d16be..d4f4eed1ca7 100755 --- a/lib/util.php +++ b/lib/util.php @@ -730,12 +730,6 @@ class OC_Util { 'baseUri' => OC_Helper::linkToRemote('webdav'), ); - // save the old timeout so that we can restore it later - $oldTimeout = ini_get("default_socket_timeout"); - - // use a 5 sec timeout for the check. Should be enough for local requests. - ini_set("default_socket_timeout", 5); - $client = new \Sabre_DAV_Client($settings); // for this self test we don't care if the ssl certificate is self signed and the peer cannot be verified. @@ -752,9 +746,6 @@ class OC_Util { $return = false; } - // restore the original timeout - ini_set("default_socket_timeout", $oldTimeout); - return $return; } diff --git a/tests/data/testcal.ics b/tests/data/testcal.ics new file mode 100644 index 00000000000..e05f01ba1c2 --- /dev/null +++ b/tests/data/testcal.ics @@ -0,0 +1,13 @@ +BEGIN:VCALENDAR +PRODID:-//some random cal software//EN +VERSION:2.0 +BEGIN:VEVENT +CREATED:20130102T120000Z +LAST-MODIFIED:20130102T120000Z +DTSTAMP:20130102T120000Z +UID:f106ecdf-c716-43ef-9d94-4e6f19f2fcfb +SUMMARY:a test cal file +DTSTART;VALUE=DATE:20130101 +DTEND;VALUE=DATE:20130102 +END:VEVENT +END:VCALENDAR
\ No newline at end of file diff --git a/tests/data/testcontact.vcf b/tests/data/testcontact.vcf new file mode 100644 index 00000000000..2af963d6916 --- /dev/null +++ b/tests/data/testcontact.vcf @@ -0,0 +1,6 @@ +BEGIN:VCARD +VERSION:3.0 +PRODID:-//some random contact software//EN +N:def;abc;;; +FN:abc def +END:VCARD
\ No newline at end of file diff --git a/tests/lib/connector/sabre/objecttree.php b/tests/lib/connector/sabre/objecttree.php new file mode 100644 index 00000000000..1d76bb59676 --- /dev/null +++ b/tests/lib/connector/sabre/objecttree.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright (c) 2013 Thomas Müller <thomas.mueller@tmit.eu> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\OC\Connector\Sabre; + + +use OC_Connector_Sabre_Directory; +use PHPUnit_Framework_TestCase; +use Sabre_DAV_Exception_Forbidden; + +class TestDoubleFileView extends \OC\Files\View{ + + public function __construct($updatables, $canRename = true) { + $this->updatables = $updatables; + $this->canRename = $canRename; + } + + public function isUpdatable($path) { + return $this->updatables[$path]; + } + + public function rename($path1, $path2) { + return $this->canRename; + } +} + +class ObjectTree extends PHPUnit_Framework_TestCase { + + /** + * @dataProvider moveFailedProvider + * @expectedException Sabre_DAV_Exception_Forbidden + */ + public function testMoveFailed($source, $dest, $updatables) { + $this->moveTest($source, $dest, $updatables); + } + + /** + * @dataProvider moveSuccessProvider + */ + public function testMoveSuccess($source, $dest, $updatables) { + $this->moveTest($source, $dest, $updatables); + $this->assertTrue(true); + } + + function moveFailedProvider() { + return array( + array('a/b', 'a/c', array('a' => false, 'a/b' => false, 'a/c' => false)), + array('a/b', 'b/b', array('a' => false, 'a/b' => false, 'b' => false, 'b/b' => false)), + array('a/b', 'b/b', array('a' => false, 'a/b' => true, 'b' => false, 'b/b' => false)), + array('a/b', 'b/b', array('a' => true, 'a/b' => true, 'b' => false, 'b/b' => false)), + ); + } + + function moveSuccessProvider() { + return array( + array('a/b', 'a/c', array('a' => false, 'a/b' => true, 'a/c' => false)), + array('a/b', 'b/b', array('a' => true, 'a/b' => true, 'b' => true, 'b/b' => false)), + ); + } + + /** + * @param $source + * @param $dest + * @param $updatables + */ + private function moveTest($source, $dest, $updatables) { + $rootDir = new OC_Connector_Sabre_Directory(''); + $objectTree = $this->getMock('\OC\Connector\Sabre\ObjectTree', + array('nodeExists', 'getNodeForPath'), + array($rootDir)); + + $objectTree->expects($this->once()) + ->method('getNodeForPath') + ->with($this->identicalTo($source)) + ->will($this->returnValue(false)); + + /** @var $objectTree \OC\Connector\Sabre\ObjectTree */ + $objectTree->fileView = new TestDoubleFileView($updatables); + $objectTree->move($source, $dest); + } + +} diff --git a/tests/lib/preview.php b/tests/lib/preview.php index bebdc12b500..d0cdd2c44fb 100644 --- a/tests/lib/preview.php +++ b/tests/lib/preview.php @@ -92,6 +92,47 @@ class Preview extends \PHPUnit_Framework_TestCase { $this->assertEquals($image->height(), $maxY); } + public function txtBlacklist() { + $txt = 'random text file'; + $ics = file_get_contents(__DIR__ . '/../data/testcal.ics'); + $vcf = file_get_contents(__DIR__ . '/../data/testcontact.vcf'); + + return array( + array('txt', $txt, false), + array('ics', $ics, true), + array('vcf', $vcf, true), + ); + } + + /** + * @dataProvider txtBlacklist + */ + public function testIsTransparent($extension, $data, $expectedResult) { + $user = $this->initFS(); + + $rootView = new \OC\Files\View(''); + $rootView->mkdir('/'.$user); + $rootView->mkdir('/'.$user.'/files'); + + $x = 32; + $y = 32; + + $sample = '/'.$user.'/files/test.'.$extension; + $rootView->file_put_contents($sample, $data); + $preview = new \OC\Preview($user, 'files/', 'test.'.$extension, $x, $y); + $image = $preview->getPreview(); + $resource = $image->resource(); + + //http://stackoverflow.com/questions/5702953/imagecolorat-and-transparency + $colorIndex = imagecolorat($resource, 1, 1); + $colorInfo = imagecolorsforindex($resource, $colorIndex); + $this->assertEquals( + $expectedResult, + $colorInfo['alpha'] === 127, + 'Failed asserting that only previews for text files are transparent.' + ); + } + private function initFS() { if(\OC\Files\Filesystem::getView()){ $user = \OC_User::getUser(); @@ -105,4 +146,4 @@ class Preview extends \PHPUnit_Framework_TestCase { return $user; } -}
\ No newline at end of file +} |