Browse Source

feat: listen to user/group events and update external storage mounts

Signed-off-by: Robin Appelman <robin@icewind.nl>
Robin Appelman 6 days ago
parent
commit
fbbbc26146
No known key found for this signature in database GPG Key ID: 42B69D8A64526EFB
  1. 10
      apps/files_external/lib/AppInfo/Application.php
  2. 26
      apps/files_external/lib/Service/DBConfigService.php
  3. 38
      apps/files_external/lib/Service/GlobalStoragesService.php
  4. 54
      apps/files_external/lib/Service/MountCacheService.php
  5. 1
      apps/files_external/lib/Service/UserGlobalStoragesService.php

10
apps/files_external/lib/AppInfo/Application.php

@ -54,7 +54,11 @@ use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\QueryException;
use OCP\Files\Config\IMountProviderCollection;
use OCP\Group\Events\BeforeGroupDeletedEvent;
use OCP\Group\Events\GroupDeletedEvent;
use OCP\Group\Events\UserAddedEvent;
use OCP\Group\Events\UserRemovedEvent;
use OCP\User\Events\UserCreatedEvent;
use OCP\User\Events\UserDeletedEvent;
/**
@ -76,9 +80,15 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide
$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
$context->registerEventListener(GroupDeletedEvent::class, GroupDeletedListener::class);
$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class);
$context->registerEventListener(StorageCreatedEvent::class, MountCacheService::class);
$context->registerEventListener(StorageDeletedEvent::class, MountCacheService::class);
$context->registerEventListener(StorageUpdatedEvent::class, MountCacheService::class);
$context->registerEventListener(BeforeGroupDeletedEvent::class, MountCacheService::class);
$context->registerEventListener(UserCreatedEvent::class, MountCacheService::class);
$context->registerEventListener(UserAddedEvent::class, MountCacheService::class);
$context->registerEventListener(UserRemovedEvent::class, MountCacheService::class);
$context->registerConfigLexicon(ConfigLexicon::class);
}

26
apps/files_external/lib/Service/DBConfigService.php

@ -80,6 +80,32 @@ class DBConfigService {
return $this->getMountsFromQuery($query);
}
public function getMountsForGroupos($groupIds) {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
->from('external_mounts', 'm')
->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
->where($builder->expr()->andX( // mounts for group
$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GROUP, IQueryBuilder::PARAM_INT)),
$builder->expr()->in('a.value', $builder->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)),
));
return $this->getMountsFromQuery($query);
}
public function getGlobalMounts() {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
->from('external_mounts', 'm')
->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
->where($builder->expr()->andX( // global mounts
$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GLOBAL, IQueryBuilder::PARAM_INT)),
$builder->expr()->isNull('a.value'),
), );
return $this->getMountsFromQuery($query);
}
public function modifyMountsOnUserDelete(string $uid): void {
$this->modifyMountsOnDelete($uid, self::APPLICABLE_TYPE_USER);
}

38
apps/files_external/lib/Service/GlobalStoragesService.php

@ -13,6 +13,7 @@ use OCA\Files_External\Event\StorageDeletedEvent;
use OCA\Files_External\Event\StorageUpdatedEvent;
use OCA\Files_External\Lib\StorageConfig;
use OCA\Files_External\MountConfig;
use OCP\IGroup;
/**
* Service class to manage global external storage
@ -169,4 +170,41 @@ class GlobalStoragesService extends StoragesService {
return array_combine($keys, $configs);
}
/**
* Gets all storages for the group, not including any global storages
* @return StorageConfig[]
*/
public function getAllStoragesForGroup(IGroup $group): array {
$mounts = $this->dbConfig->getMountsForGroupos([$group->getGID()]);
$configs = array_map([$this, 'getStorageConfigFromDBMount'], $mounts);
$configs = array_filter($configs, function ($config) {
return $config instanceof StorageConfig;
});
$keys = array_map(function (StorageConfig $config) {
return $config->getId();
}, $configs);
$storages = array_combine($keys, $configs);
return array_filter($storages, [$this, 'validateStorage']);
}
/**
* @return StorageConfig[]
*/
public function getAllGlobalStorages(): array {
$mounts = $this->dbConfig->getGlobalMounts();
$configs = array_map([$this, 'getStorageConfigFromDBMount'], $mounts);
$configs = array_filter($configs, function ($config) {
return $config instanceof StorageConfig;
});
$keys = array_map(function (StorageConfig $config) {
return $config->getId();
}, $configs);
$storages = array_combine($keys, $configs);
return array_filter($storages, [$this, 'validateStorage']);
}
}

