diff options
-rw-r--r-- | core/Migrations/Version16000Date20190207141427.php (renamed from core/Migrations/Version15000Date20180917092725.php) | 26 | ||||
-rw-r--r-- | lib/private/Collaboration/Resources/Collection.php | 18 | ||||
-rw-r--r-- | lib/private/Collaboration/Resources/Manager.php | 79 | ||||
-rw-r--r-- | lib/private/Collaboration/Resources/Resource.php | 13 |
4 files changed, 127 insertions, 9 deletions
diff --git a/core/Migrations/Version15000Date20180917092725.php b/core/Migrations/Version16000Date20190207141427.php index 1bcc6382745..44e09a8463b 100644 --- a/core/Migrations/Version15000Date20180917092725.php +++ b/core/Migrations/Version16000Date20190207141427.php @@ -28,7 +28,7 @@ use OCP\DB\ISchemaWrapper; use OCP\Migration\SimpleMigrationStep; use OCP\Migration\IOutput; -class Version15000Date20180917092725 extends SimpleMigrationStep { +class Version16000Date20190207141427 extends SimpleMigrationStep { /** @@ -74,6 +74,30 @@ class Version15000Date20180917092725 extends SimpleMigrationStep { $table->addUniqueIndex(['collection_id', 'resource_type', 'resource_id'], 'collres_unique_res'); } + if (!$schema->hasTable('collres_accesscache')) { + $table = $schema->createTable('collres_accesscache'); + + $table->addColumn('user_id', Type::STRING, [ + 'notnull' => true, + 'length' => 64, + ]); + $table->addColumn('collection_id', Type::BIGINT, [ + 'notnull' => false, + ]); + $table->addColumn('resource_id', Type::STRING, [ + 'notnull' => false, + 'length' => 64, + ]); + $table->addColumn('access', Type::SMALLINT, [ + 'notnull' => true, + 'default' => 0, + ]); + + $table->addUniqueIndex(['user_id', 'collection_id', 'resource_id'], 'collres_unique_user'); + $table->addIndex(['user_id', 'resource_id'], 'collres_user_res'); + $table->addIndex(['user_id', 'collection_id'], 'collres_user_coll'); + } + return $schema; } diff --git a/lib/private/Collaboration/Resources/Collection.php b/lib/private/Collaboration/Resources/Collection.php index 5770e8918fd..c538580b8f8 100644 --- a/lib/private/Collaboration/Resources/Collection.php +++ b/lib/private/Collaboration/Resources/Collection.php @@ -46,6 +46,9 @@ class Collection implements ICollection { /** @var string */ protected $name; + /** @var bool|null */ + protected $access; + /** @var IResource[] */ protected $resources; @@ -53,12 +56,14 @@ class Collection implements ICollection { IManager $manager, IDBConnection $connection, int $id, - string $name + string $name, + ?bool $access ) { $this->manager = $manager; $this->connection = $connection; $this->id = $id; $this->name = $name; + $this->access = $access; $this->resources = []; } @@ -161,13 +166,16 @@ class Collection implements ICollection { * @since 16.0.0 */ public function canAccess(IUser $user = null): bool { - foreach ($this->getResources() as $resource) { - if ($resource->canAccess($user)) { - return true; + if ($this->access === null) { + $this->access = false; + foreach ($this->getResources() as $resource) { + if ($resource->canAccess($user)) { + $this->access = true; + } } } - return false; + return $this->access; } protected function isSameResource(IResource $resource1, IResource $resource2): bool { diff --git a/lib/private/Collaboration/Resources/Manager.php b/lib/private/Collaboration/Resources/Manager.php index 55274432d76..ae42f272c05 100644 --- a/lib/private/Collaboration/Resources/Manager.php +++ b/lib/private/Collaboration/Resources/Manager.php @@ -193,6 +193,85 @@ class Manager implements IManager { return false; } + public function cacheAccessForResource(IResource $resource, ?IUser $user, bool $access): void { + $query = $this->connection->getQueryBuilder(); + $userId = $user instanceof IUser ? $user->getUID() : ''; + + $query->insert('collres_accesscache') + ->values([ + 'user_id' => $query->createNamedParameter($userId), + 'resource_id' => $query->createNamedParameter($resource->getId()), + 'access' => $query->createNamedParameter($access), + ]); + $query->execute(); + } + + public function cacheAccessForCollection(ICollection $collection, ?IUser $user, bool $access): void { + $query = $this->connection->getQueryBuilder(); + $userId = $user instanceof IUser ? $user->getUID() : ''; + + $query->insert('collres_accesscache') + ->values([ + 'user_id' => $query->createNamedParameter($userId), + 'collection_id' => $query->createNamedParameter($collection->getId()), + 'access' => $query->createNamedParameter($access), + ]); + $query->execute(); + } + + public function invalidateAccessCacheForUser(?IUser $user): void { + $query = $this->connection->getQueryBuilder(); + $userId = $user instanceof IUser ? $user->getUID() : ''; + + $query->delete('collres_accesscache') + ->where($query->expr()->eq('user_id', $query->createNamedParameter($userId))); + $query->execute(); + } + + public function invalidateAccessCacheForResource(IResource $resource): void { + $query = $this->connection->getQueryBuilder(); + + $query->delete('collres_accesscache') + ->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId()))); + $query->execute(); + + foreach ($resource->getCollections() as $collection) { + $this->invalidateAccessCacheForCollection($collection); + } + } + + protected function invalidateAccessCacheForCollection(ICollection $collection): void { + $query = $this->connection->getQueryBuilder(); + + $query->delete('collres_accesscache') + ->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId()))); + $query->execute(); + } + + public function invalidateAccessCacheForResourceByUser(IResource $resource, ?IUser $user): void { + $query = $this->connection->getQueryBuilder(); + $userId = $user instanceof IUser ? $user->getUID() : ''; + + $query->delete('collres_accesscache') + ->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId()))) + ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId))); + $query->execute(); + + foreach ($resource->getCollections() as $collection) { + $this->invalidateAccessCacheForCollectionByUser($collection, $user); + } + } + + protected function invalidateAccessCacheForCollectionByUser(ICollection $collection, ?IUser $user): void { + $query = $this->connection->getQueryBuilder(); + $userId = $user instanceof IUser ? $user->getUID() : ''; + + $query->delete('collres_accesscache') + ->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId()))) + ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId))); + $query->execute(); + } + /** * @param IProvider $provider */ diff --git a/lib/private/Collaboration/Resources/Resource.php b/lib/private/Collaboration/Resources/Resource.php index c31843bdd06..bfc63fefdfc 100644 --- a/lib/private/Collaboration/Resources/Resource.php +++ b/lib/private/Collaboration/Resources/Resource.php @@ -26,7 +26,6 @@ namespace OC\Collaboration\Resources; use OCP\Collaboration\Resources\ICollection; use OCP\Collaboration\Resources\IManager; use OCP\Collaboration\Resources\IResource; -use OCP\Collaboration\Resources\ResourceException; use OCP\IDBConnection; use OCP\IUser; @@ -44,6 +43,9 @@ class Resource implements IResource { /** @var string */ protected $id; + /** @var bool|null */ + protected $access; + /** @var string|null */ protected $name; @@ -57,12 +59,14 @@ class Resource implements IResource { IManager $manager, IDBConnection $connection, string $type, - string $id + string $id, + ?bool $access ) { $this->manager = $manager; $this->connection = $connection; $this->type = $type; $this->id = $id; + $this->access = $access; } /** @@ -122,7 +126,10 @@ class Resource implements IResource { * @since 16.0.0 */ public function canAccess(IUser $user = null): bool { - return $this->manager->canAccess($this, $user); + if ($this->access === null) { + $this->access = $this->manager->canAccess($this, $user); + } + return $this->access; } /** |