From f24fa2051d7c2866ced8cfe26bf147b3ce031082 Mon Sep 17 00:00:00 2001 From: Daniel Kesselberg Date: Sat, 12 Jan 2019 17:48:27 +0100 Subject: [PATCH] Publish event for app token create/update/delete Signed-off-by: Daniel Kesselberg --- settings/Activity/Provider.php | 13 ++++ .../Controller/AuthSettingsController.php | 62 +++++++++++++++---- .../Controller/AuthSettingsControllerTest.php | 14 +++-- 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/settings/Activity/Provider.php b/settings/Activity/Provider.php index e71a33e0d4..1c5db89ec5 100644 --- a/settings/Activity/Provider.php +++ b/settings/Activity/Provider.php @@ -40,6 +40,9 @@ class Provider implements IProvider { const EMAIL_CHANGED_BY = 'email_changed_by'; const EMAIL_CHANGED_SELF = 'email_changed_self'; const EMAIL_CHANGED = 'email_changed'; + public const APP_TOKEN_CREATED = 'app_token_created'; + public const APP_TOKEN_UPDATED = 'app_token_updated'; + public const APP_TOKEN_DELETED = 'app_token_deleted'; /** @var IFactory */ protected $languageFactory; @@ -107,6 +110,13 @@ class Provider implements IProvider { } else if ($event->getSubject() === self::EMAIL_CHANGED) { $subject = $this->l->t('Your email address was changed by an administrator'); + } else if ($event->getSubject() === self::APP_TOKEN_CREATED) { + $subject = $this->l->t('You created app password "%1$s"', $event->getSubjectParameters()); + } else if ($event->getSubject() === self::APP_TOKEN_UPDATED) { + $subject = $this->l->t('You updated app password "%1$s"', $event->getSubjectParameters()); + } else if ($event->getSubject() === self::APP_TOKEN_DELETED) { + $subject = $this->l->t('You deleted an app token'); + } else { throw new \InvalidArgumentException(); } @@ -131,6 +141,9 @@ class Provider implements IProvider { case self::PASSWORD_RESET: case self::EMAIL_CHANGED_SELF: case self::EMAIL_CHANGED: + case self::APP_TOKEN_CREATED: + case self::APP_TOKEN_UPDATED: + case self::APP_TOKEN_DELETED: return []; case self::PASSWORD_CHANGED_BY: case self::EMAIL_CHANGED_BY: diff --git a/settings/Controller/AuthSettingsController.php b/settings/Controller/AuthSettingsController.php index 06cabd00b0..13b16c3ea7 100644 --- a/settings/Controller/AuthSettingsController.php +++ b/settings/Controller/AuthSettingsController.php @@ -27,16 +27,19 @@ namespace OC\Settings\Controller; +use BadMethodCallException; use OC\AppFramework\Http; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IToken; +use OC\Settings\Activity\Provider; +use OCP\Activity\IManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; +use OCP\ILogger; use OCP\IRequest; use OCP\ISession; -use OCP\IUserManager; use OCP\Security\ISecureRandom; use OCP\Session\Exceptions\SessionNotAvailableException; @@ -45,9 +48,6 @@ class AuthSettingsController extends Controller { /** @var IProvider */ private $tokenProvider; - /** @var IUserManager */ - private $userManager; - /** @var ISession */ private $session; @@ -57,23 +57,37 @@ class AuthSettingsController extends Controller { /** @var ISecureRandom */ private $random; + /** @var IManager */ + private $activityManager; + + /** @var ILogger */ + private $logger; + /** * @param string $appName * @param IRequest $request * @param IProvider $tokenProvider - * @param IUserManager $userManager * @param ISession $session * @param ISecureRandom $random - * @param string $userId + * @param string|null $userId + * @param IManager $activityManager + * @param ILogger $logger */ - public function __construct($appName, IRequest $request, IProvider $tokenProvider, IUserManager $userManager, - ISession $session, ISecureRandom $random, $userId) { + public function __construct(string $appName, + IRequest $request, + IProvider $tokenProvider, + ISession $session, + ISecureRandom $random, + ?string $userId, + IManager $activityManager, + ILogger $logger) { parent::__construct($appName, $request); $this->tokenProvider = $tokenProvider; - $this->userManager = $userManager; $this->uid = $userId; $this->session = $session; $this->random = $random; + $this->activityManager = $activityManager; + $this->logger = $logger; } /** @@ -84,7 +98,7 @@ class AuthSettingsController extends Controller { */ public function index() { $tokens = $this->tokenProvider->getTokenByUser($this->uid); - + try { $sessionId = $this->session->getId(); } catch (SessionNotAvailableException $ex) { @@ -96,7 +110,7 @@ class AuthSettingsController extends Controller { return $this->getServiceNotAvailableResponse(); } - return array_map(function(IToken $token) use ($sessionToken) { + return array_map(function (IToken $token) use ($sessionToken) { $data = $token->jsonSerialize(); if ($sessionToken->getId() === $token->getId()) { $data['canDelete'] = false; @@ -140,6 +154,8 @@ class AuthSettingsController extends Controller { $tokenData = $deviceToken->jsonSerialize(); $tokenData['canDelete'] = true; + $this->publishActivity(Provider::APP_TOKEN_CREATED, $deviceToken->getId(), $name); + return new JSONResponse([ 'token' => $token, 'loginName' => $loginName, @@ -179,6 +195,7 @@ class AuthSettingsController extends Controller { */ public function destroy($id) { $this->tokenProvider->invalidateTokenById($this->uid, $id); + $this->publishActivity(Provider::APP_TOKEN_DELETED, $id); return []; } @@ -204,6 +221,29 @@ class AuthSettingsController extends Controller { 'filesystem' => $scope['filesystem'] ]); $this->tokenProvider->updateToken($token); + $this->publishActivity(Provider::APP_TOKEN_UPDATED, $id, $token->getName()); return []; } + + /** + * @param string $subject + * @param int $id + * @param string|null $tokenName + */ + private function publishActivity(string $subject, int $id, ?string $tokenName = null): void { + $event = $this->activityManager->generateEvent(); + $event->setApp('settings') + ->setType('security') + ->setAffectedUser($this->uid) + ->setAuthor($this->uid) + ->setSubject($subject, [$tokenName]) + ->setObject('app_token', $id, 'App Password'); + + try { + $this->activityManager->publish($event); + } catch (BadMethodCallException $e) { + $this->logger->warning('could not publish activity'); + $this->logger->logException($e); + } + } } diff --git a/tests/Settings/Controller/AuthSettingsControllerTest.php b/tests/Settings/Controller/AuthSettingsControllerTest.php index 1c957299e3..19344a2305 100644 --- a/tests/Settings/Controller/AuthSettingsControllerTest.php +++ b/tests/Settings/Controller/AuthSettingsControllerTest.php @@ -28,11 +28,13 @@ use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IToken; use OC\Settings\Controller\AuthSettingsController; +use OCP\Activity\IEvent; +use OCP\Activity\IManager; use OCP\AppFramework\Http\JSONResponse; +use OCP\ILogger; use OCP\IRequest; use OCP\ISession; use OCP\IUser; -use OCP\IUserManager; use OCP\Security\ISecureRandom; use OCP\Session\Exceptions\SessionNotAvailableException; use Test\TestCase; @@ -44,7 +46,6 @@ class AuthSettingsControllerTest extends TestCase { private $request; /** @var IProvider|\PHPUnit_Framework_MockObject_MockObject */ private $tokenProvider; - private $userManager; private $session; private $secureRandom; private $uid; @@ -54,13 +55,16 @@ class AuthSettingsControllerTest extends TestCase { $this->request = $this->createMock(IRequest::class); $this->tokenProvider = $this->createMock(IProvider::class); - $this->userManager = $this->createMock(IUserManager::class); $this->session = $this->createMock(ISession::class); $this->secureRandom = $this->createMock(ISecureRandom::class); $this->uid = 'jane'; - $this->user = $this->createMock(IUser::class); - $this->controller = new AuthSettingsController('core', $this->request, $this->tokenProvider, $this->userManager, $this->session, $this->secureRandom, $this->uid); + $activityManager = $this->createMock(IManager::class); + $activityManager->method('generateEvent') + ->willReturn($this->createMock(IEvent::class)); + $logger = $this->createMock(ILogger::class); + + $this->controller = new AuthSettingsController('core', $this->request, $this->tokenProvider, $this->session, $this->secureRandom, $this->uid, $activityManager, $logger); } public function testIndex() {