Skip to content

Commit 4713202

Browse files
committed
feat: listen to user/group events and update external storage mounts
Signed-off-by: Robin Appelman <[email protected]>
1 parent cfcbd28 commit 4713202

File tree

5 files changed

+115
-8
lines changed

5 files changed

+115
-8
lines changed

apps/files_external/lib/AppInfo/Application.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
use OCA\Files_External\Lib\Config\IBackendProvider;
4646
use OCA\Files_External\Listener\GroupDeletedListener;
4747
use OCA\Files_External\Listener\LoadAdditionalListener;
48-
use OCA\Files_External\Listener\StorePasswordListener;
4948
use OCA\Files_External\Listener\UserDeletedListener;
5049
use OCA\Files_External\Service\BackendService;
5150
use OCA\Files_External\Service\MountCacheService;
@@ -55,10 +54,12 @@
5554
use OCP\AppFramework\Bootstrap\IRegistrationContext;
5655
use OCP\AppFramework\QueryException;
5756
use OCP\Files\Config\IMountProviderCollection;
57+
use OCP\Group\Events\BeforeGroupDeletedEvent;
5858
use OCP\Group\Events\GroupDeletedEvent;
59-
use OCP\User\Events\PasswordUpdatedEvent;
59+
use OCP\Group\Events\UserAddedEvent;
60+
use OCP\Group\Events\UserRemovedEvent;
61+
use OCP\User\Events\UserCreatedEvent;
6062
use OCP\User\Events\UserDeletedEvent;
61-
use OCP\User\Events\UserLoggedInEvent;
6263

6364
/**
6465
* @package OCA\Files_External\AppInfo
@@ -79,11 +80,14 @@ public function register(IRegistrationContext $context): void {
7980
$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
8081
$context->registerEventListener(GroupDeletedEvent::class, GroupDeletedListener::class);
8182
$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class);
82-
$context->registerEventListener(UserLoggedInEvent::class, StorePasswordListener::class);
83-
$context->registerEventListener(PasswordUpdatedEvent::class, StorePasswordListener::class);
8483
$context->registerEventListener(StorageCreatedEvent::class, MountCacheService::class);
8584
$context->registerEventListener(StorageDeletedEvent::class, MountCacheService::class);
8685
$context->registerEventListener(StorageUpdatedEvent::class, MountCacheService::class);
86+
$context->registerEventListener(BeforeGroupDeletedEvent::class, MountCacheService::class);
87+
$context->registerEventListener(UserCreatedEvent::class, MountCacheService::class);
88+
$context->registerEventListener(UserAddedEvent::class, MountCacheService::class);
89+
$context->registerEventListener(UserRemovedEvent::class, MountCacheService::class);
90+
8791
$context->registerConfigLexicon(ConfigLexicon::class);
8892
}
8993

apps/files_external/lib/Service/DBConfigService.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,32 @@ public function getMountsForUser($userId, $groupIds) {
8080
return $this->getMountsFromQuery($query);
8181
}
8282

83+
public function getMountsForGroups($groupIds) {
84+
$builder = $this->connection->getQueryBuilder();
85+
$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
86+
->from('external_mounts', 'm')
87+
->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
88+
->where($builder->expr()->andX( // mounts for group
89+
$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GROUP, IQueryBuilder::PARAM_INT)),
90+
$builder->expr()->in('a.value', $builder->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)),
91+
));
92+
93+
return $this->getMountsFromQuery($query);
94+
}
95+
96+
public function getGlobalMounts() {
97+
$builder = $this->connection->getQueryBuilder();
98+
$query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
99+
->from('external_mounts', 'm')
100+
->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id'))
101+
->where($builder->expr()->andX( // global mounts
102+
$builder->expr()->eq('a.type', $builder->createNamedParameter(self::APPLICABLE_TYPE_GLOBAL, IQueryBuilder::PARAM_INT)),
103+
$builder->expr()->isNull('a.value'),
104+
), );
105+
106+
return $this->getMountsFromQuery($query);
107+
}
108+
83109
public function modifyMountsOnUserDelete(string $uid): void {
84110
$this->modifyMountsOnDelete($uid, self::APPLICABLE_TYPE_USER);
85111
}

apps/files_external/lib/Service/GlobalStoragesService.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use OCA\Files_External\Event\StorageUpdatedEvent;
1414
use OCA\Files_External\Lib\StorageConfig;
1515
use OCA\Files_External\MountConfig;
16+
use OCP\IGroup;
1617

1718
/**
1819
* Service class to manage global external storage
@@ -169,4 +170,31 @@ public function getStorageForAllUsers() {
169170

170171
return array_combine($keys, $configs);
171172
}
173+
174+
/**
175+
* Gets all storages for the group, not including any global storages
176+
* @return StorageConfig[]
177+
*/
178+
public function getAllStoragesForGroup(IGroup $group): array {
179+
$mounts = $this->dbConfig->getMountsForGroups([$group->getGID()]);
180+
$configs = array_map($this->getStorageConfigFromDBMount(...), $mounts);
181+
$configs = array_filter($configs, static fn (?StorageConfig $config): bool => $config instanceof StorageConfig);
182+
$keys = array_map(static fn (StorageConfig $config) => $config->getId(), $configs);
183+
184+
$storages = array_combine($keys, $configs);
185+
return array_filter($storages, $this->validateStorage(...));
186+
}
187+
188+
/**
189+
* @return StorageConfig[]
190+
*/
191+
public function getAllGlobalStorages(): array {
192+
$mounts = $this->dbConfig->getGlobalMounts();
193+
194+
$configs = array_map($this->getStorageConfigFromDBMount(...), $mounts);
195+
$configs = array_filter($configs, static fn (?StorageConfig $config): bool => $config instanceof StorageConfig);
196+
$keys = array_map(static fn (StorageConfig $config) => $config->getId(), $configs);
197+
$storages = array_combine($keys, $configs);
198+
return array_filter($storages, $this->validateStorage(...));
199+
}
172200
}

