]> source.dussan.org Git - nextcloud-server.git/commitdiff
detect system wide mount points correctly
authorBjoern Schiessle <schiessle@owncloud.com>
Wed, 15 Apr 2015 11:19:17 +0000 (13:19 +0200)
committerBjoern Schiessle <schiessle@owncloud.com>
Thu, 16 Apr 2015 12:15:04 +0000 (14:15 +0200)
lib/base.php
lib/private/encryption/keys/storage.php
lib/private/encryption/manager.php
lib/private/encryption/util.php
lib/private/server.php
tests/lib/encryption/utiltest.php
tests/lib/files/storage/wrapper/encryption.php
tests/lib/files/stream/encryption.php

index f0c54640b17c5ca85c1b3467218bfb180af171dd..80f2736fcf6ed69646186fb37d6ee2e420aa0196 100644 (file)
@@ -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(),
index 9d978193130cb7773f20658f79319eeea3199d3a..925c20c74c873532d08b4acff1c452d0afff3977 100644 (file)
@@ -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 . '/';
index 45c98baede3a57121a6099e0af0387a90b27266e..89abad4934a33dc115cb6cb26b576cdfaafa7d4e 100644 (file)
@@ -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;
index 2eed2f7ca35e67a09b9d3a181ceba64a0e2745d5..98a38012dbab740c0beae962c1d9a41f90803b4b 100644 (file)
@@ -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
         *
index e35da6a138e06e9315a6ef5419e7d4bf95fa5773..ea673ea1485044296439d368669720a90a2df94c 100644 (file)
@@ -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);
        }
 
index 03aefe6115189027b1ef5fb424abe4b65a49d57c..dc6205e16fdca2f83686d6078dbcb0e6f9218560 100644 (file)
@@ -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)
                );
        }
 
index ec3770260aa13c8e17b881ab4b2aa8dcd97ae308..3256f772df776b357884400a995ca924b59311d7 100644 (file)
@@ -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) {
index 6964d203f1822b082c4af65b56f9a40a9f2d690e..f52fd0e16cc2c9d0712fae7070c1fde6faf9bd5a 100644 (file)
@@ -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]);