54
apps/files_external/lib/Service/MountCacheService.php

@ -20,16 +20,19 @@ use OCP\EventDispatcher\Event as T;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\IMimeTypeLoader;
use OCP\Group\Events\BeforeGroupDeletedEvent;
use OCP\Group\Events\UserAddedEvent;
use OCP\Group\Events\UserRemovedEvent;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserManager;
use OCP\User\Events\UserCreatedEvent;
/**
* Listens to config events and update the mounts for the applicable users
*
* @template-implements IEventListener<StorageCreatedEvent|StorageDeletedEvent|StorageUpdatedEvent|Event>
* @template-implements IEventListener<StorageCreatedEvent|StorageDeletedEvent|StorageUpdatedEvent|BeforeGroupDeletedEvent|UserCreatedEvent|UserAddedEvent|UserRemovedEvent|Event>
*/
class MountCacheService implements IEventListener {
public function __construct(
@ -37,6 +40,7 @@ class MountCacheService implements IEventListener {
private readonly ConfigAdapter $configAdapter,
private readonly IUserManager $userManager,
private readonly IGroupManager $groupManager,
private readonly GlobalStoragesService $storagesService,
) {
}
@ -50,6 +54,18 @@ class MountCacheService implements IEventListener {
if ($event instanceof StorageUpdatedEvent) {
$this->registerUpdatedStorage($event->getOldConfig(), $event->getNewConfig());
}
if ($event instanceof UserAddedEvent) {
$this->addUserToGroup($event->getGroup(), $event->getUser());
}
if ($event instanceof UserRemovedEvent) {
$this->removeUserFromGroup($event->getGroup(), $event->getUser());
}
if ($event instanceof BeforeGroupDeletedEvent) {
$this->removeGroup($event->getGroup());
}
if ($event instanceof UserCreatedEvent) {
$this->addUser($event->getUser());
}
}
@ -152,4 +168,38 @@ class MountCacheService implements IEventListener {
$storage->getId(),
);
}
private function removeUserFromGroup(IGroup $group, IUser $user) {
$storages = $this->storagesService->getAllStoragesForGroup($group);
foreach ($storages as $storage) {
if (!in_array($user->getUID(), $storage->getApplicableUsers())) {
$this->userMountCache->removeMount($storage->getMountPointForUser($user));
}
}
}
private function addUserToGroup(IGroup $group, IUser $user) {
$storages = $this->storagesService->getAllStoragesForGroup($group);
foreach ($storages as $storage) {
$this->registerForUser($user, $storage);
}
}
private function removeGroup(IGroup $group) {
$storages = $this->storagesService->getAllStoragesForGroup($group);
foreach ($storages as $storage) {
foreach ($group->searchUsers('') as $user) {
if (!in_array($user->getUID(), $storage->getApplicableUsers())) {
$this->userMountCache->removeMount($storage->getMountPointForUser($user));
}
}
}
}
private function addUser(IUser $user) {
$storages = $this->storagesService->getAllGlobalStorages();
foreach ($storages as $storage) {
$this->registerForUser($user, $storage);
}
}
}

1
apps/files_external/lib/Service/UserGlobalStoragesService.php

@ -9,7 +9,6 @@ namespace OCA\Files_External\Service;
use OCA\Files_External\Lib\StorageConfig;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Config\IUserMountCache;
use OCP\IAppConfig;
use OCP\IGroupManager;
use OCP\IUser;

Loading…
Cancel
Save