Signed-off-by: Joas Schilling <coding@schilljs.com>tags/v16.0.0alpha1
@@ -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; | |||
} | |||
@@ -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 { |
@@ -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 | |||
*/ |
@@ -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; | |||
} | |||
/** |