From f8808e260dacfd8214e405d493365f4ecaf4d953 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Tue, 9 Feb 2021 11:51:09 +0100 Subject: [PATCH] Move app_password_created to a typed event Signed-off-by: Christoph Wurst --- .../composer/composer/autoload_classmap.php | 1 + .../composer/composer/autoload_static.php | 1 + apps/settings/lib/AppInfo/Application.php | 37 ++-------- .../AppPasswordCreatedActivityListener.php | 73 +++++++++++++++++++ core/Controller/AppPasswordController.php | 13 ++-- core/Controller/ClientFlowLoginController.php | 15 ++-- lib/composer/composer/autoload_classmap.php | 1 + lib/composer/composer/autoload_static.php | 1 + .../Events/AppPasswordCreatedEvent.php | 43 +++++++++++ 9 files changed, 140 insertions(+), 45 deletions(-) create mode 100644 apps/settings/lib/Listener/AppPasswordCreatedActivityListener.php create mode 100644 lib/private/Authentication/Events/AppPasswordCreatedEvent.php diff --git a/apps/settings/composer/composer/autoload_classmap.php b/apps/settings/composer/composer/autoload_classmap.php index bf15d877fe..a6f2d2e568 100644 --- a/apps/settings/composer/composer/autoload_classmap.php +++ b/apps/settings/composer/composer/autoload_classmap.php @@ -32,6 +32,7 @@ return array( 'OCA\\Settings\\Controller\\WebAuthnController' => $baseDir . '/../lib/Controller/WebAuthnController.php', 'OCA\\Settings\\Events\\BeforeTemplateRenderedEvent' => $baseDir . '/../lib/Events/BeforeTemplateRenderedEvent.php', 'OCA\\Settings\\Hooks' => $baseDir . '/../lib/Hooks.php', + 'OCA\\Settings\\Listener\\AppPasswordCreatedActivityListener' => $baseDir . '/../lib/Listener/AppPasswordCreatedActivityListener.php', 'OCA\\Settings\\Mailer\\NewUserMailHelper' => $baseDir . '/../lib/Mailer/NewUserMailHelper.php', 'OCA\\Settings\\Middleware\\SubadminMiddleware' => $baseDir . '/../lib/Middleware/SubadminMiddleware.php', 'OCA\\Settings\\Search\\AppSearch' => $baseDir . '/../lib/Search/AppSearch.php', diff --git a/apps/settings/composer/composer/autoload_static.php b/apps/settings/composer/composer/autoload_static.php index 87635f6358..096e6a2d5b 100644 --- a/apps/settings/composer/composer/autoload_static.php +++ b/apps/settings/composer/composer/autoload_static.php @@ -47,6 +47,7 @@ class ComposerStaticInitSettings 'OCA\\Settings\\Controller\\WebAuthnController' => __DIR__ . '/..' . '/../lib/Controller/WebAuthnController.php', 'OCA\\Settings\\Events\\BeforeTemplateRenderedEvent' => __DIR__ . '/..' . '/../lib/Events/BeforeTemplateRenderedEvent.php', 'OCA\\Settings\\Hooks' => __DIR__ . '/..' . '/../lib/Hooks.php', + 'OCA\\Settings\\Listener\\AppPasswordCreatedActivityListener' => __DIR__ . '/..' . '/../lib/Listener/AppPasswordCreatedActivityListener.php', 'OCA\\Settings\\Mailer\\NewUserMailHelper' => __DIR__ . '/..' . '/../lib/Mailer/NewUserMailHelper.php', 'OCA\\Settings\\Middleware\\SubadminMiddleware' => __DIR__ . '/..' . '/../lib/Middleware/SubadminMiddleware.php', 'OCA\\Settings\\Search\\AppSearch' => __DIR__ . '/..' . '/../lib/Search/AppSearch.php', diff --git a/apps/settings/lib/AppInfo/Application.php b/apps/settings/lib/AppInfo/Application.php index 8240b31055..7fa3f8f347 100644 --- a/apps/settings/lib/AppInfo/Application.php +++ b/apps/settings/lib/AppInfo/Application.php @@ -35,19 +35,17 @@ declare(strict_types=1); namespace OCA\Settings\AppInfo; -use BadMethodCallException; use OC\AppFramework\Utility\TimeFactory; +use OC\Authentication\Events\AppPasswordCreatedEvent; use OC\Authentication\Token\IProvider; -use OC\Authentication\Token\IToken; use OC\Group\Manager; use OC\Server; -use OCA\Settings\Activity\Provider; use OCA\Settings\Hooks; +use OCA\Settings\Listener\AppPasswordCreatedActivityListener; use OCA\Settings\Mailer\NewUserMailHelper; use OCA\Settings\Middleware\SubadminMiddleware; use OCA\Settings\Search\AppSearch; use OCA\Settings\Search\SectionSearch; -use OCP\Activity\IManager as IActivityManager; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; @@ -56,13 +54,10 @@ use OCP\AppFramework\IAppContainer; use OCP\Defaults; use OCP\IGroup; use OCP\IGroupManager; -use OCP\ILogger; use OCP\IServerContainer; use OCP\IUser; use OCP\Settings\IManager; use OCP\Util; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; class Application extends App implements IBootstrap { public const APP_ID = 'settings'; @@ -81,6 +76,9 @@ class Application extends App implements IBootstrap { $context->registerSearchProvider(SectionSearch::class); $context->registerSearchProvider(AppSearch::class); + // Register listeners + $context->registerEventListener(AppPasswordCreatedEvent::class, AppPasswordCreatedActivityListener::class); + /** * Core class wrappers */ @@ -129,31 +127,6 @@ class Application extends App implements IBootstrap { } public function boot(IBootContext $context): void { - $context->injectFn(function (EventDispatcherInterface $dispatcher, IAppContainer $appContainer) { - $dispatcher->addListener('app_password_created', function (GenericEvent $event) use ($appContainer) { - if (($token = $event->getSubject()) instanceof IToken) { - /** @var IActivityManager $activityManager */ - $activityManager = $appContainer->get(IActivityManager::class); - /** @var ILogger $logger */ - $logger = $appContainer->get(ILogger::class); - - $activity = $activityManager->generateEvent(); - $activity->setApp('settings') - ->setType('security') - ->setAffectedUser($token->getUID()) - ->setAuthor($token->getUID()) - ->setSubject(Provider::APP_TOKEN_CREATED, ['name' => $token->getName()]) - ->setObject('app_token', $token->getId()); - - try { - $activityManager->publish($activity); - } catch (BadMethodCallException $e) { - $logger->logException($e, ['message' => 'could not publish activity', 'level' => ILogger::WARN]); - } - } - }); - }); - Util::connectHook('OC_User', 'post_setPassword', $this, 'onChangePassword'); Util::connectHook('OC_User', 'changeUser', $this, 'onChangeInfo'); diff --git a/apps/settings/lib/Listener/AppPasswordCreatedActivityListener.php b/apps/settings/lib/Listener/AppPasswordCreatedActivityListener.php new file mode 100644 index 0000000000..83aa67642a --- /dev/null +++ b/apps/settings/lib/Listener/AppPasswordCreatedActivityListener.php @@ -0,0 +1,73 @@ + + * + * @author 2021 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 OCA\Settings\Listener; + +use BadMethodCallException; +use OC\Authentication\Events\AppPasswordCreatedEvent; +use OCA\Settings\Activity\Provider; +use OCP\Activity\IManager as IActivityManager; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use Psr\Log\LoggerInterface; + +/** + * @template-implements IEventListener<\OC\Authentication\Events\AppPasswordCreatedEvent> + */ +class AppPasswordCreatedActivityListener implements IEventListener { + /** @var IActivityManager */ + private $activityManager; + + /** @var LoggerInterface */ + private $logger; + + public function __construct(IActivityManager $activityManager, + LoggerInterface $logger) { + $this->activityManager = $activityManager; + $this->logger = $logger; + } + + public function handle(Event $event): void { + if (!($event instanceof AppPasswordCreatedEvent)) { + return; + } + + $activity = $this->activityManager->generateEvent(); + $activity->setApp('settings') + ->setType('security') + ->setAffectedUser($event->getToken()->getUID()) + ->setAuthor($event->getToken()->getUID()) + ->setSubject(Provider::APP_TOKEN_CREATED, ['name' => $event->getToken()->getName()]) + ->setObject('app_token', $event->getToken()->getId()); + + try { + $this->activityManager->publish($activity); + } catch (BadMethodCallException $e) { + $this->logger->warning('Could not publish activity: ' . $e->getMessage(), [ + 'exception' => $e + ]); + } + } +} diff --git a/core/Controller/AppPasswordController.php b/core/Controller/AppPasswordController.php index 2f8c1184de..15f86b4ad6 100644 --- a/core/Controller/AppPasswordController.php +++ b/core/Controller/AppPasswordController.php @@ -27,6 +27,7 @@ declare(strict_types=1); namespace OC\Core\Controller; +use OC\Authentication\Events\AppPasswordCreatedEvent; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IToken; @@ -35,11 +36,10 @@ use OCP\AppFramework\OCS\OCSForbiddenException; use OCP\Authentication\Exceptions\CredentialsUnavailableException; use OCP\Authentication\Exceptions\PasswordUnavailableException; use OCP\Authentication\LoginCredentials\IStore; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IRequest; use OCP\ISession; use OCP\Security\ISecureRandom; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; class AppPasswordController extends \OCP\AppFramework\OCSController { @@ -55,7 +55,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { /** @var IStore */ private $credentialStore; - /** @var EventDispatcherInterface */ + /** @var IEventDispatcher */ private $eventDispatcher; public function __construct(string $appName, @@ -64,7 +64,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { ISecureRandom $random, IProvider $tokenProvider, IStore $credentialStore, - EventDispatcherInterface $eventDispatcher) { + IEventDispatcher $eventDispatcher) { parent::__construct($appName, $request); $this->session = $session; @@ -112,8 +112,9 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { IToken::DO_NOT_REMEMBER ); - $event = new GenericEvent($generatedToken); - $this->eventDispatcher->dispatch('app_password_created', $event); + $this->eventDispatcher->dispatchTyped( + new AppPasswordCreatedEvent($generatedToken) + ); return new DataResponse([ 'apppassword' => $token diff --git a/core/Controller/ClientFlowLoginController.php b/core/Controller/ClientFlowLoginController.php index 9a7296281b..b7599acc3c 100644 --- a/core/Controller/ClientFlowLoginController.php +++ b/core/Controller/ClientFlowLoginController.php @@ -32,6 +32,7 @@ namespace OC\Core\Controller; +use OC\Authentication\Events\AppPasswordCreatedEvent; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Token\IProvider; @@ -44,6 +45,7 @@ use OCP\AppFramework\Http; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\StandaloneTemplateResponse; use OCP\Defaults; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IL10N; use OCP\IRequest; use OCP\ISession; @@ -52,8 +54,6 @@ use OCP\IUserSession; use OCP\Security\ICrypto; use OCP\Security\ISecureRandom; use OCP\Session\Exceptions\SessionNotAvailableException; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; class ClientFlowLoginController extends Controller { /** @var IUserSession */ @@ -76,7 +76,7 @@ class ClientFlowLoginController extends Controller { private $accessTokenMapper; /** @var ICrypto */ private $crypto; - /** @var EventDispatcherInterface */ + /** @var IEventDispatcher */ private $eventDispatcher; public const STATE_NAME = 'client.flow.state.token'; @@ -94,7 +94,7 @@ class ClientFlowLoginController extends Controller { * @param ClientMapper $clientMapper * @param AccessTokenMapper $accessTokenMapper * @param ICrypto $crypto - * @param EventDispatcherInterface $eventDispatcher + * @param IEventDispatcher $eventDispatcher */ public function __construct($appName, IRequest $request, @@ -108,7 +108,7 @@ class ClientFlowLoginController extends Controller { ClientMapper $clientMapper, AccessTokenMapper $accessTokenMapper, ICrypto $crypto, - EventDispatcherInterface $eventDispatcher) { + IEventDispatcher $eventDispatcher) { parent::__construct($appName, $request); $this->userSession = $userSession; $this->l10n = $l10n; @@ -364,8 +364,9 @@ class ClientFlowLoginController extends Controller { $this->tokenProvider->invalidateToken($sessionId); } - $event = new GenericEvent($generatedToken); - $this->eventDispatcher->dispatch('app_password_created', $event); + $this->eventDispatcher->dispatchTyped( + new AppPasswordCreatedEvent($generatedToken) + ); return new Http\RedirectResponse($redirectUri); } diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 49b138714a..ed69bfd959 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -667,6 +667,7 @@ return array( 'OC\\Archive\\TAR' => $baseDir . '/lib/private/Archive/TAR.php', 'OC\\Archive\\ZIP' => $baseDir . '/lib/private/Archive/ZIP.php', 'OC\\Authentication\\Events\\ARemoteWipeEvent' => $baseDir . '/lib/private/Authentication/Events/ARemoteWipeEvent.php', + 'OC\\Authentication\\Events\\AppPasswordCreatedEvent' => $baseDir . '/lib/private/Authentication/Events/AppPasswordCreatedEvent.php', 'OC\\Authentication\\Events\\LoginFailed' => $baseDir . '/lib/private/Authentication/Events/LoginFailed.php', 'OC\\Authentication\\Events\\RemoteWipeFinished' => $baseDir . '/lib/private/Authentication/Events/RemoteWipeFinished.php', 'OC\\Authentication\\Events\\RemoteWipeStarted' => $baseDir . '/lib/private/Authentication/Events/RemoteWipeStarted.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 373db9144b..a5ded45e48 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -696,6 +696,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Archive\\TAR' => __DIR__ . '/../../..' . '/lib/private/Archive/TAR.php', 'OC\\Archive\\ZIP' => __DIR__ . '/../../..' . '/lib/private/Archive/ZIP.php', 'OC\\Authentication\\Events\\ARemoteWipeEvent' => __DIR__ . '/../../..' . '/lib/private/Authentication/Events/ARemoteWipeEvent.php', + 'OC\\Authentication\\Events\\AppPasswordCreatedEvent' => __DIR__ . '/../../..' . '/lib/private/Authentication/Events/AppPasswordCreatedEvent.php', 'OC\\Authentication\\Events\\LoginFailed' => __DIR__ . '/../../..' . '/lib/private/Authentication/Events/LoginFailed.php', 'OC\\Authentication\\Events\\RemoteWipeFinished' => __DIR__ . '/../../..' . '/lib/private/Authentication/Events/RemoteWipeFinished.php', 'OC\\Authentication\\Events\\RemoteWipeStarted' => __DIR__ . '/../../..' . '/lib/private/Authentication/Events/RemoteWipeStarted.php', diff --git a/lib/private/Authentication/Events/AppPasswordCreatedEvent.php b/lib/private/Authentication/Events/AppPasswordCreatedEvent.php new file mode 100644 index 0000000000..6daa504527 --- /dev/null +++ b/lib/private/Authentication/Events/AppPasswordCreatedEvent.php @@ -0,0 +1,43 @@ + + * + * @author 2021 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\Authentication\Events; + +use OC\Authentication\Token\IToken; +use OCP\EventDispatcher\Event; + +class AppPasswordCreatedEvent extends Event { + /** @var IToken */ + private $token; + + public function __construct(IToken $token) { + parent::__construct(); + $this->token = $token; + } + + public function getToken(): IToken { + return $this->token; + } +}