From 84ba97a469bce1ad6d4c99bce3d8522edc937049 Mon Sep 17 00:00:00 2001 From: Cristian Scheid Date: Tue, 30 Jun 2026 08:20:40 -0300 Subject: [PATCH 1/2] fix: propagate disabled state to lookup server Signed-off-by: Cristian Scheid --- lib/AppInfo/Application.php | 3 ++ lib/Controller/SlaveController.php | 11 ++++ lib/Listeners/UserChanged.php | 53 +++++++++++++++++++ lib/Slave.php | 3 +- psalm.xml | 2 + tests/stubs/oc_user_disableduserexception.php | 13 +++++ tests/stubs/oc_user_loginexception.php | 14 +++++ .../lib/Controller/SlaveControllerTest.php | 4 ++ 8 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 lib/Listeners/UserChanged.php create mode 100644 tests/stubs/oc_user_disableduserexception.php create mode 100644 tests/stubs/oc_user_loginexception.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 8f79ce33..95fdd0a0 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -15,6 +15,7 @@ use OCA\GlobalSiteSelector\GlobalSiteSelector; use OCA\GlobalSiteSelector\Listeners\AddContentSecurityPolicyListener; use OCA\GlobalSiteSelector\Listeners\DeletingUser; +use OCA\GlobalSiteSelector\Listeners\UserChanged; use OCA\GlobalSiteSelector\Listeners\UserCreated; use OCA\GlobalSiteSelector\Listeners\UserDeleted; use OCA\GlobalSiteSelector\Listeners\UserLoggedOut; @@ -36,6 +37,7 @@ use OCP\Server; use OCP\User\Events\BeforeUserDeletedEvent; use OCP\User\Events\BeforeUserLoggedInEvent; +use OCP\User\Events\UserChangedEvent; use OCP\User\Events\UserCreatedEvent; use OCP\User\Events\UserDeletedEvent; use OCP\User\Events\UserLoggedOutEvent; @@ -80,6 +82,7 @@ public function register(IRegistrationContext $context): void { $context->registerEventListener(BeforeUserDeletedEvent::class, DeletingUser::class); $context->registerEventListener(UserDeletedEvent::class, UserDeleted::class); $context->registerEventListener(UserLoggedOutEvent::class, UserLoggedOut::class); + $context->registerEventListener(UserChangedEvent::class, UserChanged::class); $context->registerSetupCheck(LongJwtKeySetupCheck::class); diff --git a/lib/Controller/SlaveController.php b/lib/Controller/SlaveController.php index 24c60be3..dfd572ee 100644 --- a/lib/Controller/SlaveController.php +++ b/lib/Controller/SlaveController.php @@ -9,6 +9,7 @@ namespace OCA\GlobalSiteSelector\Controller; use OC\Authentication\Token\IProvider; +use OC\User\DisabledUserException; use OCA\GlobalSiteSelector\AppInfo\Application; use OCA\GlobalSiteSelector\Exceptions\LocalFederatedShareException; use OCA\GlobalSiteSelector\Exceptions\MasterUrlException; @@ -63,6 +64,7 @@ public function __construct( private readonly IUserManager $userManager, private readonly UserBackend $userBackend, private readonly ISession $session, + private readonly Slave $slave, private readonly SlaveService $slaveService, private readonly GlobalScaleService $globalScaleService, private readonly GlobalShareService $globalShareService, @@ -159,6 +161,9 @@ public function autoLogin(string $jwt): RedirectResponse { if (!($user instanceof IUser)) { throw new \InvalidArgumentException('User is not valid'); } + if (!$user->isEnabled()) { + throw new DisabledUserException('Account disabled'); + } $user->updateLastLoginTimestamp(); $this->session->set('globalScale.userData', $options); @@ -191,6 +196,12 @@ public function autoLogin(string $jwt): RedirectResponse { $response = new RedirectResponse($masterUrl); $response->throttle(); return $response; + } catch (DisabledUserException $e) { + // user is disabled, remove from lookup server + $params = ['uid' => $uid]; + $this->slave->preDeleteUser($params); + $this->slave->deleteUser($params); + return new RedirectResponse($masterUrl); } catch (\Exception $e) { $this->logger->warning('issue during login process', ['exception' => $e]); $response = new RedirectResponse($masterUrl); diff --git a/lib/Listeners/UserChanged.php b/lib/Listeners/UserChanged.php new file mode 100644 index 00000000..dfa4a076 --- /dev/null +++ b/lib/Listeners/UserChanged.php @@ -0,0 +1,53 @@ + + */ +class UserChanged implements IEventListener { + + public function __construct( + private GlobalSiteSelector $globalSiteSelector, + private Slave $slave, + ) { + } + + public function handle(Event $event): void { + if (!$event instanceof UserChangedEvent) { + return; + } + + if (!$this->globalSiteSelector->isSlave()) { + return; + } + + if ($event->getFeature() !== 'enabled') { + return; + } + + $params = ['uid' => $event->getUser()->getUID()]; + + if ($event->getValue() === false) { + // user was disabled, remove from lookup server + $this->slave->preDeleteUser($params); + $this->slave->deleteUser($params); + } else { + // user was enabled, add to lookup server + $this->slave->createUser($params); + } + } +} diff --git a/lib/Slave.php b/lib/Slave.php index fe764ae7..a6622311 100644 --- a/lib/Slave.php +++ b/lib/Slave.php @@ -160,11 +160,10 @@ public function batchUpdate(): void { $offset = 0; $usersData = []; do { - $users = $backend->getUsers('', $limit, $offset); foreach ($users as $uid) { $user = $this->userManager->get($uid); - if ($user !== null) { + if ($user !== null && $user->isEnabled()) { $usersData[$user->getCloudId()] = $this->slaveService->getAccountData($user); } } diff --git a/psalm.xml b/psalm.xml index 72b23f2c..f6184379 100644 --- a/psalm.xml +++ b/psalm.xml @@ -58,6 +58,8 @@ + + diff --git a/tests/stubs/oc_user_disableduserexception.php b/tests/stubs/oc_user_disableduserexception.php new file mode 100644 index 00000000..c29ce7cd --- /dev/null +++ b/tests/stubs/oc_user_disableduserexception.php @@ -0,0 +1,13 @@ +userBackend = $this->getMockBuilder(UserBackend::class) ->disableOriginalConstructor()->getMock(); $this->session = $this->createMock(ISession::class); + $this->slave = $this->createMock(Slave::class); $this->slaveService = $this->createMock(SlaveService::class); $this->globalScaleService = $this->createMock(GlobalScaleService::class); $this->globalShareService = $this->createMock(GlobalShareService::class); @@ -86,6 +89,7 @@ private function getInstance(array $mockMathods = []) { $this->userManager, $this->userBackend, $this->session, + $this->slave, $this->slaveService, $this->globalScaleService, $this->globalShareService, From 8c5b8841952e09b8fa8beee2e7f803d304aedf09 Mon Sep 17 00:00:00 2001 From: Cristian Scheid Date: Thu, 2 Jul 2026 14:01:59 -0300 Subject: [PATCH 2/2] fix: adjusted batch upodate to remove disabled users Signed-off-by: Cristian Scheid --- lib/Slave.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/Slave.php b/lib/Slave.php index a6622311..09df9f2f 100644 --- a/lib/Slave.php +++ b/lib/Slave.php @@ -158,17 +158,28 @@ public function batchUpdate(): void { foreach ($backends as $backend) { $limit = 200; $offset = 0; - $usersData = []; do { + $usersToAdd = []; + $usersToRemove = []; $users = $backend->getUsers('', $limit, $offset); foreach ($users as $uid) { $user = $this->userManager->get($uid); - if ($user !== null && $user->isEnabled()) { - $usersData[$user->getCloudId()] = $this->slaveService->getAccountData($user); + if ($user === null) { + continue; + } + if ($user->isEnabled()) { + $usersToAdd[$user->getCloudId()] = $this->slaveService->getAccountData($user); + } else { + $usersToRemove[] = $user->getCloudId(); } } $offset += $limit; - $this->addUsers($usersData); + if ($usersToAdd !== []) { + $this->addUsers($usersToAdd); + } + if ($usersToRemove !== []) { + $this->removeUsers($usersToRemove); + } } while (count($users) >= $limit); } }