Loading lib/Listeners/PasswordUpdatedListener.php +6 −28 Original line number Diff line number Diff line Loading @@ -5,9 +5,7 @@ declare(strict_types=1); namespace OCA\EcloudAccounts\Listeners; use Exception; use OC\Authentication\Token\IProvider as TokenProvider; use OCA\EcloudAccounts\AppInfo\Application; use OCA\EcloudAccounts\Service\SSOService; use OCA\EcloudAccounts\Service\UserService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ISession; Loading @@ -17,19 +15,16 @@ use Psr\Log\LoggerInterface; class PasswordUpdatedListener implements IEventListener { private SSOService $ssoService; private UserService $userService; private LoggerInterface $logger; private ISession $session; private IUserSession $userSession; private TokenProvider $tokenProvider; public function __construct(SSOService $ssoService, LoggerInterface $logger, ISession $session, IUserSession $userSession, TokenProvider $tokenProvider) { $this->ssoService = $ssoService; public function __construct(UserService $userService, LoggerInterface $logger, ISession $session, IUserSession $userSession) { $this->userService = $userService; $this->logger = $logger; $this->session = $session; $this->userSession = $userSession; $this->tokenProvider = $tokenProvider; } public function handle(Event $event): void { Loading @@ -44,24 +39,7 @@ class PasswordUpdatedListener implements IEventListener { $user = $event->getUser(); $username = $user->getUID(); try { $this->ssoService->logout($username); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e, 'app' => Application::APP_ID]); } // Remove all Nextcloud sessions/tokens for the user (invalidate cache + storage) try { $this->tokenProvider->invalidateTokensOfUser($username, null); } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } // Finally, log out the current session (also clears remember-me cookies) try { $this->userSession->logout(); } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } // Invalidate all sessions and tokens for the user $this->userService->invalidateUserSessions($username); } } lib/Listeners/UserChangedListener.php +2 −40 Original line number Diff line number Diff line Loading @@ -5,16 +5,11 @@ declare(strict_types=1); namespace OCA\EcloudAccounts\Listeners; use Exception; use OC\Authentication\Token\IProvider as TokenProvider; use OCA\EcloudAccounts\AppInfo\Application; use OCA\EcloudAccounts\Db\MailboxMapper; use OCA\EcloudAccounts\Service\LDAPConnectionService; use OCA\EcloudAccounts\Service\SSOService; use OCA\EcloudAccounts\Service\UserService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ISession; use OCP\IUserSession; use OCP\User\Events\UserChangedEvent; use OCP\Util; use Psr\Log\LoggerInterface; Loading @@ -31,21 +26,13 @@ class UserChangedListener implements IEventListener { private $userService; private $LDAPConnectionService; private SSOService $ssoService; private ISession $session; private IUserSession $userSession; private TokenProvider $tokenProvider; public function __construct(Util $util, LoggerInterface $logger, MailboxMapper $mailboxMapper, UserService $userService, LDAPConnectionService $LDAPConnectionService, SSOService $ssoService, ISession $session, IUserSession $userSession, TokenProvider $tokenProvider) { public function __construct(Util $util, LoggerInterface $logger, MailboxMapper $mailboxMapper, UserService $userService, LDAPConnectionService $LDAPConnectionService) { $this->util = $util; $this->mailboxMapper = $mailboxMapper; $this->logger = $logger; $this->userService = $userService; $this->LDAPConnectionService = $LDAPConnectionService; $this->ssoService = $ssoService; $this->session = $session; $this->userSession = $userSession; $this->tokenProvider = $tokenProvider; } public function handle(Event $event): void { Loading @@ -69,7 +56,7 @@ class UserChangedListener implements IEventListener { if ($feature === self::ENABLED_FEATURE) { try { $this->userService->mapActiveAttributesInLDAP($username, $newValue); $this->invalidateUserSessions($username); $this->userService->invalidateUserSessions($username); } catch (Exception $e) { $this->logger->error('Failed to update LDAP attributes for user: ' . $username, ['exception' => $e]); } Loading @@ -91,29 +78,4 @@ class UserChangedListener implements IEventListener { $this->logger->error("Error setting quota for user $username " . $e->getMessage()); } } private function invalidateUserSessions(string $username): void { // Logout from SSO service try { $this->ssoService->logout($username); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e, 'app' => Application::APP_ID]); } // Remove all Nextcloud sessions/tokens for the user (invalidate cache + storage) try { $this->tokenProvider->invalidateTokensOfUser($username, null); } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } // Finally, log out the current session if it's the same user (also clears remember-me cookies) try { if ($this->userSession->isLoggedIn() && $this->userSession->getUser() && $this->userSession->getUser()->getUID() === $username) { $this->userSession->logout(); } } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } } } lib/Service/UserService.php +46 −1 Original line number Diff line number Diff line Loading @@ -7,15 +7,18 @@ namespace OCA\EcloudAccounts\Service; require __DIR__ . '/../../vendor/autoload.php'; use Exception; use OC\Authentication\Token\IProvider as TokenProvider; use OCA\EcloudAccounts\AppInfo\Application; use OCA\EcloudAccounts\Event\BeforeUserRegisteredEvent; use OCA\EcloudAccounts\Exception\AddUsernameToCommonStoreException; use OCA\EcloudAccounts\Exception\LDAPUserCreationException; use OCA\EcloudAccounts\Service\SSOService; use OCP\Defaults; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Util; use Psr\Log\LoggerInterface; Loading @@ -42,7 +45,11 @@ class UserService { /** @var LDAPConnectionService */ private $LDAPConnectionService; private IEventDispatcher $dispatcher; public function __construct($appName, IUserManager $userManager, IConfig $config, CurlService $curlService, LoggerInterface $logger, Defaults $defaults, IFactory $l10nFactory, LDAPConnectionService $LDAPConnectionService, IEventDispatcher $dispatcher) { private SSOService $ssoService; private IUserSession $userSession; private TokenProvider $tokenProvider; public function __construct($appName, IUserManager $userManager, IConfig $config, CurlService $curlService, LoggerInterface $logger, Defaults $defaults, IFactory $l10nFactory, LDAPConnectionService $LDAPConnectionService, IEventDispatcher $dispatcher, SSOService $ssoService, IUserSession $userSession, TokenProvider $tokenProvider) { $this->userManager = $userManager; $this->config = $config; $this->appConfig = $this->config->getSystemValue($appName); Loading @@ -52,6 +59,9 @@ class UserService { $this->l10nFactory = $l10nFactory; $this->LDAPConnectionService = $LDAPConnectionService; $this->dispatcher = $dispatcher; $this->ssoService = $ssoService; $this->userSession = $userSession; $this->tokenProvider = $tokenProvider; $commonServiceURL = $this->config->getSystemValue('common_services_url', ''); if (!empty($commonServiceURL)) { Loading Loading @@ -497,4 +507,39 @@ class UserService { $legacyDomain = $this->config->getSystemValue('legacy_domain', ''); return str_ireplace('@' . $legacyDomain, '', $username); } /** * Invalidate all sessions and tokens for a user. * This includes SSO logout, Nextcloud token invalidation, and current session logout. * * @param string $username The username of the user whose sessions should be invalidated * @param bool $logoutCurrentSession Whether to logout the current session if it matches the user (default: true) * @return void */ public function invalidateUserSessions(string $username, bool $logoutCurrentSession = true): void { // Logout from SSO service try { $this->ssoService->logout($username); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e, 'app' => Application::APP_ID]); } // Remove all Nextcloud sessions/tokens for the user (invalidate cache + storage) try { $this->tokenProvider->invalidateTokensOfUser($username, null); } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } // Finally, log out the current session if it's the same user (also clears remember-me cookies) if ($logoutCurrentSession) { try { if ($this->userSession->isLoggedIn() && $this->userSession->getUser() && $this->userSession->getUser()->getUID() === $username) { $this->userSession->logout(); } } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } } } } Loading
lib/Listeners/PasswordUpdatedListener.php +6 −28 Original line number Diff line number Diff line Loading @@ -5,9 +5,7 @@ declare(strict_types=1); namespace OCA\EcloudAccounts\Listeners; use Exception; use OC\Authentication\Token\IProvider as TokenProvider; use OCA\EcloudAccounts\AppInfo\Application; use OCA\EcloudAccounts\Service\SSOService; use OCA\EcloudAccounts\Service\UserService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ISession; Loading @@ -17,19 +15,16 @@ use Psr\Log\LoggerInterface; class PasswordUpdatedListener implements IEventListener { private SSOService $ssoService; private UserService $userService; private LoggerInterface $logger; private ISession $session; private IUserSession $userSession; private TokenProvider $tokenProvider; public function __construct(SSOService $ssoService, LoggerInterface $logger, ISession $session, IUserSession $userSession, TokenProvider $tokenProvider) { $this->ssoService = $ssoService; public function __construct(UserService $userService, LoggerInterface $logger, ISession $session, IUserSession $userSession) { $this->userService = $userService; $this->logger = $logger; $this->session = $session; $this->userSession = $userSession; $this->tokenProvider = $tokenProvider; } public function handle(Event $event): void { Loading @@ -44,24 +39,7 @@ class PasswordUpdatedListener implements IEventListener { $user = $event->getUser(); $username = $user->getUID(); try { $this->ssoService->logout($username); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e, 'app' => Application::APP_ID]); } // Remove all Nextcloud sessions/tokens for the user (invalidate cache + storage) try { $this->tokenProvider->invalidateTokensOfUser($username, null); } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } // Finally, log out the current session (also clears remember-me cookies) try { $this->userSession->logout(); } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } // Invalidate all sessions and tokens for the user $this->userService->invalidateUserSessions($username); } }
lib/Listeners/UserChangedListener.php +2 −40 Original line number Diff line number Diff line Loading @@ -5,16 +5,11 @@ declare(strict_types=1); namespace OCA\EcloudAccounts\Listeners; use Exception; use OC\Authentication\Token\IProvider as TokenProvider; use OCA\EcloudAccounts\AppInfo\Application; use OCA\EcloudAccounts\Db\MailboxMapper; use OCA\EcloudAccounts\Service\LDAPConnectionService; use OCA\EcloudAccounts\Service\SSOService; use OCA\EcloudAccounts\Service\UserService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ISession; use OCP\IUserSession; use OCP\User\Events\UserChangedEvent; use OCP\Util; use Psr\Log\LoggerInterface; Loading @@ -31,21 +26,13 @@ class UserChangedListener implements IEventListener { private $userService; private $LDAPConnectionService; private SSOService $ssoService; private ISession $session; private IUserSession $userSession; private TokenProvider $tokenProvider; public function __construct(Util $util, LoggerInterface $logger, MailboxMapper $mailboxMapper, UserService $userService, LDAPConnectionService $LDAPConnectionService, SSOService $ssoService, ISession $session, IUserSession $userSession, TokenProvider $tokenProvider) { public function __construct(Util $util, LoggerInterface $logger, MailboxMapper $mailboxMapper, UserService $userService, LDAPConnectionService $LDAPConnectionService) { $this->util = $util; $this->mailboxMapper = $mailboxMapper; $this->logger = $logger; $this->userService = $userService; $this->LDAPConnectionService = $LDAPConnectionService; $this->ssoService = $ssoService; $this->session = $session; $this->userSession = $userSession; $this->tokenProvider = $tokenProvider; } public function handle(Event $event): void { Loading @@ -69,7 +56,7 @@ class UserChangedListener implements IEventListener { if ($feature === self::ENABLED_FEATURE) { try { $this->userService->mapActiveAttributesInLDAP($username, $newValue); $this->invalidateUserSessions($username); $this->userService->invalidateUserSessions($username); } catch (Exception $e) { $this->logger->error('Failed to update LDAP attributes for user: ' . $username, ['exception' => $e]); } Loading @@ -91,29 +78,4 @@ class UserChangedListener implements IEventListener { $this->logger->error("Error setting quota for user $username " . $e->getMessage()); } } private function invalidateUserSessions(string $username): void { // Logout from SSO service try { $this->ssoService->logout($username); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e, 'app' => Application::APP_ID]); } // Remove all Nextcloud sessions/tokens for the user (invalidate cache + storage) try { $this->tokenProvider->invalidateTokensOfUser($username, null); } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } // Finally, log out the current session if it's the same user (also clears remember-me cookies) try { if ($this->userSession->isLoggedIn() && $this->userSession->getUser() && $this->userSession->getUser()->getUID() === $username) { $this->userSession->logout(); } } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } } }
lib/Service/UserService.php +46 −1 Original line number Diff line number Diff line Loading @@ -7,15 +7,18 @@ namespace OCA\EcloudAccounts\Service; require __DIR__ . '/../../vendor/autoload.php'; use Exception; use OC\Authentication\Token\IProvider as TokenProvider; use OCA\EcloudAccounts\AppInfo\Application; use OCA\EcloudAccounts\Event\BeforeUserRegisteredEvent; use OCA\EcloudAccounts\Exception\AddUsernameToCommonStoreException; use OCA\EcloudAccounts\Exception\LDAPUserCreationException; use OCA\EcloudAccounts\Service\SSOService; use OCP\Defaults; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Util; use Psr\Log\LoggerInterface; Loading @@ -42,7 +45,11 @@ class UserService { /** @var LDAPConnectionService */ private $LDAPConnectionService; private IEventDispatcher $dispatcher; public function __construct($appName, IUserManager $userManager, IConfig $config, CurlService $curlService, LoggerInterface $logger, Defaults $defaults, IFactory $l10nFactory, LDAPConnectionService $LDAPConnectionService, IEventDispatcher $dispatcher) { private SSOService $ssoService; private IUserSession $userSession; private TokenProvider $tokenProvider; public function __construct($appName, IUserManager $userManager, IConfig $config, CurlService $curlService, LoggerInterface $logger, Defaults $defaults, IFactory $l10nFactory, LDAPConnectionService $LDAPConnectionService, IEventDispatcher $dispatcher, SSOService $ssoService, IUserSession $userSession, TokenProvider $tokenProvider) { $this->userManager = $userManager; $this->config = $config; $this->appConfig = $this->config->getSystemValue($appName); Loading @@ -52,6 +59,9 @@ class UserService { $this->l10nFactory = $l10nFactory; $this->LDAPConnectionService = $LDAPConnectionService; $this->dispatcher = $dispatcher; $this->ssoService = $ssoService; $this->userSession = $userSession; $this->tokenProvider = $tokenProvider; $commonServiceURL = $this->config->getSystemValue('common_services_url', ''); if (!empty($commonServiceURL)) { Loading Loading @@ -497,4 +507,39 @@ class UserService { $legacyDomain = $this->config->getSystemValue('legacy_domain', ''); return str_ireplace('@' . $legacyDomain, '', $username); } /** * Invalidate all sessions and tokens for a user. * This includes SSO logout, Nextcloud token invalidation, and current session logout. * * @param string $username The username of the user whose sessions should be invalidated * @param bool $logoutCurrentSession Whether to logout the current session if it matches the user (default: true) * @return void */ public function invalidateUserSessions(string $username, bool $logoutCurrentSession = true): void { // Logout from SSO service try { $this->ssoService->logout($username); } catch (Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e, 'app' => Application::APP_ID]); } // Remove all Nextcloud sessions/tokens for the user (invalidate cache + storage) try { $this->tokenProvider->invalidateTokensOfUser($username, null); } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } // Finally, log out the current session if it's the same user (also clears remember-me cookies) if ($logoutCurrentSession) { try { if ($this->userSession->isLoggedIn() && $this->userSession->getUser() && $this->userSession->getUser()->getUID() === $username) { $this->userSession->logout(); } } catch (Exception $e) { $this->logger->error($e, ['app' => Application::APP_ID]); } } } }