apps/files_external/lib/Service/MountCacheService.php

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,27 @@
2020
use OCP\EventDispatcher\IEventListener;
2121
use OCP\Files\Cache\ICacheEntry;
2222
use OCP\Files\Config\IUserMountCache;
23-
use OCP\Files\IMimeTypeLoader;
23+
use OCP\Group\Events\BeforeGroupDeletedEvent;
24+
use OCP\Group\Events\UserAddedEvent;
25+
use OCP\Group\Events\UserRemovedEvent;
2426
use OCP\IGroup;
2527
use OCP\IGroupManager;
2628
use OCP\IUser;
2729
use OCP\IUserManager;
30+
use OCP\User\Events\UserCreatedEvent;
2831

2932
/**
3033
* Listens to config events and update the mounts for the applicable users
3134
*
32-
* @template-implements IEventListener<StorageCreatedEvent|StorageDeletedEvent|StorageUpdatedEvent|Event>
35+
* @template-implements IEventListener<StorageCreatedEvent|StorageDeletedEvent|StorageUpdatedEvent|BeforeGroupDeletedEvent|UserCreatedEvent|UserAddedEvent|UserRemovedEvent|Event>
3336
*/
3437
class MountCacheService implements IEventListener {
3538
public function __construct(
3639
private readonly IUserMountCache $userMountCache,
3740
private readonly ConfigAdapter $configAdapter,
3841
private readonly IUserManager $userManager,
3942
private readonly IGroupManager $groupManager,
43+
private readonly GlobalStoragesService $storagesService,
4044
) {
4145
}
4246

@@ -50,6 +54,18 @@ public function handle(Event $event): void {
5054
if ($event instanceof StorageUpdatedEvent) {
5155
$this->registerUpdatedStorage($event->getOldConfig(), $event->getNewConfig());
5256
}
57+
if ($event instanceof UserAddedEvent) {
58+
$this->addUserToGroup($event->getGroup(), $event->getUser());
59+
}
60+
if ($event instanceof UserRemovedEvent) {
61+
$this->removeUserFromGroup($event->getGroup(), $event->getUser());
62+
}
63+
if ($event instanceof BeforeGroupDeletedEvent) {
64+
$this->removeGroup($event->getGroup());
65+
}
66+
if ($event instanceof UserCreatedEvent) {
67+
$this->addUser($event->getUser());
68+
}
5369
}
5470

5571

@@ -152,4 +168,38 @@ private function registerForUser(IUser $user, StorageConfig $storage): void {
152168
$storage->getId(),
153169
);
154170
}
171+
172+
private function removeUserFromGroup(IGroup $group, IUser $user): void {
173+
$storages = $this->storagesService->getAllStoragesForGroup($group);
174+
foreach ($storages as $storage) {
175+
if (!in_array($user->getUID(), $storage->getApplicableUsers())) {
176+
$this->userMountCache->removeMount($storage->getMountPointForUser($user));
177+
}
178+
}
179+
}
180+
181+
private function addUserToGroup(IGroup $group, IUser $user): void {
182+
$storages = $this->storagesService->getAllStoragesForGroup($group);
183+
foreach ($storages as $storage) {
184+
$this->registerForUser($user, $storage);
185+
}
186+
}
187+
188+
private function removeGroup(IGroup $group): void {
189+
$storages = $this->storagesService->getAllStoragesForGroup($group);
190+
foreach ($storages as $storage) {
191+
foreach ($group->searchUsers('') as $user) {
192+
if (!in_array($user->getUID(), $storage->getApplicableUsers())) {
193+
$this->userMountCache->removeMount($storage->getMountPointForUser($user));
194+
}
195+
}
196+
}
197+
}
198+
199+
private function addUser(IUser $user): void {
200+
$storages = $this->storagesService->getAllGlobalStorages();
201+
foreach ($storages as $storage) {
202+
$this->registerForUser($user, $storage);
203+
}
204+
}
155205
}

apps/files_external/lib/Service/UserGlobalStoragesService.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
use OCA\Files_External\Lib\StorageConfig;
1111
use OCP\EventDispatcher\IEventDispatcher;
12-
use OCP\Files\Config\IUserMountCache;
1312
use OCP\IAppConfig;
1413
use OCP\IGroupManager;
1514
use OCP\IUser;

0 commit comments

Comments
 (0)