From 6dfb31a98eac4833e99d7e5768f16c122b1635d8 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Tue, 3 Dec 2019 15:05:05 +0100 Subject: [PATCH 1/2] Add typed events for all user hooks and legacy events Signed-off-by: Christoph Wurst --- .../Service/UserGlobalStoragesServiceTest.php | 3 +- apps/user_ldap/tests/LDAPProviderTest.php | 2 - lib/composer/composer/autoload_classmap.php | 14 +- lib/composer/composer/autoload_static.php | 14 +- lib/private/Files/View.php | 4 +- lib/private/Server.php | 162 ++++++++--- lib/private/User/Manager.php | 54 ++-- lib/private/User/Session.php | 29 +- lib/private/User/User.php | 93 +++--- .../Events/BeforePasswordUpdatedEvent.php | 82 ++++++ ...erEvent.php => BeforeUserCreatedEvent.php} | 2 +- .../User/Events/BeforeUserDeletedEvent.php | 54 ++++ .../User/Events/BeforeUserLoggedInEvent.php | 66 +++++ .../BeforeUserLoggedInWithCookieEvent.php | 55 ++++ .../User/Events/BeforeUserLoggedOutEvent.php | 55 ++++ .../User/Events/PasswordUpdatedEvent.php | 82 ++++++ lib/public/User/Events/UserChangedEvent.php | 93 ++++++ lib/public/User/Events/UserDeletedEvent.php | 54 ++++ ...stLoginEvent.php => UserLoggedInEvent.php} | 2 +- .../Events/UserLoggedInWithCookieEvent.php | 66 +++++ lib/public/User/Events/UserLoggedOutEvent.php | 55 ++++ tests/lib/Files/Cache/CacheTest.php | 3 +- tests/lib/Files/Config/UserMountCacheTest.php | 2 +- tests/lib/Files/Node/IntegrationTest.php | 3 +- .../Files/Storage/Wrapper/EncryptionTest.php | 7 +- tests/lib/Files/Stream/EncryptionTest.php | 2 +- tests/lib/User/DatabaseTest.php | 7 +- tests/lib/User/ManagerTest.php | 54 ++-- tests/lib/User/SessionTest.php | 18 +- tests/lib/User/UserTest.php | 275 ++++++------------ 30 files changed, 1038 insertions(+), 374 deletions(-) create mode 100644 lib/public/User/Events/BeforePasswordUpdatedEvent.php rename lib/public/User/Events/{CreateUserEvent.php => BeforeUserCreatedEvent.php} (96%) create mode 100644 lib/public/User/Events/BeforeUserDeletedEvent.php create mode 100644 lib/public/User/Events/BeforeUserLoggedInEvent.php create mode 100644 lib/public/User/Events/BeforeUserLoggedInWithCookieEvent.php create mode 100644 lib/public/User/Events/BeforeUserLoggedOutEvent.php create mode 100644 lib/public/User/Events/PasswordUpdatedEvent.php create mode 100644 lib/public/User/Events/UserChangedEvent.php create mode 100644 lib/public/User/Events/UserDeletedEvent.php rename lib/public/User/Events/{PostLoginEvent.php => UserLoggedInEvent.php} (97%) create mode 100644 lib/public/User/Events/UserLoggedInWithCookieEvent.php create mode 100644 lib/public/User/Events/UserLoggedOutEvent.php diff --git a/apps/files_external/tests/Service/UserGlobalStoragesServiceTest.php b/apps/files_external/tests/Service/UserGlobalStoragesServiceTest.php index ef8dc8a250ebc..ea0b10e8864a2 100644 --- a/apps/files_external/tests/Service/UserGlobalStoragesServiceTest.php +++ b/apps/files_external/tests/Service/UserGlobalStoragesServiceTest.php @@ -30,6 +30,7 @@ use OCA\Files_External\NotFoundException; use OCA\Files_External\Service\StoragesService; use OCA\Files_External\Service\UserGlobalStoragesService; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IGroupManager; use OCP\IUser; use OCP\IUserSession; @@ -65,7 +66,7 @@ protected function setUp(): void { $this->globalStoragesService = $this->service; - $this->user = new \OC\User\User(self::USER_ID, null, \OC::$server->getEventDispatcher()); + $this->user = new \OC\User\User(self::USER_ID, null, \OC::$server->query(IEventDispatcher::class)); /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject $userSession */ $userSession = $this->createMock(IUserSession::class); $userSession diff --git a/apps/user_ldap/tests/LDAPProviderTest.php b/apps/user_ldap/tests/LDAPProviderTest.php index b6e63f4a7ae56..84b9458cdbeb1 100644 --- a/apps/user_ldap/tests/LDAPProviderTest.php +++ b/apps/user_ldap/tests/LDAPProviderTest.php @@ -37,7 +37,6 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IServerContainer; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Class LDAPProviderTest @@ -78,7 +77,6 @@ private function getUserManagerMock(IUserLDAP $userBackend) { ->setMethods(['getBackends']) ->setConstructorArgs([ $this->createMock(IConfig::class), - $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class) ]) ->getMock(); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 563d7cf7c726a..faf2f0efb9f37 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -452,9 +452,19 @@ 'OCP\\User\\Backend\\IProvideAvatarBackend' => $baseDir . '/lib/public/User/Backend/IProvideAvatarBackend.php', 'OCP\\User\\Backend\\ISetDisplayNameBackend' => $baseDir . '/lib/public/User/Backend/ISetDisplayNameBackend.php', 'OCP\\User\\Backend\\ISetPasswordBackend' => $baseDir . '/lib/public/User/Backend/ISetPasswordBackend.php', - 'OCP\\User\\Events\\CreateUserEvent' => $baseDir . '/lib/public/User/Events/CreateUserEvent.php', - 'OCP\\User\\Events\\PostLoginEvent' => $baseDir . '/lib/public/User/Events/PostLoginEvent.php', + 'OCP\\User\\Events\\BeforePasswordUpdatedEvent' => $baseDir . '/lib/public/User/Events/BeforePasswordUpdatedEvent.php', + 'OCP\\User\\Events\\BeforeUserCreatedEvent' => $baseDir . '/lib/public/User/Events/BeforeUserCreatedEvent.php', + 'OCP\\User\\Events\\BeforeUserDeletedEvent' => $baseDir . '/lib/public/User/Events/BeforeUserDeletedEvent.php', + 'OCP\\User\\Events\\BeforeUserLoggedInEvent' => $baseDir . '/lib/public/User/Events/BeforeUserLoggedInEvent.php', + 'OCP\\User\\Events\\BeforeUserLoggedInWithCookieEvent' => $baseDir . '/lib/public/User/Events/BeforeUserLoggedInWithCookieEvent.php', + 'OCP\\User\\Events\\BeforeUserLoggedOutEvent' => $baseDir . '/lib/public/User/Events/BeforeUserLoggedOutEvent.php', + 'OCP\\User\\Events\\PasswordUpdatedEvent' => $baseDir . '/lib/public/User/Events/PasswordUpdatedEvent.php', + 'OCP\\User\\Events\\UserChangedEvent' => $baseDir . '/lib/public/User/Events/UserChangedEvent.php', 'OCP\\User\\Events\\UserCreatedEvent' => $baseDir . '/lib/public/User/Events/UserCreatedEvent.php', + 'OCP\\User\\Events\\UserDeletedEvent' => $baseDir . '/lib/public/User/Events/UserDeletedEvent.php', + 'OCP\\User\\Events\\UserLoggedInEvent' => $baseDir . '/lib/public/User/Events/UserLoggedInEvent.php', + 'OCP\\User\\Events\\UserLoggedInWithCookieEvent' => $baseDir . '/lib/public/User/Events/UserLoggedInWithCookieEvent.php', + 'OCP\\User\\Events\\UserLoggedOutEvent' => $baseDir . '/lib/public/User/Events/UserLoggedOutEvent.php', 'OCP\\Util' => $baseDir . '/lib/public/Util.php', 'OCP\\WorkflowEngine\\EntityContext\\IDisplayName' => $baseDir . '/lib/public/WorkflowEngine/EntityContext/IDisplayName.php', 'OCP\\WorkflowEngine\\EntityContext\\IDisplayText' => $baseDir . '/lib/public/WorkflowEngine/EntityContext/IDisplayText.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 140ec461857bc..966945800cb8b 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -481,9 +481,19 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\User\\Backend\\IProvideAvatarBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IProvideAvatarBackend.php', 'OCP\\User\\Backend\\ISetDisplayNameBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ISetDisplayNameBackend.php', 'OCP\\User\\Backend\\ISetPasswordBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ISetPasswordBackend.php', - 'OCP\\User\\Events\\CreateUserEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/CreateUserEvent.php', - 'OCP\\User\\Events\\PostLoginEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/PostLoginEvent.php', + 'OCP\\User\\Events\\BeforePasswordUpdatedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/BeforePasswordUpdatedEvent.php', + 'OCP\\User\\Events\\BeforeUserCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/BeforeUserCreatedEvent.php', + 'OCP\\User\\Events\\BeforeUserDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/BeforeUserDeletedEvent.php', + 'OCP\\User\\Events\\BeforeUserLoggedInEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/BeforeUserLoggedInEvent.php', + 'OCP\\User\\Events\\BeforeUserLoggedInWithCookieEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/BeforeUserLoggedInWithCookieEvent.php', + 'OCP\\User\\Events\\BeforeUserLoggedOutEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/BeforeUserLoggedOutEvent.php', + 'OCP\\User\\Events\\PasswordUpdatedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/PasswordUpdatedEvent.php', + 'OCP\\User\\Events\\UserChangedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserChangedEvent.php', 'OCP\\User\\Events\\UserCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserCreatedEvent.php', + 'OCP\\User\\Events\\UserDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserDeletedEvent.php', + 'OCP\\User\\Events\\UserLoggedInEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserLoggedInEvent.php', + 'OCP\\User\\Events\\UserLoggedInWithCookieEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserLoggedInWithCookieEvent.php', + 'OCP\\User\\Events\\UserLoggedOutEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserLoggedOutEvent.php', 'OCP\\Util' => __DIR__ . '/../../..' . '/lib/public/Util.php', 'OCP\\WorkflowEngine\\EntityContext\\IDisplayName' => __DIR__ . '/../../..' . '/lib/public/WorkflowEngine/EntityContext/IDisplayName.php', 'OCP\\WorkflowEngine\\EntityContext\\IDisplayText' => __DIR__ . '/../../..' . '/lib/public/WorkflowEngine/EntityContext/IDisplayText.php', diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index 9151a5130a1fe..e6b8ff026c2d9 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -50,6 +50,7 @@ use OC\User\User; use OCA\Files_Sharing\SharedMount; use OCP\Constants; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Cache\ICacheEntry; use OCP\Files\EmptyFileNameException; use OCP\Files\FileNameTooLongException; @@ -1308,9 +1309,8 @@ private function getUserObjectForOwner($ownerId) { $owner = $this->userManager->get($ownerId); if ($owner instanceof IUser) { return $owner; - } else { - return new User($ownerId, null, \OC::$server->getEventDispatcher()); } + return new User($ownerId, null, \OC::$server->query(IEventDispatcher::class)); } /** diff --git a/lib/private/Server.php b/lib/private/Server.php index dcac72369e4d8..6ae950802dc9c 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -163,6 +163,19 @@ use OCP\RichObjectStrings\IValidator; use OCP\Security\IContentSecurityPolicyManager; use OCP\Share\IShareHelper; +use OCP\User\Events\BeforePasswordUpdatedEvent; +use OCP\User\Events\BeforeUserCreatedEvent; +use OCP\User\Events\BeforeUserDeletedEvent; +use OCP\User\Events\BeforeUserLoggedInEvent; +use OCP\User\Events\BeforeUserLoggedInWithCookieEvent; +use OCP\User\Events\BeforeUserLoggedOutEvent; +use OCP\User\Events\PasswordUpdatedEvent; +use OCP\User\Events\UserChangedEvent; +use OCP\User\Events\UserCreatedEvent; +use OCP\User\Events\UserDeletedEvent; +use OCP\User\Events\UserLoggedInEvent; +use OCP\User\Events\UserLoggedInWithCookieEvent; +use OCP\User\Events\UserLoggedOutEvent; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; @@ -380,8 +393,9 @@ public function __construct($webRoot, \OC\Config $config) { $defaultTokenProvider = null; } - $dispatcher = $c->getEventDispatcher(); - + $symfonyDispatcher = $c->getEventDispatcher(); + /** @var IEventDispatcher $eventDispatcher */ + $eventDispatcher = $c->query(IEventDispatcher::class); $userSession = new \OC\User\Session( $manager, $session, @@ -393,48 +407,129 @@ public function __construct($webRoot, \OC\Config $config) { $c->getLogger(), $c->query(IEventDispatcher::class) ); - $userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) { - \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password)); + + // Convert new, typed events to legacy Symfony events and hooks + $eventDispatcher->addListener(BeforeUserCreatedEvent::class, function(BeforeUserCreatedEvent $event) use ($c) { + $c->getUserManager()->emit('\OC\User', 'preCreateUser', [$event->getUid(), $event->getPassword()]); + \OC_Hook::emit('OC_User', 'pre_createUser', [ + 'run' => true, + 'uid' => $event->getUid(), + 'password' => $event->getPassword(), + ]); + }); + $eventDispatcher->addListener(UserCreatedEvent::class, function(UserCreatedEvent $event) use ($c) { + $c->getUserManager()->emit('\OC\User', 'postCreateUser', [$event->getUser(), $event->getPassword()]); + \OC_Hook::emit('OC_User', 'post_createUser', [ + 'uid' => $event->getUid(), + 'password' => $event->getPassword(), + ]); }); - $userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password)); + $eventDispatcher->addListener(BeforePasswordUpdatedEvent::class, function(BeforePasswordUpdatedEvent $event) use ($symfonyDispatcher, $c) { + $symfonyDispatcher->dispatch(IUser::class . '::preSetPassword', new GenericEvent($event->getUser(), [ + 'password' => $event->getPassword(), + 'recoveryPassword' => $event->getRecoveryPassword(), + ])); + $c->getUserManager()->emit('\OC\User', 'preSetPassword', [ + $event->getUser(), + $event->getPassword(), + $event->getRecoveryPassword() + ]); }); - $userSession->listen('\OC\User', 'preDelete', function ($user) use ($dispatcher) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID())); - $dispatcher->dispatch('OCP\IUser::preDelete', new GenericEvent($user)); + $eventDispatcher->addListener(PasswordUpdatedEvent::class, function(PasswordUpdatedEvent $event) use ($symfonyDispatcher, $c) { + $symfonyDispatcher->dispatch(IUser::class . '::postSetPassword', new GenericEvent($event->getUser(), [ + 'password' => $event->getPassword(), + 'recoveryPassword' => $event->getRecoveryPassword(), + ])); + $c->getUserManager()->emit('\OC\User', 'postSetPassword', [ + $event->getUser(), + $event->getPassword(), + $event->getRecoveryPassword() + ]); + \OC_Hook::emit('OC_User', 'post_setPassword', [ + 'run' => true, + 'uid' => $event->getUser()->getUID(), + 'password' => $event->getPassword(), + 'recoveryPassword' => $event->getRecoveryPassword(), + ]); }); - $userSession->listen('\OC\User', 'postDelete', function ($user) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID())); + $eventDispatcher->addListener(BeforeUserDeletedEvent::class, function(BeforeUserDeletedEvent $event) use ($symfonyDispatcher, $c) { + $symfonyDispatcher->dispatch(IUser::class . '::preDelete', new GenericEvent($event->getUser())); + $c->getUserManager()->emit('\OC\User', 'preDelete', [$event->getUser()]); + \OC_Hook::emit('OC_User', 'pre_deleteUser', ['run' => true, 'uid' => $event->getUser()->getUID()]); }); - $userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword)); + $eventDispatcher->addListener(UserDeletedEvent::class, function(UserDeletedEvent $event) use ($symfonyDispatcher, $c) { + $symfonyDispatcher->dispatch(IUser::class . '::postDelete', new GenericEvent($event->getUser())); + $c->getUserManager()->emit('\OC\User', 'postDelete', [$event->getUser()]); + \OC_Hook::emit('OC_User', 'post_deleteUser', ['uid' => $event->getUser()->getUID()]); }); - $userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword)); + $eventDispatcher->addListener(UserChangedEvent::class, function(UserChangedEvent $event) use ($c, $symfonyDispatcher) { + $symfonyDispatcher->dispatch(IUser::class . '::changeUser', new GenericEvent($event->getUser(), [ + 'feature' => $event->getFeature(), + 'value' => $event->getValue(), + 'oldValue' => $event->getOldValue(), + ])); + $c->getUserManager()->emit('\OC\User', 'changeUser', [ + $event->getUser(), + $event->getFeature(), + $event->getValue(), + $event->getOldValue(), + ]); + \OC_Hook::emit('OC_User', 'changeUser', [ + 'run' => true, + 'user' => $event->getUser(), + 'feature' => $event->getFeature(), + 'value' => $event->getValue(), + 'old_value' => $event->getOldValue(), + ]); }); - $userSession->listen('\OC\User', 'preLogin', function ($uid, $password) { - \OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password)); + $eventDispatcher->addListener(BeforeUserLoggedInEvent::class, function(BeforeUserLoggedInEvent $event) use ($c) { + $c->getUserManager()->emit('\OC\User', 'preLogin', [ + $event->getUsername(), + $event->getPassword(), + ]); + \OC_Hook::emit('OC_User', 'pre_login', [ + 'run' => true, + 'uid' => $event->getUsername(), + 'password' => $event->getPassword(), + ]); }); - $userSession->listen('\OC\User', 'postLogin', function ($user, $password, $isTokenLogin) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'isTokenLogin' => $isTokenLogin)); + $eventDispatcher->addListener(UserLoggedInEvent::class, function(UserLoggedInEvent $event) use ($c) { + $c->getUserManager()->emit('\OC\User', 'postLogin', [ + $event->getUser(), + $event->getPassword(), + $event->isTokenLogin(), + ]); + \OC_Hook::emit('OC_User', 'post_login', [ + 'run' => true, + 'uid' => $event->getUser()->getUID(), + 'password' => $event->getPassword(), + 'isTokenLogin' => $event->isTokenLogin(), + ]); }); - $userSession->listen('\OC\User', 'postRememberedLogin', function ($user, $password) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password)); + $eventDispatcher->addListener(BeforeUserLoggedInWithCookieEvent::class, function(BeforeUserLoggedInWithCookieEvent $event) use ($c) { + $c->getUserManager()->emit('\OC\User', 'preRememberedLogin', [ + $event->getUsername(), + ]); }); - $userSession->listen('\OC\User', 'logout', function () { - \OC_Hook::emit('OC_User', 'logout', array()); + $eventDispatcher->addListener(UserLoggedInWithCookieEvent::class, function(UserLoggedInWithCookieEvent $event) use ($c) { + $c->getUserManager()->emit('\OC\User', 'postRememberedLogin', [ + $event->getUser(), + $event->getPassword(), + ]); + \OC_Hook::emit('OC_User', 'post_login', [ + 'run' => true, + 'uid' => $event->getUser()->getUID(), + 'password' => $event->getPassword(), + ]); }); - $userSession->listen('\OC\User', 'changeUser', function ($user, $feature, $value, $oldValue) { - /** @var $user \OC\User\User */ - \OC_Hook::emit('OC_User', 'changeUser', array('run' => true, 'user' => $user, 'feature' => $feature, 'value' => $value, 'old_value' => $oldValue)); + $eventDispatcher->addListener(BeforeUserLoggedOutEvent::class, function(BeforeUserLoggedOutEvent $event) use ($c) { + $c->getUserManager()->emit('\OC\User', 'logout'); + \OC_Hook::emit('OC_User', 'logout', []); }); + $eventDispatcher->addListener(UserLoggedOutEvent::class, function(UserLoggedOutEvent $event) use ($c) { + $c->getUserManager()->emit('\OC\User', 'postLogout'); + }); + return $userSession; }); $this->registerAlias(\OCP\IUserSession::class, \OC\User\Session::class); @@ -1848,6 +1943,7 @@ public function getCapabilitiesManager() { * * @return EventDispatcherInterface * @since 8.2.0 + * @deprecated inject or query \OCP\EventDispatcher\IEventDispatcher instead */ public function getEventDispatcher() { return $this->query(\OC\EventDispatcher\SymfonyAdapter::class); diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 7fc774630bdac..9e9a8953b8fc6 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -43,10 +43,9 @@ use OCP\IUserBackend; use OCP\IUserManager; use OCP\User\Backend\IGetRealUIDBackend; -use OCP\User\Events\CreateUserEvent; +use OCP\User\Events\BeforeUserCreatedEvent; use OCP\User\Events\UserCreatedEvent; use OCP\UserInterface; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Class Manager @@ -66,33 +65,25 @@ * @package OC\User */ class Manager extends PublicEmitter implements IUserManager { - /** - * @var \OCP\UserInterface[] $backends - */ + + /** @var UserInterface[] $backends */ private $backends = array(); - /** - * @var \OC\User\User[] $cachedUsers - */ + /** @var User[] $cachedUsers */ private $cachedUsers = array(); /** @var IConfig */ private $config; - /** @var EventDispatcherInterface */ - private $dispatcher; - /** @var IEventDispatcher */ private $eventDispatcher; public function __construct(IConfig $config, - EventDispatcherInterface $oldDispatcher, IEventDispatcher $eventDispatcher) { $this->config = $config; - $this->dispatcher = $oldDispatcher; $cachedUsers = &$this->cachedUsers; $this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) { - /** @var \OC\User\User $user */ + /** @var User $user */ unset($cachedUsers[$user->getUID()]); }); $this->eventDispatcher = $eventDispatcher; @@ -100,7 +91,8 @@ public function __construct(IConfig $config, /** * Get the active backends - * @return \OCP\UserInterface[] + * + * @return UserInterface[] */ public function getBackends() { return $this->backends; @@ -109,7 +101,7 @@ public function getBackends() { /** * register a user backend * - * @param \OCP\UserInterface $backend + * @param UserInterface $backend */ public function registerBackend($backend) { $this->backends[] = $backend; @@ -118,7 +110,7 @@ public function registerBackend($backend) { /** * remove a user backend * - * @param \OCP\UserInterface $backend + * @param UserInterface $backend */ public function removeBackend($backend) { $this->cachedUsers = array(); @@ -139,7 +131,8 @@ public function clearBackends() { * get a user by user id * * @param string $uid - * @return \OC\User\User|null Either the user or null if the specified user does not exist + * + * @return User|null Either the user or null if the specified user does not exist */ public function get($uid) { if (is_null($uid) || $uid === '' || $uid === false) { @@ -160,9 +153,10 @@ public function get($uid) { * get or construct the user object * * @param string $uid - * @param \OCP\UserInterface $backend + * @param UserInterface $backend * @param bool $cacheUser If false the newly created user object will not be cached - * @return \OC\User\User + * + * @return User */ protected function getUserObject($uid, $backend, $cacheUser = true) { if ($backend instanceof IGetRealUIDBackend) { @@ -173,7 +167,7 @@ protected function getUserObject($uid, $backend, $cacheUser = true) { return $this->cachedUsers[$uid]; } - $user = new User($uid, $backend, $this->dispatcher, $this, $this->config); + $user = new User($uid, $backend, $this->eventDispatcher, $this->config); if ($cacheUser) { $this->cachedUsers[$uid] = $user; } @@ -238,7 +232,8 @@ public function checkPasswordNoLogging($loginName, $password) { * @param string $pattern * @param int $limit * @param int $offset - * @return \OC\User\User[] + * + * @return User[] */ public function search($pattern, $limit = null, $offset = null) { $users = array(); @@ -253,8 +248,8 @@ public function search($pattern, $limit = null, $offset = null) { uasort($users, function ($a, $b) { /** - * @var \OC\User\User $a - * @var \OC\User\User $b + * @var User $a + * @var User $b */ return strcasecmp($a->getUID(), $b->getUID()); }); @@ -267,7 +262,8 @@ public function search($pattern, $limit = null, $offset = null) { * @param string $pattern * @param int $limit * @param int $offset - * @return \OC\User\User[] + * + * @return User[] */ public function searchDisplayName($pattern, $limit = null, $offset = null) { $users = array(); @@ -282,8 +278,8 @@ public function searchDisplayName($pattern, $limit = null, $offset = null) { usort($users, function ($a, $b) { /** - * @var \OC\User\User $a - * @var \OC\User\User $b + * @var User $a + * @var User $b */ return strcasecmp($a->getDisplayName(), $b->getDisplayName()); }); @@ -365,15 +361,13 @@ public function createUserFromBackend($uid, $password, UserInterface $backend) { throw new \InvalidArgumentException($l->t('The username is already being used')); } - $this->emit('\OC\User', 'preCreateUser', [$uid, $password]); - $this->eventDispatcher->dispatchTyped(new CreateUserEvent($uid, $password)); + $this->eventDispatcher->dispatchTyped(new BeforeUserCreatedEvent($uid, $password)); $state = $backend->createUser($uid, $password); if($state === false) { throw new \InvalidArgumentException($l->t('Could not create user')); } $user = $this->getUserObject($uid, $backend); if ($user instanceof IUser) { - $this->emit('\OC\User', 'postCreateUser', [$user, $password]); $this->eventDispatcher->dispatchTyped(new UserCreatedEvent($user, $password)); } return $user; diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 16d3b13cbabd2..581ec6d96dac0 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -62,7 +62,12 @@ use OCP\Lockdown\ILockdownManager; use OCP\Security\ISecureRandom; use OCP\Session\Exceptions\SessionNotAvailableException; -use OCP\User\Events\PostLoginEvent; +use OCP\User\Events\BeforeUserLoggedInEvent; +use OCP\User\Events\BeforeUserLoggedInWithCookieEvent; +use OCP\User\Events\BeforeUserLoggedOutEvent; +use OCP\User\Events\UserLoggedInEvent; +use OCP\User\Events\UserLoggedInWithCookieEvent; +use OCP\User\Events\UserLoggedOutEvent; use OCP\Util; use Symfony\Component\EventDispatcher\GenericEvent; @@ -400,16 +405,11 @@ public function completeLogin(IUser $user, array $loginDetails, $regenerateSessi $firstTimeLogin = $user->updateLastLoginTimestamp(); } - $this->dispatcher->dispatchTyped(new PostLoginEvent( + $this->dispatcher->dispatchTyped(new UserLoggedInEvent( $user, $loginDetails['password'], $isToken )); - $this->manager->emit('\OC\User', 'postLogin', [ - $user, - $loginDetails['password'], - $isToken, - ]); if($this->isLoggedIn()) { $this->prepareUserLogin($firstTimeLogin, $regenerateSessionId); return true; @@ -438,10 +438,7 @@ public function logClientIn($user, IRequest $request, OC\Security\Bruteforce\Throttler $throttler) { $currentDelay = $throttler->sleepDelay($request->getRemoteAddress(), 'login'); - - if ($this->manager instanceof PublicEmitter) { - $this->manager->emit('\OC\User', 'preLogin', array($user, $password)); - } + $this->dispatcher->dispatchTyped(new BeforeUserLoggedInEvent($user, $password)); try { $isTokenPassword = $this->isTokenPassword($password); @@ -841,7 +838,7 @@ public function tryTokenLogin(IRequest $request) { */ public function loginWithCookie($uid, $currentToken, $oldSessionId) { $this->session->regenerateId(); - $this->manager->emit('\OC\User', 'preRememberedLogin', array($uid)); + $this->dispatcher->dispatchTyped(new BeforeUserLoggedInWithCookieEvent($uid)); $user = $this->manager->get($uid); if (is_null($user)) { // user does not exist @@ -883,7 +880,7 @@ public function loginWithCookie($uid, $currentToken, $oldSessionId) { } catch (PasswordlessTokenException $ex) { // Ignore } - $this->manager->emit('\OC\User', 'postRememberedLogin', [$user, $password]); + $this->dispatcher->dispatchTyped(new UserLoggedInWithCookieEvent($user, $password)); return true; } @@ -900,9 +897,9 @@ public function createRememberMeToken(IUser $user) { * logout the user from the session */ public function logout() { - $this->manager->emit('\OC\User', 'logout'); $user = $this->getUser(); - if (!is_null($user)) { + $this->dispatcher->dispatchTyped(new BeforeUserLoggedOutEvent($user)); + if ($user !== null) { try { $this->tokenProvider->invalidateToken($this->session->getId()); } catch (SessionNotAvailableException $ex) { @@ -914,7 +911,7 @@ public function logout() { $this->setToken(null); $this->unsetMagicInCookie(); $this->session->clear(); - $this->manager->emit('\OC\User', 'postLogout'); + $this->dispatcher->dispatchTyped(new UserLoggedOutEvent($user)); } /** diff --git a/lib/private/User/User.php b/lib/private/User/User.php index c68b8b88e31f4..b408c792ef99e 100644 --- a/lib/private/User/User.php +++ b/lib/private/User/User.php @@ -1,4 +1,5 @@ -uid = $uid; $this->backend = $backend; - $this->dispatcher = $dispatcher; - $this->emitter = $emitter; - if(is_null($config)) { + if($config === null) { $config = \OC::$server->getConfig(); } + $this->eventDispatcher = $eventDispatcher ?? \OC::$server->query(IEventDispatcher::class); $this->config = $config; $this->urlGenerator = $urlGenerator; $enabled = $this->config->getUserValue($uid, 'core', 'enabled', 'true'); $this->enabled = ($enabled === 'true'); $this->lastLogin = $this->config->getUserValue($uid, 'login', 'lastLogin', 0); - if (is_null($this->urlGenerator)) { + if ($this->urlGenerator === null) { $this->urlGenerator = \OC::$server->getURLGenerator(); } } @@ -200,10 +206,8 @@ public function updateLastLoginTimestamp() { * @return bool */ public function delete() { - $this->dispatcher->dispatch(IUser::class . '::preDelete', new GenericEvent($this)); - if ($this->emitter) { - $this->emitter->emit('\OC\User', 'preDelete', array($this)); - } + $this->eventDispatcher->dispatchTyped(new BeforeUserDeletedEvent($this)); + // get the home now because it won't return it after user deletion $homePath = $this->getHome(); $result = $this->backend->deleteUser($this->uid); @@ -245,10 +249,7 @@ public function delete() { $accountManager = \OC::$server->query(AccountManager::class); $accountManager->deleteUser($this); - $this->dispatcher->dispatch(IUser::class . '::postDelete', new GenericEvent($this)); - if ($this->emitter) { - $this->emitter->emit('\OC\User', 'postDelete', array($this)); - } + $this->eventDispatcher->dispatchTyped(new UserDeletedEvent($this)); } return !($result === false); } @@ -261,26 +262,22 @@ public function delete() { * @return bool */ public function setPassword($password, $recoveryPassword = null) { - $this->dispatcher->dispatch(IUser::class . '::preSetPassword', new GenericEvent($this, [ - 'password' => $password, - 'recoveryPassword' => $recoveryPassword, - ])); - if ($this->emitter) { - $this->emitter->emit('\OC\User', 'preSetPassword', array($this, $password, $recoveryPassword)); - } - if ($this->backend->implementsActions(Backend::SET_PASSWORD)) { - $result = $this->backend->setPassword($this->uid, $password); - $this->dispatcher->dispatch(IUser::class . '::postSetPassword', new GenericEvent($this, [ - 'password' => $password, - 'recoveryPassword' => $recoveryPassword, - ])); - if ($this->emitter) { - $this->emitter->emit('\OC\User', 'postSetPassword', array($this, $password, $recoveryPassword)); - } - return !($result === false); - } else { + $this->eventDispatcher->dispatchTyped(new BeforePasswordUpdatedEvent( + $this, + $password, + $recoveryPassword + )); + if (!$this->backend->implementsActions(Backend::SET_PASSWORD)) { return false; } + + $result = $this->backend->setPassword($this->uid, $password); + $this->eventDispatcher->dispatchTyped(new PasswordUpdatedEvent( + $this, + $password, + $recoveryPassword + )); + return !($result === false); } /** @@ -459,7 +456,9 @@ public function getCloudId() { private function removeProtocolFromUrl($url) { if (strpos($url, 'https://') === 0) { return substr($url, strlen('https://')); - } else if (strpos($url, 'http://') === 0) { + } + + if (strpos($url, 'http://') === 0) { return substr($url, strlen('http://')); } @@ -467,13 +466,7 @@ private function removeProtocolFromUrl($url) { } public function triggerChange($feature, $value = null, $oldValue = null) { - $this->dispatcher->dispatch(IUser::class . '::changeUser', new GenericEvent($this, [ - 'feature' => $feature, - 'value' => $value, - 'oldValue' => $oldValue, - ])); - if ($this->emitter) { - $this->emitter->emit('\OC\User', 'changeUser', array($this, $feature, $value, $oldValue)); - } + $this->eventDispatcher->dispatchTyped(new UserChangedEvent($this, $feature, $value, $oldValue)); } + } diff --git a/lib/public/User/Events/BeforePasswordUpdatedEvent.php b/lib/public/User/Events/BeforePasswordUpdatedEvent.php new file mode 100644 index 0000000000000..c40bd92b619d2 --- /dev/null +++ b/lib/public/User/Events/BeforePasswordUpdatedEvent.php @@ -0,0 +1,82 @@ + + * + * @author 2019 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class BeforePasswordUpdatedEvent extends Event { + + /** @var IUser */ + private $user; + + /** @var string */ + private $password; + + /** @var string|null */ + private $recoveryPassword; + + /** + * @param IUser $user + * @param string $password + * @param string|null $recoveryPassword + * @since 18.0.0 + */ + public function __construct(IUser $user, + string $password, + string $recoveryPassword = null) { + parent::__construct(); + $this->user = $user; + $this->password = $password; + $this->recoveryPassword = $recoveryPassword; + } + + /** + * @return IUser + * @since 18.0.0 + */ + public function getUser(): IUser { + return $this->user; + } + + /** + * @return string + * @since 18.0.0 + */ + public function getPassword(): string { + return $this->password; + } + + /** + * @return string|null + * @since 18.0.0 + */ + public function getRecoveryPassword(): ?string { + return $this->recoveryPassword; + } + +} diff --git a/lib/public/User/Events/CreateUserEvent.php b/lib/public/User/Events/BeforeUserCreatedEvent.php similarity index 96% rename from lib/public/User/Events/CreateUserEvent.php rename to lib/public/User/Events/BeforeUserCreatedEvent.php index 37525deb55f42..1a00a167dbbae 100644 --- a/lib/public/User/Events/CreateUserEvent.php +++ b/lib/public/User/Events/BeforeUserCreatedEvent.php @@ -31,7 +31,7 @@ /** * @since 18.0.0 */ -class CreateUserEvent extends Event { +class BeforeUserCreatedEvent extends Event { /** @var string */ private $uid; diff --git a/lib/public/User/Events/BeforeUserDeletedEvent.php b/lib/public/User/Events/BeforeUserDeletedEvent.php new file mode 100644 index 0000000000000..b40c498350f53 --- /dev/null +++ b/lib/public/User/Events/BeforeUserDeletedEvent.php @@ -0,0 +1,54 @@ + + * + * @author 2019 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class BeforeUserDeletedEvent extends Event { + + /** @var IUser */ + private $user; + + /** + * @param IUser $user + * @since 18.0.0 + */ + public function __construct(IUser $user) { + parent::__construct(); + $this->user = $user; + } + + /** + * @return IUser + * @since 18.0.0 + */ + public function getUser(): IUser { + return $this->user; + } + +} diff --git a/lib/public/User/Events/BeforeUserLoggedInEvent.php b/lib/public/User/Events/BeforeUserLoggedInEvent.php new file mode 100644 index 0000000000000..8b8194787370d --- /dev/null +++ b/lib/public/User/Events/BeforeUserLoggedInEvent.php @@ -0,0 +1,66 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class BeforeUserLoggedInEvent extends Event { + + /** @var IUser */ + private $username; + + /** @var string */ + private $password; + + /** + * @since 18.0.0 + */ + public function __construct(string $username, string $password) { + parent::__construct(); + $this->username = $username; + $this->password = $password; + } + + /** + * @since 18.0.0 + */ + public function getUsername(): IUser { + return $this->username; + } + + /** + * @since 18.0.0 + */ + public function getPassword(): string { + return $this->password; + } + +} diff --git a/lib/public/User/Events/BeforeUserLoggedInWithCookieEvent.php b/lib/public/User/Events/BeforeUserLoggedInWithCookieEvent.php new file mode 100644 index 0000000000000..af52a15c7370b --- /dev/null +++ b/lib/public/User/Events/BeforeUserLoggedInWithCookieEvent.php @@ -0,0 +1,55 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class BeforeUserLoggedInWithCookieEvent extends Event { + + /** @var IUser */ + private $username; + + /** + * @since 18.0.0 + */ + public function __construct(string $username) { + parent::__construct(); + $this->username = $username; + } + + /** + * @since 18.0.0 + */ + public function getUsername(): IUser { + return $this->username; + } + +} diff --git a/lib/public/User/Events/BeforeUserLoggedOutEvent.php b/lib/public/User/Events/BeforeUserLoggedOutEvent.php new file mode 100644 index 0000000000000..a5d617089f72e --- /dev/null +++ b/lib/public/User/Events/BeforeUserLoggedOutEvent.php @@ -0,0 +1,55 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class BeforeUserLoggedOutEvent extends Event { + + /** @var IUser|null */ + private $user; + + /** + * @since 18.0.0 + */ + public function __construct(IUser $user = null) { + parent::__construct(); + $this->user = $user; + } + + /** + * @since 18.0.0 + */ + public function getUser(): ?IUser { + return $this->user; + } + +} diff --git a/lib/public/User/Events/PasswordUpdatedEvent.php b/lib/public/User/Events/PasswordUpdatedEvent.php new file mode 100644 index 0000000000000..83b5b0a7bfd76 --- /dev/null +++ b/lib/public/User/Events/PasswordUpdatedEvent.php @@ -0,0 +1,82 @@ + + * + * @author 2019 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class PasswordUpdatedEvent extends Event { + + /** @var IUser */ + private $user; + + /** @var string */ + private $password; + + /** @var string|null */ + private $recoveryPassword; + + /** + * @param IUser $user + * @param string $password + * @param string|null $recoveryPassword + * @since 18.0.0 + */ + public function __construct(IUser $user, + string $password, + string $recoveryPassword = null) { + parent::__construct(); + $this->user = $user; + $this->password = $password; + $this->recoveryPassword = $recoveryPassword; + } + + /** + * @return IUser + * @since 18.0.0 + */ + public function getUser(): IUser { + return $this->user; + } + + /** + * @return string + * @since 18.0.0 + */ + public function getPassword(): string { + return $this->password; + } + + /** + * @return string|null + * @since 18.0.0 + */ + public function getRecoveryPassword(): ?string { + return $this->recoveryPassword; + } + +} diff --git a/lib/public/User/Events/UserChangedEvent.php b/lib/public/User/Events/UserChangedEvent.php new file mode 100644 index 0000000000000..86b2f439bfb6d --- /dev/null +++ b/lib/public/User/Events/UserChangedEvent.php @@ -0,0 +1,93 @@ + + * + * @author 2019 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class UserChangedEvent extends Event { + + /** @var IUser */ + private $user; + + /** @var string */ + private $feature; + + /** @var mixed */ + private $value; + + /** @var mixed */ + private $oldValue; + + /** + * @since 18.0.0 + */ + public function __construct(IUser $user, + string $feature, + $value, + $oldValue = null) { + parent::__construct(); + $this->user = $user; + $this->feature = $feature; + $this->value = $value; + $this->oldValue = $oldValue; + } + + /** + * @return IUser + * @since 18.0.0 + */ + public function getUser(): IUser { + return $this->user; + } + + /** + * @return string + * @since 18.0.0 + */ + public function getFeature(): string { + return $this->feature; + } + + /** + * @return mixed + * @since 18.0.0 + */ + public function getValue() { + return $this->value; + } + + /** + * @return mixed + * @since 18.0.0 + */ + public function getOldValue() { + return $this->oldValue; + } + + +} diff --git a/lib/public/User/Events/UserDeletedEvent.php b/lib/public/User/Events/UserDeletedEvent.php new file mode 100644 index 0000000000000..284ee35a2427a --- /dev/null +++ b/lib/public/User/Events/UserDeletedEvent.php @@ -0,0 +1,54 @@ + + * + * @author 2019 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class UserDeletedEvent extends Event { + + /** @var IUser */ + private $user; + + /** + * @param IUser $user + * @since 18.0.0 + */ + public function __construct(IUser $user) { + parent::__construct(); + $this->user = $user; + } + + /** + * @return IUser + * @since 18.0.0 + */ + public function getUser(): IUser { + return $this->user; + } + +} diff --git a/lib/public/User/Events/PostLoginEvent.php b/lib/public/User/Events/UserLoggedInEvent.php similarity index 97% rename from lib/public/User/Events/PostLoginEvent.php rename to lib/public/User/Events/UserLoggedInEvent.php index 15772bfef1794..8ce83f42308e6 100644 --- a/lib/public/User/Events/PostLoginEvent.php +++ b/lib/public/User/Events/UserLoggedInEvent.php @@ -33,7 +33,7 @@ /** * @since 18.0.0 */ -class PostLoginEvent extends Event { +class UserLoggedInEvent extends Event { /** @var IUser */ private $user; diff --git a/lib/public/User/Events/UserLoggedInWithCookieEvent.php b/lib/public/User/Events/UserLoggedInWithCookieEvent.php new file mode 100644 index 0000000000000..7a03bc8336c24 --- /dev/null +++ b/lib/public/User/Events/UserLoggedInWithCookieEvent.php @@ -0,0 +1,66 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class UserLoggedInWithCookieEvent extends Event { + + /** @var IUser */ + private $user; + + /** @var string */ + private $password; + + /** + * @since 18.0.0 + */ + public function __construct(IUser $user, string $password) { + parent::__construct(); + $this->user = $user; + $this->password = $password; + } + + /** + * @since 18.0.0 + */ + public function getUser(): IUser { + return $this->user; + } + + /** + * @since 18.0.0 + */ + public function getPassword(): string { + return $this->password; + } + +} diff --git a/lib/public/User/Events/UserLoggedOutEvent.php b/lib/public/User/Events/UserLoggedOutEvent.php new file mode 100644 index 0000000000000..14259149533ce --- /dev/null +++ b/lib/public/User/Events/UserLoggedOutEvent.php @@ -0,0 +1,55 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\User\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; + +/** + * @since 18.0.0 + */ +class UserLoggedOutEvent extends Event { + + /** @var IUser|null */ + private $user; + + /** + * @since 18.0.0 + */ + public function __construct(IUser $user = null) { + parent::__construct(); + $this->user = $user; + } + + /** + * @since 18.0.0 + */ + public function getUser(): ?IUser { + return $this->user; + } + +} diff --git a/tests/lib/Files/Cache/CacheTest.php b/tests/lib/Files/Cache/CacheTest.php index b2816c0309479..d31189526cc3c 100644 --- a/tests/lib/Files/Cache/CacheTest.php +++ b/tests/lib/Files/Cache/CacheTest.php @@ -13,6 +13,7 @@ use OC\Files\Cache\Cache; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Search\ISearchComparison; use OCP\IUser; @@ -332,7 +333,7 @@ function testSearchQueryByTag() { $userId = static::getUniqueID('user'); \OC::$server->getUserManager()->createUser($userId, $userId); static::loginAsUser($userId); - $user = new \OC\User\User($userId, null, \OC::$server->getEventDispatcher()); + $user = new \OC\User\User($userId, null, \OC::$server->query(IEventDispatcher::class)); $file1 = 'folder'; $file2 = 'folder/foobar'; diff --git a/tests/lib/Files/Config/UserMountCacheTest.php b/tests/lib/Files/Config/UserMountCacheTest.php index 2f61f634ffb6e..99bd279891094 100644 --- a/tests/lib/Files/Config/UserMountCacheTest.php +++ b/tests/lib/Files/Config/UserMountCacheTest.php @@ -46,7 +46,7 @@ class UserMountCacheTest extends TestCase { protected function setUp(): void { $this->fileIds = []; $this->connection = \OC::$server->getDatabaseConnection(); - $this->userManager = new Manager($this->createMock(IConfig::class), $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class)); + $this->userManager = new Manager($this->createMock(IConfig::class), $this->createMock(IEventDispatcher::class)); $userBackend = new Dummy(); $userBackend->createUser('u1', ''); $userBackend->createUser('u2', ''); diff --git a/tests/lib/Files/Node/IntegrationTest.php b/tests/lib/Files/Node/IntegrationTest.php index 2a542a1097a1d..3f04e74890ac8 100644 --- a/tests/lib/Files/Node/IntegrationTest.php +++ b/tests/lib/Files/Node/IntegrationTest.php @@ -12,6 +12,7 @@ use OC\Files\Storage\Temporary; use OC\Files\View; use OC\User\User; +use OCP\EventDispatcher\IEventDispatcher; use OCP\ILogger; use OCP\IUserManager; @@ -45,7 +46,7 @@ protected function setUp(): void { \OC_Hook::clear('OC_Filesystem'); - $user = new User($this->getUniqueID('user'), new \Test\Util\User\Dummy, \OC::$server->getEventDispatcher()); + $user = new User(self::getUniqueID('user'), new \Test\Util\User\Dummy, \OC::$server->query(IEventDispatcher::class)); $this->loginAsUser($user->getUID()); $this->view = new View(); diff --git a/tests/lib/Files/Storage/Wrapper/EncryptionTest.php b/tests/lib/Files/Storage/Wrapper/EncryptionTest.php index a9d678e76e998..5f7bd60957b94 100644 --- a/tests/lib/Files/Storage/Wrapper/EncryptionTest.php +++ b/tests/lib/Files/Storage/Wrapper/EncryptionTest.php @@ -19,7 +19,6 @@ use OCP\Files\Mount\IMountPoint; use OCP\IConfig; use OCP\ILogger; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\Files\Storage\Storage; class EncryptionTest extends Storage { @@ -132,7 +131,7 @@ protected function setUp(): void { $this->util = $this->getMockBuilder('\OC\Encryption\Util') ->setMethods(['getUidAndFilename', 'isFile', 'isExcluded']) - ->setConstructorArgs([new View(), new Manager($this->config, $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class)), $this->groupManager, $this->config, $this->arrayCache]) + ->setConstructorArgs([new View(), new Manager($this->config, $this->createMock(IEventDispatcher::class)), $this->groupManager, $this->config, $this->arrayCache]) ->getMock(); $this->util->expects($this->any()) ->method('getUidAndFilename') @@ -569,7 +568,7 @@ public function testGetHeader($path, $strippedPathExists, $strippedPath) { ->setConstructorArgs( [ new View(), - new Manager($this->config, $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class)), + new Manager($this->config, $this->createMock(IEventDispatcher::class)), $this->groupManager, $this->config, $this->arrayCache @@ -638,7 +637,7 @@ public function testGetHeaderAddLegacyModule($header, $isEncrypted, $exists, $ex ->willReturn($exists); $util = $this->getMockBuilder('\OC\Encryption\Util') - ->setConstructorArgs([new View(), new Manager($this->config, $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class)), $this->groupManager, $this->config, $this->arrayCache]) + ->setConstructorArgs([new View(), new Manager($this->config, $this->createMock(IEventDispatcher::class)), $this->groupManager, $this->config, $this->arrayCache]) ->getMock(); $cache = $this->getMockBuilder('\OC\Files\Cache\Cache') diff --git a/tests/lib/Files/Stream/EncryptionTest.php b/tests/lib/Files/Stream/EncryptionTest.php index fd5e8c6ca9d6b..0f562cf508a9b 100644 --- a/tests/lib/Files/Stream/EncryptionTest.php +++ b/tests/lib/Files/Stream/EncryptionTest.php @@ -49,7 +49,7 @@ protected function getStream($fileName, $mode, $unencryptedSize, $wrapper = '\OC $file->expects($this->any())->method('getAccessList')->willReturn([]); $util = $this->getMockBuilder('\OC\Encryption\Util') ->setMethods(['getUidAndFilename']) - ->setConstructorArgs([new View(), new \OC\User\Manager($config, $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class)), $groupManager, $config, $arrayCache]) + ->setConstructorArgs([new View(), new \OC\User\Manager($config, $this->createMock(IEventDispatcher::class)), $groupManager, $config, $arrayCache]) ->getMock(); $util->expects($this->any()) ->method('getUidAndFilename') diff --git a/tests/lib/User/DatabaseTest.php b/tests/lib/User/DatabaseTest.php index 65d483734d9c6..f027a2fd4fb9c 100644 --- a/tests/lib/User/DatabaseTest.php +++ b/tests/lib/User/DatabaseTest.php @@ -28,7 +28,6 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Security\Events\ValidatePasswordPolicyEvent; use PHPUnit\Framework\MockObject\MockObject; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Class DatabaseTest @@ -82,7 +81,7 @@ function (Event $event) { $this->assertSame($user, $this->backend->checkPassword($user, 'newpass')); } - + public function testVerifyPasswordEventFail() { $this->expectException(\OC\HintException::class); $this->expectExceptionMessage('password change failed'); @@ -130,8 +129,8 @@ public function testSearch() { $user2 = $this->getUser(); $this->backend->createUser($user2, 'pass1'); - $user1Obj = new User($user1, $this->backend, $this->createMock(EventDispatcherInterface::class)); - $user2Obj = new User($user2, $this->backend, $this->createMock(EventDispatcherInterface::class)); + $user1Obj = new User($user1, $this->backend, $this->createMock(IEventDispatcher::class)); + $user2Obj = new User($user2, $this->backend, $this->createMock(IEventDispatcher::class)); $emailAddr1 = "$user1@nextcloud.com"; $emailAddr2 = "$user2@nextcloud.com"; diff --git a/tests/lib/User/ManagerTest.php b/tests/lib/User/ManagerTest.php index 40197101fd6e7..e0b2502f9ab91 100644 --- a/tests/lib/User/ManagerTest.php +++ b/tests/lib/User/ManagerTest.php @@ -14,7 +14,6 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IUser; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\TestCase; /** @@ -28,8 +27,6 @@ class ManagerTest extends TestCase { /** @var IConfig */ private $config; - /** @var EventDispatcherInterface */ - private $oldDispatcher; /** @var IEventDispatcher */ private $eventDispatcher; @@ -37,13 +34,12 @@ protected function setUp(): void { parent::setUp(); $this->config = $this->createMock(IConfig::class); - $this->oldDispatcher = $this->createMock(EventDispatcherInterface::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); } public function testGetBackends() { $userDummyBackend = $this->createMock(\Test\Util\User\Dummy::class); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($userDummyBackend); $this->assertEquals([$userDummyBackend], $manager->getBackends()); $dummyDatabaseBackend = $this->createMock(Database::class); @@ -62,7 +58,7 @@ public function testUserExistsSingleBackendExists() { ->with($this->equalTo('foo')) ->will($this->returnValue(true)); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $this->assertTrue($manager->userExists('foo')); @@ -78,14 +74,14 @@ public function testUserExistsSingleBackendNotExists() { ->with($this->equalTo('foo')) ->will($this->returnValue(false)); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $this->assertFalse($manager->userExists('foo')); } public function testUserExistsNoBackends() { - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $this->assertFalse($manager->userExists('foo')); } @@ -109,7 +105,7 @@ public function testUserExistsTwoBackendsSecondExists() { ->with($this->equalTo('foo')) ->will($this->returnValue(true)); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend1); $manager->registerBackend($backend2); @@ -133,7 +129,7 @@ public function testUserExistsTwoBackendsFirstExists() { $backend2->expects($this->never()) ->method('userExists'); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend1); $manager->registerBackend($backend2); @@ -160,7 +156,7 @@ public function testCheckPassword() { } })); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $user = $manager->checkPassword('foo', 'bar'); @@ -179,7 +175,7 @@ public function testCheckPasswordNotSupported() { ->method('implementsActions') ->will($this->returnValue(false)); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $this->assertFalse($manager->checkPassword('foo', 'bar')); @@ -197,7 +193,7 @@ public function testGetOneBackendExists() { $backend->expects($this->never()) ->method('loginName2UserName'); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $this->assertEquals('foo', $manager->get('foo')->getUID()); @@ -213,7 +209,7 @@ public function testGetOneBackendNotExists() { ->with($this->equalTo('foo')) ->will($this->returnValue(false)); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $this->assertEquals(null, $manager->get('foo')); @@ -231,7 +227,7 @@ public function testGetOneBackendDoNotTranslateLoginNames() { $backend->expects($this->never()) ->method('loginName2UserName'); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $this->assertEquals('bLeNdEr', $manager->get('bLeNdEr')->getUID()); @@ -249,7 +245,7 @@ public function testSearchOneBackend() { $backend->expects($this->never()) ->method('loginName2UserName'); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $result = $manager->search('fo'); @@ -283,7 +279,7 @@ public function testSearchTwoBackendLimitOffset() { $backend2->expects($this->never()) ->method('loginName2UserName'); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend1); $manager->registerBackend($backend2); @@ -337,7 +333,7 @@ public function testCreateUserInvalid($uid, $password, $exception) { ->willReturn(true); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $this->expectException(\InvalidArgumentException::class, $exception); @@ -364,7 +360,7 @@ public function testCreateUserSingleBackendNotExists() { $backend->expects($this->never()) ->method('loginName2UserName'); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $user = $manager->createUser('foo', 'bar'); @@ -391,7 +387,7 @@ public function testCreateUserSingleBackendExists() { ->with($this->equalTo('foo')) ->will($this->returnValue(true)); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $manager->createUser('foo', 'bar'); @@ -412,14 +408,14 @@ public function testCreateUserSingleBackendNotSupported() { $backend->expects($this->never()) ->method('userExists'); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $this->assertFalse($manager->createUser('foo', 'bar')); } public function testCreateUserNoBackends() { - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $this->assertFalse($manager->createUser('foo', 'bar')); } @@ -439,7 +435,7 @@ public function testCreateUserFromBackendWithBackendError() { ->with('MyUid', 'MyPassword') ->willReturn(false); - $manager = new Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->createUserFromBackend('MyUid', 'MyPassword', $backend); } @@ -479,7 +475,7 @@ public function testCreateUserTwoBackendExists() { ->with($this->equalTo('foo')) ->will($this->returnValue(true)); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend1); $manager->registerBackend($backend2); @@ -487,7 +483,7 @@ public function testCreateUserTwoBackendExists() { } public function testCountUsersNoBackend() { - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $result = $manager->countUsers(); $this->assertTrue(is_array($result)); @@ -512,7 +508,7 @@ public function testCountUsersOneBackend() { ->method('getBackendName') ->will($this->returnValue('Mock_Test_Util_User_Dummy')); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend); $result = $manager->countUsers(); @@ -553,7 +549,7 @@ public function testCountUsersTwoBackends() { ->method('getBackendName') ->will($this->returnValue('Mock_Test_Util_User_Dummy')); - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $manager->registerBackend($backend1); $manager->registerBackend($backend2); @@ -654,7 +650,7 @@ public function testCallForSeenUsers() { } public function testDeleteUser() { - $manager = new \OC\User\Manager($this->config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($this->config, $this->eventDispatcher); $backend = new \Test\Util\User\Dummy(); $manager->registerBackend($backend); @@ -688,7 +684,7 @@ public function testGetByEmail() { ->with($this->equalTo('uid2')) ->will($this->returnValue(true)); - $manager = new \OC\User\Manager($config, $this->oldDispatcher, $this->eventDispatcher); + $manager = new Manager($config, $this->eventDispatcher); $manager->registerBackend($backend); $users = $manager->getByEmail('test@example.com'); diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index e7df7578c7dca..3640854af69ea 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -29,9 +29,8 @@ use OCP\Lockdown\ILockdownManager; use OCP\Security\ICrypto; use OCP\Security\ISecureRandom; -use OCP\User\Events\PostLoginEvent; +use OCP\User\Events\UserLoggedInEvent; use PHPUnit\Framework\MockObject\MockObject; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * @group DB @@ -175,7 +174,7 @@ public function testIsLoggedIn($isLoggedIn) { 'getUser' ]) ->getMock(); - $user = new User('sepp', null, $this->createMock(EventDispatcherInterface::class)); + $user = new User('sepp', null, $this->createMock(IEventDispatcher::class)); $userSession->expects($this->once()) ->method('getUser') ->will($this->returnValue($isLoggedIn ? $user : null)); @@ -230,7 +229,6 @@ public function testLoginValidPasswordEnabled() { ->setMethods($mockedManagerMethods) ->setConstructorArgs([ $this->config, - $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class) ]) ->getMock(); @@ -264,7 +262,7 @@ public function testLoginValidPasswordEnabled() { $this->dispatcher->expects($this->once()) ->method('dispatchTyped') ->with( - $this->callback(function(PostLoginEvent $e) { + $this->callback(function(UserLoggedInEvent $e) { return $e->getUser()->getUID() === 'foo' && $e->getPassword() === 'bar' && $e->isTokenLogin() === false; @@ -296,7 +294,6 @@ public function testLoginValidPasswordDisabled() { ->setMethods($mockedManagerMethods) ->setConstructorArgs([ $this->config, - $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class) ]) ->getMock(); @@ -329,7 +326,6 @@ public function testLoginInvalidPassword() { ->setMethods($mockedManagerMethods) ->setConstructorArgs([ $this->config, - $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class) ]) ->getMock(); @@ -572,7 +568,6 @@ public function testRememberLoginValidToken() { ->setMethods($mockedManagerMethods) ->setConstructorArgs([ $this->config, - $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class) ]) ->getMock(); @@ -661,7 +656,6 @@ public function testRememberLoginInvalidSessionToken() { ->setMethods($mockedManagerMethods) ->setConstructorArgs([ $this->config, - $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class) ]) ->getMock(); @@ -725,7 +719,6 @@ public function testRememberLoginInvalidToken() { ->setMethods($mockedManagerMethods) ->setConstructorArgs([ $this->config, - $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class) ]) ->getMock(); @@ -777,7 +770,6 @@ public function testRememberLoginInvalidUser() { ->setMethods($mockedManagerMethods) ->setConstructorArgs([ $this->config, - $this->createMock(EventDispatcherInterface::class), $this->createMock(IEventDispatcher::class) ]) ->getMock(); @@ -815,8 +807,8 @@ public function testRememberLoginInvalidUser() { public function testActiveUserAfterSetSession() { $users = array( - 'foo' => new User('foo', null, $this->createMock(EventDispatcherInterface::class)), - 'bar' => new User('bar', null, $this->createMock(EventDispatcherInterface::class)) + 'foo' => new User('foo', null, $this->createMock(IEventDispatcher::class)), + 'bar' => new User('bar', null, $this->createMock(IEventDispatcher::class)) ); $manager = $this->getMockBuilder('\OC\User\Manager') diff --git a/tests/lib/User/UserTest.php b/tests/lib/User/UserTest.php index 0bf582727ff8d..77756cede72dc 100644 --- a/tests/lib/User/UserTest.php +++ b/tests/lib/User/UserTest.php @@ -1,4 +1,4 @@ - @@ -9,16 +9,19 @@ namespace Test\User; -use OC\Hooks\PublicEmitter; use OC\User\User; use OCP\Comments\ICommentsManager; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; -use OCP\IUser; use OCP\Notification\IManager as INotificationManager; use OCP\Notification\INotification; +use OCP\User\Events\BeforePasswordUpdatedEvent; +use OCP\User\Events\BeforeUserDeletedEvent; +use OCP\User\Events\PasswordUpdatedEvent; +use OCP\User\Events\UserChangedEvent; +use OCP\User\Events\UserDeletedEvent; use OCP\UserInterface; use PHPUnit\Framework\MockObject\MockObject; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\TestCase; /** @@ -30,17 +33,17 @@ */ class UserTest extends TestCase { - /** @var EventDispatcherInterface|MockObject */ + /** @var IEventDispatcher|MockObject */ protected $dispatcher; protected function setUp(): void { parent::setUp(); - $this->dispatcher = $this->createMock(EventDispatcherInterface::class); + $this->dispatcher = $this->createMock(IEventDispatcher::class); } public function testDisplayName() { /** - * @var \OC\User\Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var \OC\User\Backend|MockObject $backend */ $backend = $this->createMock(\OC\User\Backend::class); $backend->expects($this->once()) @@ -62,7 +65,7 @@ public function testDisplayName() { */ public function testDisplayNameEmpty() { /** - * @var \OC\User\Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var \OC\User\UserInterface|MockObject $backend */ $backend = $this->createMock(\OC\User\Backend::class); $backend->expects($this->once()) @@ -81,7 +84,7 @@ public function testDisplayNameEmpty() { public function testDisplayNameNotSupported() { /** - * @var \OC\User\Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var \OC\User\UserInterface|MockObject $backend */ $backend = $this->createMock(\OC\User\Backend::class); $backend->expects($this->never()) @@ -98,7 +101,7 @@ public function testDisplayNameNotSupported() { public function testSetPassword() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) @@ -121,7 +124,7 @@ public function testSetPassword() { public function testSetPasswordNotSupported() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->never()) @@ -137,7 +140,7 @@ public function testSetPasswordNotSupported() { public function testChangeAvatarSupportedYes() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(AvatarUserDummy::class); $backend->expects($this->once()) @@ -161,7 +164,7 @@ public function testChangeAvatarSupportedYes() { public function testChangeAvatarSupportedNo() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(AvatarUserDummy::class); $backend->expects($this->once()) @@ -185,7 +188,7 @@ public function testChangeAvatarSupportedNo() { public function testChangeAvatarNotSupported() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(AvatarUserDummy::class); $backend->expects($this->never()) @@ -201,7 +204,7 @@ public function testChangeAvatarNotSupported() { public function testDelete() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) @@ -214,7 +217,7 @@ public function testDelete() { public function testDeleteWithDifferentHome() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -246,7 +249,7 @@ public function testDeleteWithDifferentHome() { public function testGetHome() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) @@ -277,7 +280,7 @@ public function testGetBackendClassName() { public function testGetHomeNotSupported() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->never()) @@ -298,13 +301,13 @@ public function testGetHomeNotSupported() { ->with($this->equalTo('datadirectory')) ->will($this->returnValue('arbitrary/path')); - $user = new User('foo', $backend, $this->dispatcher, null, $allConfig); + $user = new User('foo', $backend, $this->dispatcher, $allConfig); $this->assertEquals('arbitrary/path/foo', $user->getHome()); } public function testCanChangePassword() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -324,7 +327,7 @@ public function testCanChangePassword() { public function testCanChangePasswordNotSupported() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -338,7 +341,7 @@ public function testCanChangePasswordNotSupported() { public function testCanChangeDisplayName() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -358,7 +361,7 @@ public function testCanChangeDisplayName() { public function testCanChangeDisplayNameNotSupported() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -372,7 +375,7 @@ public function testCanChangeDisplayNameNotSupported() { public function testSetDisplayNameSupported() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\OC\User\Database::class); @@ -401,7 +404,7 @@ public function testSetDisplayNameSupported() { */ public function testSetDisplayNameEmpty() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\OC\User\Database::class); @@ -422,7 +425,7 @@ public function testSetDisplayNameEmpty() { public function testSetDisplayNameNotSupported() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\OC\User\Database::class); @@ -438,88 +441,70 @@ public function testSetDisplayNameNotSupported() { $this->assertEquals('foo',$user->getDisplayName()); } - public function testSetPasswordHooks() { - $hooksCalled = 0; - $test = $this; - + public function testSetPasswordEvents() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var Backend|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) ->method('setPassword'); - /** - * @param User $user - * @param string $password - */ - $hook = function ($user, $password) use ($test, &$hooksCalled) { - $hooksCalled++; - $test->assertEquals('foo', $user->getUID()); - $test->assertEquals('bar', $password); - }; - - $emitter = new PublicEmitter(); - $emitter->listen('\OC\User', 'preSetPassword', $hook); - $emitter->listen('\OC\User', 'postSetPassword', $hook); - $backend->expects($this->any()) ->method('implementsActions') ->will($this->returnCallback(function ($actions) { - if ($actions === \OC\User\Backend::SET_PASSWORD) { - return true; - } else { - return false; - } + return $actions === \OC\User\Backend::SET_PASSWORD; })); - - $user = new User('foo', $backend, $this->dispatcher, $emitter); + $user = new User('foo', $backend, $this->dispatcher); + $expectedEvent1 = new BeforePasswordUpdatedEvent($user, 'bar'); + $this->dispatcher->expects($this->at(0)) + ->method('dispatchTyped') + ->with($this->equalTo($expectedEvent1)); + $expectedEvent2 = new PasswordUpdatedEvent($user, 'bar', ''); + $this->dispatcher->expects($this->at(1)) + ->method('dispatchTyped') + ->with($this->equalTo($expectedEvent2)); $user->setPassword('bar',''); - $this->assertEquals(2, $hooksCalled); } public function dataDeleteHooks() { return [ - [true, 2], - [false, 1], + [true, true], + [false, false], ]; } /** * @dataProvider dataDeleteHooks + * * @param bool $result - * @param int $expectedHooks + * @param bool $expectDeletedEvent */ - public function testDeleteHooks($result, $expectedHooks) { - $hooksCalled = 0; - $test = $this; - + public function testDeleteEvents(bool $result, bool $expectDeletedEvent) { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var Backend|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) ->method('deleteUser') ->willReturn($result); - $emitter = new PublicEmitter(); - $user = new User('foo', $backend, $this->dispatcher, $emitter); - - /** - * @param User $user - */ - $hook = function ($user) use ($test, &$hooksCalled) { - $hooksCalled++; - $test->assertEquals('foo', $user->getUID()); - }; - - $emitter->listen('\OC\User', 'preDelete', $hook); - $emitter->listen('\OC\User', 'postDelete', $hook); - $config = $this->createMock(IConfig::class); $commentsManager = $this->createMock(ICommentsManager::class); $notificationManager = $this->createMock(INotificationManager::class); + $user = new User('foo', $backend, $this->dispatcher); + $this->dispatcher->expects($this->at(0)) + ->method('dispatchTyped') + ->with($this->equalTo(new BeforeUserDeletedEvent($user))); + if ($expectDeletedEvent) { + $this->dispatcher->expects($this->at(1)) + ->method('dispatchTyped') + ->with($this->equalTo(new UserDeletedEvent($user))); + } else { + $this->dispatcher->expects($this->atMost(1)) + ->method('dispatchTyped'); + } + if ($result) { $config->expects($this->once()) ->method('deleteAllUserValues') @@ -567,14 +552,10 @@ public function testDeleteHooks($result, $expectedHooks) { $this->restoreService('AllConfig'); $this->restoreService('CommentsManager'); $this->restoreService('NotificationManager'); - - $this->assertEquals($expectedHooks, $hooksCalled); } public function testGetCloudId() { - /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $urlGenerator = $this->getMockBuilder('\OC\URLGenerator') ->setMethods(['getAbsoluteURL']) @@ -584,33 +565,14 @@ public function testGetCloudId() { ->method('getAbsoluteURL') ->withAnyParameters() ->willReturn('http://localhost:8888/owncloud'); - $user = new User('foo', $backend, $this->dispatcher, null, null, $urlGenerator); + $user = new User('foo', $backend, $this->dispatcher, null, $urlGenerator); $this->assertEquals('foo@localhost:8888/owncloud', $user->getCloudId()); } public function testSetEMailAddressEmpty() { - /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - $test = $this; - $hooksCalled = 0; - - /** - * @param IUser $user - * @param string $feature - * @param string $value - */ - $hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) { - $hooksCalled++; - $test->assertEquals('eMailAddress', $feature); - $test->assertEquals('', $value); - }; - - $emitter = new PublicEmitter(); - $emitter->listen('\OC\User', 'changeUser', $hook); - $config = $this->createMock(IConfig::class); $config->expects($this->once()) ->method('deleteUserValue') @@ -619,34 +581,18 @@ public function testSetEMailAddressEmpty() { 'settings', 'email' ); + $user = new User('foo', $backend, $this->dispatcher, $config); + $this->dispatcher->expects($this->once()) + ->method('dispatchTyped') + ->with(new UserChangedEvent($user, 'eMailAddress', '')); - $user = new User('foo', $backend, $this->dispatcher, $emitter, $config); $user->setEMailAddress(''); } public function testSetEMailAddress() { - /** - * @var UserInterface | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - $test = $this; - $hooksCalled = 0; - - /** - * @param IUser $user - * @param string $feature - * @param string $value - */ - $hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) { - $hooksCalled++; - $test->assertEquals('eMailAddress', $feature); - $test->assertEquals('foo@bar.com', $value); - }; - - $emitter = new PublicEmitter(); - $emitter->listen('\OC\User', 'changeUser', $hook); - $config = $this->createMock(IConfig::class); $config->expects($this->once()) ->method('setUserValue') @@ -656,56 +602,37 @@ public function testSetEMailAddress() { 'email', 'foo@bar.com' ); + $user = new User('foo', $backend, $this->dispatcher, $config); + $this->dispatcher->expects($this->once()) + ->method('dispatchTyped') + ->with(new UserChangedEvent($user, 'eMailAddress', 'foo@bar.com')); - $user = new User('foo', $backend, $this->dispatcher, $emitter, $config); $user->setEMailAddress('foo@bar.com'); } public function testSetEMailAddressNoChange() { /** - * @var UserInterface | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - /** @var PublicEmitter|\PHPUnit_Framework_MockObject_MockObject $emitter */ - $emitter = $this->createMock(PublicEmitter::class); - $emitter->expects($this->never()) - ->method('emit'); - $config = $this->createMock(IConfig::class); $config->expects($this->any()) ->method('getUserValue') ->willReturn('foo@bar.com'); $config->expects($this->never()) ->method('setUserValue'); + $user = new User('foo', $backend, $this->dispatcher, $config); + $this->dispatcher->expects($this->never()) + ->method('dispatchTyped'); - $user = new User('foo', $backend, $this->dispatcher, $emitter, $config); $user->setEMailAddress('foo@bar.com'); } public function testSetQuota() { - /** - * @var UserInterface | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - $test = $this; - $hooksCalled = 0; - - /** - * @param IUser $user - * @param string $feature - * @param string $value - */ - $hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) { - $hooksCalled++; - $test->assertEquals('quota', $feature); - $test->assertEquals('23 TB', $value); - }; - - $emitter = new PublicEmitter(); - $emitter->listen('\OC\User', 'changeUser', $hook); - $config = $this->createMock(IConfig::class); $config->expects($this->once()) ->method('setUserValue') @@ -715,37 +642,33 @@ public function testSetQuota() { 'quota', '23 TB' ); + $user = new User('foo', $backend, $this->dispatcher, $config); + $this->dispatcher->expects($this->once()) + ->method('dispatchTyped') + ->with(new UserChangedEvent($user, 'quota', '23 TB')); - $user = new User('foo', $backend, $this->dispatcher, $emitter, $config); $user->setQuota('23 TB'); } public function testSetQuotaAddressNoChange() { - /** - * @var UserInterface | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - /** @var PublicEmitter|\PHPUnit_Framework_MockObject_MockObject $emitter */ - $emitter = $this->createMock(PublicEmitter::class); - $emitter->expects($this->never()) - ->method('emit'); - $config = $this->createMock(IConfig::class); $config->expects($this->any()) ->method('getUserValue') ->willReturn('23 TB'); $config->expects($this->never()) ->method('setUserValue'); + $user = new User('foo', $backend, $this->dispatcher, $config); + $this->dispatcher->expects($this->never()) + ->method('dispatchTyped'); - $user = new User('foo', $backend, $this->dispatcher, $emitter, $config); $user->setQuota('23 TB'); } public function testGetLastLogin() { - /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $config = $this->createMock(IConfig::class); @@ -753,19 +676,17 @@ public function testGetLastLogin() { ->will($this->returnCallback(function ($uid, $app, $key, $default) { if ($uid === 'foo' && $app === 'login' && $key === 'lastLogin') { return 42; - } else { - return $default; } + + return $default; })); - $user = new User('foo', $backend, $this->dispatcher, null, $config); + $user = new User('foo', $backend, $this->dispatcher, $config); $this->assertSame(42, $user->getLastLogin()); } public function testSetEnabled() { - /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $config = $this->createMock(IConfig::class); @@ -778,14 +699,12 @@ public function testSetEnabled() { 'true' ); - $user = new User('foo', $backend, $this->dispatcher, null, $config); + $user = new User('foo', $backend, $this->dispatcher, $config); $user->setEnabled(true); } public function testSetDisabled() { - /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $config = $this->createMock(IConfig::class); @@ -803,7 +722,6 @@ public function testSetDisabled() { 'foo', $backend, $this->dispatcher, - null, $config, ]) ->setMethods(['isEnabled', 'triggerChange']) @@ -824,7 +742,7 @@ public function testSetDisabled() { public function testSetDisabledAlreadyDisabled() { /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend + * @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -837,7 +755,6 @@ public function testSetDisabledAlreadyDisabled() { 'foo', $backend, $this->dispatcher, - null, $config, ]) ->setMethods(['isEnabled', 'triggerChange']) @@ -853,9 +770,7 @@ public function testSetDisabledAlreadyDisabled() { } public function testGetEMailAddress() { - /** - * @var Backend | \PHPUnit_Framework_MockObject_MockObject $backend - */ + /** @var UserInterface|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $config = $this->createMock(IConfig::class); @@ -868,7 +783,7 @@ public function testGetEMailAddress() { } })); - $user = new User('foo', $backend, $this->dispatcher, null, $config); + $user = new User('foo', $backend, $this->dispatcher, $config); $this->assertSame('foo@bar.com', $user->getEMailAddress()); } } From f7731ccc1d38a942f4b87ae9af090e534759c753 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Tue, 10 Dec 2019 18:44:59 +0100 Subject: [PATCH 2/2] fixup! Add typed events for all user hooks and legacy events Signed-off-by: Christoph Wurst --- .../Files/Config/UserMountCacheListener.php | 49 ----------------- .../Files/Listener/UserMountCacheListener.php | 53 +++++++++++++++++++ lib/private/Server.php | 20 +++---- lib/private/User/Manager.php | 12 ++--- tests/lib/Files/Config/UserMountCacheTest.php | 16 +++--- 5 files changed, 75 insertions(+), 75 deletions(-) delete mode 100644 lib/private/Files/Config/UserMountCacheListener.php create mode 100644 lib/private/Files/Listener/UserMountCacheListener.php diff --git a/lib/private/Files/Config/UserMountCacheListener.php b/lib/private/Files/Config/UserMountCacheListener.php deleted file mode 100644 index bacd5728957fe..0000000000000 --- a/lib/private/Files/Config/UserMountCacheListener.php +++ /dev/null @@ -1,49 +0,0 @@ - - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OC\Files\Config; - -use OC\User\Manager; -use OCP\Files\Config\IUserMountCache; - -/** - * Listen to hooks and update the mount cache as needed - */ -class UserMountCacheListener { - /** - * @var IUserMountCache - */ - private $userMountCache; - - /** - * UserMountCacheListener constructor. - * - * @param IUserMountCache $userMountCache - */ - public function __construct(IUserMountCache $userMountCache) { - $this->userMountCache = $userMountCache; - } - - public function listen(Manager $manager) { - $manager->listen('\OC\User', 'postDelete', [$this->userMountCache, 'removeUserMounts']); - } -} diff --git a/lib/private/Files/Listener/UserMountCacheListener.php b/lib/private/Files/Listener/UserMountCacheListener.php new file mode 100644 index 0000000000000..636792a14481d --- /dev/null +++ b/lib/private/Files/Listener/UserMountCacheListener.php @@ -0,0 +1,53 @@ + + * + * @author 2019 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace OC\Files\Listener; + +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Files\Config\IUserMountCache; +use OCP\User\Events\UserDeletedEvent; + +/** + * Listen to events and update the mount cache as needed + */ +class UserMountCacheListener implements IEventListener { + + /** @var IUserMountCache */ + private $userMountCache; + + public function __construct(IUserMountCache $userMountCache) { + $this->userMountCache = $userMountCache; + } + + public function handle(Event $event): void { + if (!($event instanceof UserDeletedEvent)) { + return; + } + + $this->userMountCache->removeUserMounts($event->getUser()); + } + +} diff --git a/lib/private/Server.php b/lib/private/Server.php index 6ae950802dc9c..42ba82a4c2031 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -80,7 +80,7 @@ use OC\Federation\CloudFederationProviderManager; use OC\Federation\CloudIdManager; use OC\Files\Config\UserMountCache; -use OC\Files\Config\UserMountCacheListener; +use OC\Files\Listener\UserMountCacheListener; use OC\Files\Mount\CacheMountProvider; use OC\Files\Mount\LocalHomeMountProvider; use OC\Files\Mount\ObjectHomeMountProvider; @@ -144,6 +144,7 @@ use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudFederationProviderManager; use OCP\Federation\ICloudIdManager; +use OCP\Files\Config\IUserMountCache; use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorageFactory; use OCP\FullTextSearch\IFullTextSearchManager; @@ -813,13 +814,8 @@ public function __construct($webRoot, \OC\Config $config) { }); $this->registerAlias('DateTimeFormatter', \OCP\IDateTimeFormatter::class); - $this->registerService(\OCP\Files\Config\IUserMountCache::class, function (Server $c) { - $mountCache = new UserMountCache($c->getDatabaseConnection(), $c->getUserManager(), $c->getLogger()); - $listener = new UserMountCacheListener($mountCache); - $listener->listen($c->getUserManager()); - return $mountCache; - }); $this->registerAlias('UserMountCache', \OCP\Files\Config\IUserMountCache::class); + $this->registerAlias(IUserMountCache::class, UserMountCache::class); $this->registerService(\OCP\Files\Config\IMountProviderCollection::class, function (Server $c) { $loader = \OC\Files\Filesystem::getLoader(); @@ -1316,10 +1312,12 @@ public function getCalendarRoomBackendManager() { } private function connectDispatcher() { - $dispatcher = $this->getEventDispatcher(); + $legacyDispatcher = $this->getEventDispatcher(); + /** @var IEventDispatcher $dispatcher */ + $dispatcher = $this->query(IEventDispatcher::class); // Delete avatar on user deletion - $dispatcher->addListener('OCP\IUser::preDelete', function(GenericEvent $e) { + $legacyDispatcher->addListener('OCP\IUser::preDelete', function(GenericEvent $e) { $logger = $this->getLogger(); $manager = $this->getAvatarManager(); /** @var IUser $user */ @@ -1336,7 +1334,7 @@ private function connectDispatcher() { } }); - $dispatcher->addListener('OCP\IUser::changeUser', function (GenericEvent $e) { + $legacyDispatcher->addListener('OCP\IUser::changeUser', function (GenericEvent $e) { $manager = $this->getAvatarManager(); /** @var IUser $user */ $user = $e->getSubject(); @@ -1356,6 +1354,8 @@ private function connectDispatcher() { // no avatar to remove } }); + + $dispatcher->addServiceListener(UserDeletedEvent::class, UserMountCacheListener::class); } /** diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 9e9a8953b8fc6..c97ebbbbfecef 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -45,6 +45,7 @@ use OCP\User\Backend\IGetRealUIDBackend; use OCP\User\Events\BeforeUserCreatedEvent; use OCP\User\Events\UserCreatedEvent; +use OCP\User\Events\UserDeletedEvent; use OCP\UserInterface; /** @@ -70,7 +71,7 @@ class Manager extends PublicEmitter implements IUserManager { private $backends = array(); /** @var User[] $cachedUsers */ - private $cachedUsers = array(); + private $cachedUsers = []; /** @var IConfig */ private $config; @@ -81,12 +82,11 @@ class Manager extends PublicEmitter implements IUserManager { public function __construct(IConfig $config, IEventDispatcher $eventDispatcher) { $this->config = $config; - $cachedUsers = &$this->cachedUsers; - $this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) { - /** @var User $user */ - unset($cachedUsers[$user->getUID()]); - }); $this->eventDispatcher = $eventDispatcher; + + $eventDispatcher->addListener(UserDeletedEvent::class, function(UserDeletedEvent $event) { + unset($this->cachedUsers[$event->getUser()->getUID()]); + }); } /** diff --git a/tests/lib/Files/Config/UserMountCacheTest.php b/tests/lib/Files/Config/UserMountCacheTest.php index 99bd279891094..164c668e208e0 100644 --- a/tests/lib/Files/Config/UserMountCacheTest.php +++ b/tests/lib/Files/Config/UserMountCacheTest.php @@ -9,6 +9,7 @@ namespace Test\Files\Config; use OC\DB\QueryBuilder\Literal; +use OC\Files\Config\UserMountCache; use OC\Files\Mount\MountPoint; use OC\Files\Storage\Storage; use OC\Log; @@ -26,19 +27,14 @@ * @group DB */ class UserMountCacheTest extends TestCase { - /** - * @var IDBConnection - */ + + /** @var IDBConnection */ private $connection; - /** - * @var IUserManager - */ + /** @var IUserManager */ private $userManager; - /** - * @var \OC\Files\Config\UserMountCache - */ + /** @var UserMountCache */ private $cache; private $fileIds = []; @@ -52,7 +48,7 @@ protected function setUp(): void { $userBackend->createUser('u2', ''); $userBackend->createUser('u3', ''); $this->userManager->registerBackend($userBackend); - $this->cache = new \OC\Files\Config\UserMountCache($this->connection, $this->userManager, $this->createMock(Log::class)); + $this->cache = new UserMountCache($this->connection, $this->userManager, $this->createMock(Log::class)); } protected function tearDown(): void {