diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php index 0c8b90935d..c755b6a29b 100644 --- a/apps/files_external/appinfo/application.php +++ b/apps/files_external/appinfo/application.php @@ -26,6 +26,7 @@ namespace OCA\Files_External\AppInfo; use \OCP\AppFramework\App; +use OCP\AppFramework\IAppContainer; use \OCP\IContainer; use \OCA\Files_External\Service\BackendService; @@ -33,9 +34,13 @@ use \OCA\Files_External\Service\BackendService; * @package OCA\Files_External\Appinfo */ class Application extends App { - public function __construct(array $urlParams=array()) { + public function __construct(array $urlParams = array()) { parent::__construct('files_external', $urlParams); + $this->getContainer()->registerService('OCP\Files\Config\IUserMountCache', function (IAppContainer $c) { + return $c->getServer()->query('UserMountCache'); + }); + $this->loadBackends(); $this->loadAuthMechanisms(); diff --git a/apps/files_external/migration/storagemigrator.php b/apps/files_external/migration/storagemigrator.php index 2da47decf9..ba81810a4f 100644 --- a/apps/files_external/migration/storagemigrator.php +++ b/apps/files_external/migration/storagemigrator.php @@ -29,6 +29,7 @@ use OCA\Files_external\Service\LegacyStoragesService; use OCA\Files_external\Service\StoragesService; use OCA\Files_external\Service\UserLegacyStoragesService; use OCA\Files_external\Service\UserStoragesService; +use OCP\Files\Config\IUserMountCache; use OCP\IConfig; use OCP\IDBConnection; use OCP\ILogger; @@ -64,6 +65,9 @@ class StorageMigrator { */ private $logger; + /** @var IUserMountCache */ + private $userMountCache; + /** * StorageMigrator constructor. * @@ -72,19 +76,22 @@ class StorageMigrator { * @param IConfig $config * @param IDBConnection $connection * @param ILogger $logger + * @param IUserMountCache $userMountCache */ public function __construct( BackendService $backendService, DBConfigService $dbConfig, IConfig $config, IDBConnection $connection, - ILogger $logger + ILogger $logger, + IUserMountCache $userMountCache ) { $this->backendService = $backendService; $this->dbConfig = $dbConfig; $this->config = $config; $this->connection = $connection; $this->logger = $logger; + $this->userMountCache = $userMountCache; } private function migrate(LegacyStoragesService $legacyService, StoragesService $storageService) { @@ -107,7 +114,7 @@ class StorageMigrator { */ public function migrateGlobal() { $legacyService = new GlobalLegacyStoragesService($this->backendService); - $storageService = new GlobalStoragesService($this->backendService, $this->dbConfig); + $storageService = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->userMountCache); $this->migrate($legacyService, $storageService); } @@ -125,7 +132,7 @@ class StorageMigrator { if (version_compare($userVersion, '0.5.0', '<')) { $this->config->setUserValue($userId, 'files_external', 'config_version', '0.5.0'); $legacyService = new UserLegacyStoragesService($this->backendService, $dummySession); - $storageService = new UserStoragesService($this->backendService, $this->dbConfig, $dummySession); + $storageService = new UserStoragesService($this->backendService, $this->dbConfig, $dummySession, $this->userMountCache); $this->migrate($legacyService, $storageService); } diff --git a/apps/files_external/service/storagesservice.php b/apps/files_external/service/storagesservice.php index c0dd263ed6..678b91c010 100644 --- a/apps/files_external/service/storagesservice.php +++ b/apps/files_external/service/storagesservice.php @@ -31,6 +31,7 @@ use \OCA\Files_external\Lib\StorageConfig; use \OCA\Files_external\NotFoundException; use \OCA\Files_External\Lib\Backend\Backend; use \OCA\Files_External\Lib\Auth\AuthMechanism; +use OCP\Files\Config\IUserMountCache; use \OCP\Files\StorageNotAvailableException; /** @@ -46,13 +47,20 @@ abstract class StoragesService { */ protected $dbConfig; + /** + * @var IUserMountCache + */ + protected $userMountCache; + /** * @param BackendService $backendService * @param DBConfigService $dbConfigService + * @param IUserMountCache $userMountCache */ - public function __construct(BackendService $backendService, DBConfigService $dbConfigService) { + public function __construct(BackendService $backendService, DBConfigService $dbConfigService, IUserMountCache $userMountCache) { $this->backendService = $backendService; $this->dbConfig = $dbConfigService; + $this->userMountCache = $userMountCache; } protected function readDBConfig() { @@ -416,6 +424,15 @@ abstract class StoragesService { $this->triggerChangeHooks($oldStorage, $updatedStorage); + if (($wasGlobal && !$isGlobal) || count($removedGroups) > 0) { // to expensive to properly handle these on the fly + $this->userMountCache->remoteStorageMounts($this->getStorageId($updatedStorage)); + } else { + $storageId = $this->getStorageId($updatedStorage); + foreach ($removedUsers as $userId) { + $this->userMountCache->removeUserStorageMount($storageId, $userId); + } + } + return $this->getStorage($id); } @@ -480,4 +497,25 @@ abstract class StoragesService { return $storageImpl->getId(); } + /** + * Construct the storage implementation + * + * @param StorageConfig $storageConfig + * @return int + */ + private function getStorageId(StorageConfig $storageConfig) { + try { + $class = $storageConfig->getBackend()->getStorageClass(); + /** @var \OC\Files\Storage\Storage $storage */ + $storage = new $class($storageConfig->getBackendOptions()); + + // auth mechanism should fire first + $storage = $storageConfig->getBackend()->wrapStorage($storage); + $storage = $storageConfig->getAuthMechanism()->wrapStorage($storage); + + return $storage->getStorageCache()->getNumericId(); + } catch (\Exception $e) { + return -1; + } + } } diff --git a/apps/files_external/service/userglobalstoragesservice.php b/apps/files_external/service/userglobalstoragesservice.php index 6407db2dd5..03c831fe97 100644 --- a/apps/files_external/service/userglobalstoragesservice.php +++ b/apps/files_external/service/userglobalstoragesservice.php @@ -25,6 +25,7 @@ namespace OCA\Files_External\Service; use \OCA\Files_external\Service\GlobalStoragesService; use \OCA\Files_External\Service\BackendService; +use OCP\Files\Config\IUserMountCache; use \OCP\IUserSession; use \OCP\IGroupManager; use \OCA\Files_External\Service\UserTrait; @@ -46,14 +47,16 @@ class UserGlobalStoragesService extends GlobalStoragesService { * @param DBConfigService $dbConfig * @param IUserSession $userSession * @param IGroupManager $groupManager + * @param IUserMountCache $userMountCache */ public function __construct( BackendService $backendService, DBConfigService $dbConfig, IUserSession $userSession, - IGroupManager $groupManager + IGroupManager $groupManager, + IUserMountCache $userMountCache ) { - parent::__construct($backendService, $dbConfig); + parent::__construct($backendService, $dbConfig, $userMountCache); $this->userSession = $userSession; $this->groupManager = $groupManager; } diff --git a/apps/files_external/service/userstoragesservice.php b/apps/files_external/service/userstoragesservice.php index 2805d9e693..d4b04de609 100644 --- a/apps/files_external/service/userstoragesservice.php +++ b/apps/files_external/service/userstoragesservice.php @@ -23,6 +23,7 @@ namespace OCA\Files_external\Service; +use OCP\Files\Config\IUserMountCache; use \OCP\IUserSession; use \OC\Files\Filesystem; @@ -44,14 +45,16 @@ class UserStoragesService extends StoragesService { * @param BackendService $backendService * @param DBConfigService $dbConfig * @param IUserSession $userSession user session + * @param IUserMountCache $userMountCache */ public function __construct( BackendService $backendService, DBConfigService $dbConfig, - IUserSession $userSession + IUserSession $userSession, + IUserMountCache $userMountCache ) { $this->userSession = $userSession; - parent::__construct($backendService, $dbConfig); + parent::__construct($backendService, $dbConfig, $userMountCache); } protected function readDBConfig() { diff --git a/apps/files_external/tests/service/globalstoragesservicetest.php b/apps/files_external/tests/service/globalstoragesservicetest.php index 7fc60efca0..6cdfbef82d 100644 --- a/apps/files_external/tests/service/globalstoragesservicetest.php +++ b/apps/files_external/tests/service/globalstoragesservicetest.php @@ -34,7 +34,7 @@ use \OCA\Files_external\Lib\StorageConfig; class GlobalStoragesServiceTest extends StoragesServiceTest { public function setUp() { parent::setUp(); - $this->service = new GlobalStoragesService($this->backendService, $this->dbConfig); + $this->service = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache); } public function tearDown() { diff --git a/apps/files_external/tests/service/storagesservicetest.php b/apps/files_external/tests/service/storagesservicetest.php index 710d804fd3..68671b599b 100644 --- a/apps/files_external/tests/service/storagesservicetest.php +++ b/apps/files_external/tests/service/storagesservicetest.php @@ -76,6 +76,11 @@ abstract class StoragesServiceTest extends \Test\TestCase { */ protected static $hookCalls; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\OCP\Files\Config\IUserMountCache + */ + protected $mountCache; + public function setUp() { parent::setUp(); $this->dbConfig = new CleaningDBConfig(\OC::$server->getDatabaseConnection()); @@ -87,6 +92,8 @@ abstract class StoragesServiceTest extends \Test\TestCase { ); \OC_Mount_Config::$skipTest = true; + $this->mountCache = $this->getMock('OCP\Files\Config\IUserMountCache'); + // prepare BackendService mock $this->backendService = $this->getMockBuilder('\OCA\Files_External\Service\BackendService') diff --git a/apps/files_external/tests/service/userglobalstoragesservicetest.php b/apps/files_external/tests/service/userglobalstoragesservicetest.php index a22e287407..baecf143c6 100644 --- a/apps/files_external/tests/service/userglobalstoragesservicetest.php +++ b/apps/files_external/tests/service/userglobalstoragesservicetest.php @@ -94,7 +94,8 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest { $this->backendService, $this->dbConfig, $userSession, - $this->groupManager + $this->groupManager, + $this->mountCache ); } diff --git a/apps/files_external/tests/service/userstoragesservicetest.php b/apps/files_external/tests/service/userstoragesservicetest.php index bf0efc13cf..37423cb8d7 100644 --- a/apps/files_external/tests/service/userstoragesservicetest.php +++ b/apps/files_external/tests/service/userstoragesservicetest.php @@ -49,7 +49,7 @@ class UserStoragesServiceTest extends StoragesServiceTest { public function setUp() { parent::setUp(); - $this->globalStoragesService = new GlobalStoragesService($this->backendService, $this->dbConfig); + $this->globalStoragesService = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache); $this->userId = $this->getUniqueID('user_'); $this->createUser($this->userId, $this->userId); @@ -62,7 +62,7 @@ class UserStoragesServiceTest extends StoragesServiceTest { ->method('getUser') ->will($this->returnValue($this->user)); - $this->service = new UserStoragesService($this->backendService, $this->dbConfig, $userSession); + $this->service = new UserStoragesService($this->backendService, $this->dbConfig, $userSession, $this->mountCache); } private function makeTestStorageData() { diff --git a/lib/private/files/config/usermountcache.php b/lib/private/files/config/usermountcache.php index e60c6d0400..5fa192d105 100644 --- a/lib/private/files/config/usermountcache.php +++ b/lib/private/files/config/usermountcache.php @@ -230,4 +230,21 @@ class UserMountCache implements IUserMountCache { ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($user->getUID()))); $query->execute(); } + + public function removeUserStorageMount($storageId, $userId) { + $builder = $this->connection->getQueryBuilder(); + + $query = $builder->delete('mounts') + ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($userId))) + ->andWhere($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, \PDO::PARAM_INT))); + $query->execute(); + } + + public function remoteStorageMounts($storageId) { + $builder = $this->connection->getQueryBuilder(); + + $query = $builder->delete('mounts') + ->where($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, \PDO::PARAM_INT))); + $query->execute(); + } } diff --git a/lib/public/files/config/iusermountcache.php b/lib/public/files/config/iusermountcache.php index 888e5d41e2..f722ad1631 100644 --- a/lib/public/files/config/iusermountcache.php +++ b/lib/public/files/config/iusermountcache.php @@ -67,4 +67,23 @@ interface IUserMountCache { * @since 9.0.0 */ public function removeUserMounts(IUser $user); + + /** + * Remove all mounts for a user and storage + * + * @param $storageId + * @param string $userId + * @return mixed + * @since 9.0.0 + */ + public function removeUserStorageMount($storageId, $userId); + + /** + * Remove all cached mounts for a storage + * + * @param $storageId + * @return mixed + * @since 9.0.0 + */ + public function remoteStorageMounts($storageId); }