From: Bjoern Schiessle Date: Wed, 15 Apr 2015 11:19:17 +0000 (+0200) Subject: detect system wide mount points correctly X-Git-Tag: v8.1.0alpha2~60^2~1 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b25c06f5769fbcd90a780cbce90998a38c112043;p=nextcloud-server.git detect system wide mount points correctly --- diff --git a/lib/base.php b/lib/base.php index f0c54640b17..80f2736fcf6 100644 --- a/lib/base.php +++ b/lib/base.php @@ -728,6 +728,7 @@ class OC { new \OC\Encryption\Util( new \OC\Files\View(), \OC::$server->getUserManager(), + \OC::$server->getGroupManager(), \OC::$server->getConfig()), \OC\Files\Filesystem::getMountManager(), \OC::$server->getEncryptionManager(), diff --git a/lib/private/encryption/keys/storage.php b/lib/private/encryption/keys/storage.php index 9d978193130..925c20c74c8 100644 --- a/lib/private/encryption/keys/storage.php +++ b/lib/private/encryption/keys/storage.php @@ -266,7 +266,7 @@ class Storage implements \OCP\Encryption\Keys\IStorage { $filename = $this->util->stripPartialFileExtension($filename); // in case of system wide mount points the keys are stored directly in the data directory - if ($this->util->isSystemWideMountPoint($filename)) { + if ($this->util->isSystemWideMountPoint($filename, $owner)) { $keyPath = $this->keys_base_dir . $filename . '/'; } else { $keyPath = '/' . $owner . $this->keys_base_dir . $filename . '/'; @@ -287,7 +287,7 @@ class Storage implements \OCP\Encryption\Keys\IStorage { list($owner, $source) = $this->util->getUidAndFilename($source); list(, $target) = $this->util->getUidAndFilename($target); - $systemWide = $this->util->isSystemWideMountPoint($target); + $systemWide = $this->util->isSystemWideMountPoint($target, $owner); if ($systemWide) { $sourcePath = $this->keys_base_dir . $source . '/'; @@ -315,7 +315,7 @@ class Storage implements \OCP\Encryption\Keys\IStorage { list($owner, $source) = $this->util->getUidAndFilename($source); list(, $target) = $this->util->getUidAndFilename($target); - $systemWide = $this->util->isSystemWideMountPoint($target); + $systemWide = $this->util->isSystemWideMountPoint($target, $owner); if ($systemWide) { $sourcePath = $this->keys_base_dir . $source . '/'; diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php index 45c98baede3..89abad4934a 100644 --- a/lib/private/encryption/manager.php +++ b/lib/private/encryption/manager.php @@ -216,7 +216,11 @@ class Manager implements IManager { if (!($storage instanceof Shared)) { $manager = \OC::$server->getEncryptionManager(); $util = new Util( - new View(), \OC::$server->getUserManager(), \OC::$server->getConfig()); + new View(), + \OC::$server->getUserManager(), + \OC::$server->getGroupManager(), + \OC::$server->getConfig() + ); $user = \OC::$server->getUserSession()->getUser(); $logger = \OC::$server->getLogger(); $uid = $user ? $user->getUID() : null; diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php index 2eed2f7ca35..98a38012dba 100644 --- a/lib/private/encryption/util.php +++ b/lib/private/encryption/util.php @@ -66,15 +66,20 @@ class Util { /** @var array paths excluded from encryption */ protected $excludedPaths; + /** @var \OC\Group\Manager $manager */ + protected $groupManager; + /** * * @param \OC\Files\View $view * @param \OC\User\Manager $userManager + * @param \OC\Group\Manager $groupManager * @param IConfig $config */ public function __construct( \OC\Files\View $view, \OC\User\Manager $userManager, + \OC\Group\Manager $groupManager, IConfig $config) { $this->ocHeaderKeys = [ @@ -83,6 +88,7 @@ class Util { $this->view = $view; $this->userManager = $userManager; + $this->groupManager = $groupManager; $this->config = $config; $this->excludedPaths[] = 'files_encryption'; @@ -304,15 +310,15 @@ class Util { /** * check if the file is stored on a system wide mount point * @param string $path relative to /data/user with leading '/' + * @param string $uid * @return boolean */ - public function isSystemWideMountPoint($path) { - $normalizedPath = ltrim($path, '/'); + public function isSystemWideMountPoint($path, $uid) { if (\OCP\App::isEnabled("files_external")) { $mounts = \OC_Mount_Config::getSystemMountPoints(); foreach ($mounts as $mount) { - if ($mount['mountpoint'] == substr($normalizedPath, 0, strlen($mount['mountpoint']))) { - if ($this->isMountPointApplicableToUser($mount)) { + if (strpos($path, '/files/' . $mount['mountpoint']) === 0) { + if ($this->isMountPointApplicableToUser($mount, $uid)) { return true; } } @@ -321,6 +327,29 @@ class Util { return false; } + /** + * check if mount point is applicable to user + * + * @param array $mount contains $mount['applicable']['users'], $mount['applicable']['groups'] + * @param string $uid + * @return boolean + */ + private function isMountPointApplicableToUser($mount, $uid) { + $acceptedUids = array('all', $uid); + // check if mount point is applicable for the user + $intersection = array_intersect($acceptedUids, $mount['applicable']['users']); + if (!empty($intersection)) { + return true; + } + // check if mount point is applicable for group where the user is a member + foreach ($mount['applicable']['groups'] as $gid) { + if ($this->groupManager->isInGroup($uid, $gid)) { + return true; + } + } + return false; + } + /** * check if it is a path which is excluded by ownCloud from encryption * diff --git a/lib/private/server.php b/lib/private/server.php index e35da6a138e..ea673ea1485 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -88,7 +88,12 @@ class Server extends SimpleContainer implements IServerContainer { }); $this->registerService('EncryptionFileHelper', function (Server $c) { - $util = new \OC\Encryption\Util(new \OC\Files\View(), $c->getUserManager(), $c->getConfig()); + $util = new \OC\Encryption\Util( + new \OC\Files\View(), + $c->getUserManager(), + $c->getGroupManager(), + $c->getConfig() + ); return new Encryption\File($util); }); @@ -437,7 +442,12 @@ class Server extends SimpleContainer implements IServerContainer { */ function getEncryptionKeyStorage($encryptionModuleId) { $view = new \OC\Files\View(); - $util = new \OC\Encryption\Util($view, \OC::$server->getUserManager(), \OC::$server->getConfig()); + $util = new \OC\Encryption\Util( + $view, + \OC::$server->getUserManager(), + \OC::$server->getGroupManager(), + \OC::$server->getConfig() + ); return $this->query('EncryptionKeyStorageFactory')->get($encryptionModuleId, $view, $util); } diff --git a/tests/lib/encryption/utiltest.php b/tests/lib/encryption/utiltest.php index 03aefe61151..dc6205e16fd 100644 --- a/tests/lib/encryption/utiltest.php +++ b/tests/lib/encryption/utiltest.php @@ -20,9 +20,15 @@ class UtilTest extends TestCase { /** @var \PHPUnit_Framework_MockObject_MockObject */ protected $userManager; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $groupManager; + /** @var \PHPUnit_Framework_MockObject_MockObject */ private $config; + /** @var \OC\Encryption\Util */ + private $util; + public function setUp() { parent::setUp(); $this->view = $this->getMockBuilder('OC\Files\View') @@ -33,18 +39,28 @@ class UtilTest extends TestCase { ->disableOriginalConstructor() ->getMock(); + $this->groupManager = $this->getMockBuilder('OC\Group\Manager') + ->disableOriginalConstructor() + ->getMock(); + $this->config = $this->getMockBuilder('OCP\IConfig') ->disableOriginalConstructor() ->getMock(); + $this->util = new Util( + $this->view, + $this->userManager, + $this->groupManager, + $this->config + ); + } /** * @dataProvider providesHeadersForEncryptionModule */ public function testGetEncryptionModuleId($expected, $header) { - $u = new Util($this->view, $this->userManager, $this->config); - $id = $u->getEncryptionModuleId($header); + $id = $this->util->getEncryptionModuleId($header); $this->assertEquals($expected, $id); } @@ -61,8 +77,7 @@ class UtilTest extends TestCase { */ public function testReadHeader($header, $expected, $moduleId) { $expected['oc_encryption_module'] = $moduleId; - $u = new Util($this->view, $this->userManager, $this->config); - $result = $u->readHeader($header); + $result = $this->util->readHeader($header); $this->assertSameSize($expected, $result); foreach ($expected as $key => $value) { $this->assertArrayHasKey($key, $result); @@ -78,8 +93,7 @@ class UtilTest extends TestCase { $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); $em->expects($this->any())->method('getId')->willReturn($moduleId); - $u = new Util($this->view, $this->userManager, $this->config); - $result = $u->createHeader($header, $em); + $result = $this->util->createHeader($header, $em); $this->assertEquals($expected, $result); } @@ -102,23 +116,20 @@ class UtilTest extends TestCase { $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); $em->expects($this->any())->method('getId')->willReturn('moduleId'); - $u = new Util($this->view, $this->userManager, $this->config); - $u->createHeader($header, $em); + $this->util->createHeader($header, $em); } /** * @dataProvider providePathsForTestIsExcluded */ - public function testIsEcluded($path, $expected) { + public function testIsExcluded($path, $expected) { $this->userManager ->expects($this->any()) ->method('userExists') ->will($this->returnCallback(array($this, 'isExcludedCallback'))); - $u = new Util($this->view, $this->userManager, $this->config); - $this->assertSame($expected, - $u->isExcluded($path) + $this->util->isExcluded($path) ); } diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index ec3770260aa..3256f772df7 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -34,8 +34,11 @@ class Encryption extends \Test\Files\Storage\Storage { $config = $this->getMockBuilder('\OCP\IConfig') ->disableOriginalConstructor() ->getMock(); + $groupManager = $this->getMockBuilder('\OC\Group\Manager') + ->disableOriginalConstructor() + ->getMock(); - $util = $this->getMock('\OC\Encryption\Util', ['getUidAndFilename'], [new View(), new \OC\User\Manager(), $config]); + $util = $this->getMock('\OC\Encryption\Util', ['getUidAndFilename'], [new View(), new \OC\User\Manager(), $groupManager, $config]); $util->expects($this->any()) ->method('getUidAndFilename') ->willReturnCallback(function ($path) { diff --git a/tests/lib/files/stream/encryption.php b/tests/lib/files/stream/encryption.php index 6964d203f18..f52fd0e16cc 100644 --- a/tests/lib/files/stream/encryption.php +++ b/tests/lib/files/stream/encryption.php @@ -27,12 +27,15 @@ class Encryption extends \Test\TestCase { $config = $this->getMockBuilder('\OCP\IConfig') ->disableOriginalConstructor() ->getMock(); + $groupManager = $this->getMockBuilder('\OC\Group\Manager') + ->disableOriginalConstructor() + ->getMock(); $file = $this->getMockBuilder('\OC\Encryption\File') ->disableOriginalConstructor() ->setMethods(['getAccessList']) ->getMock(); $file->expects($this->any())->method('getAccessList')->willReturn([]); - $util = $this->getMock('\OC\Encryption\Util', ['getUidAndFilename'], [new View(), new \OC\User\Manager(), $config]); + $util = $this->getMock('\OC\Encryption\Util', ['getUidAndFilename'], [new View(), new \OC\User\Manager(), $groupManager, $config]); $util->expects($this->any()) ->method('getUidAndFilename') ->willReturn(['user1', $internalPath]);