diff options
author | Roeland Jago Douma <roeland@famdouma.nl> | 2019-04-03 16:00:46 +0200 |
---|---|---|
committer | Roeland Jago Douma <roeland@famdouma.nl> | 2019-05-20 20:50:27 +0200 |
commit | f03eb7ec3c130d19323f7fb4bdb5ba398f1b3e2d (patch) | |
tree | 5af334055b94b3b8119b3f76d974f136d26a0199 /lib | |
parent | ae7f89fd9f2bb87c0254f5fa087d0d9472612644 (diff) | |
download | nextcloud-server-f03eb7ec3c130d19323f7fb4bdb5ba398f1b3e2d.tar.gz nextcloud-server-f03eb7ec3c130d19323f7fb4bdb5ba398f1b3e2d.zip |
Remote wipe support
This allows a user to mark a token for remote wipe.
Clients that support this can then wipe the device properly.
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 5 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 5 | ||||
-rw-r--r-- | lib/private/Authentication/Exceptions/WipeTokenException.php | 41 | ||||
-rw-r--r-- | lib/private/Authentication/Notifications/Notifier.php | 77 | ||||
-rw-r--r-- | lib/private/Authentication/Token/IProvider.php | 3 | ||||
-rw-r--r-- | lib/private/Authentication/Token/IToken.php | 1 | ||||
-rw-r--r-- | lib/private/Authentication/Token/IWipeableToken.php | 29 | ||||
-rw-r--r-- | lib/private/Authentication/Token/Manager.php | 5 | ||||
-rw-r--r-- | lib/private/Authentication/Token/PublicKeyToken.php | 6 | ||||
-rw-r--r-- | lib/private/Authentication/Token/PublicKeyTokenProvider.php | 9 | ||||
-rw-r--r-- | lib/private/Authentication/Token/RemoteWipe.php | 149 |
11 files changed, 329 insertions, 1 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index e8bdc89515d..2e271ca3ddc 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -512,6 +512,7 @@ return array( 'OC\\Authentication\\Exceptions\\PasswordlessTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/PasswordlessTokenException.php', 'OC\\Authentication\\Exceptions\\TwoFactorAuthRequiredException' => $baseDir . '/lib/private/Authentication/Exceptions/TwoFactorAuthRequiredException.php', 'OC\\Authentication\\Exceptions\\UserAlreadyLoggedInException' => $baseDir . '/lib/private/Authentication/Exceptions/UserAlreadyLoggedInException.php', + 'OC\\Authentication\\Exceptions\\WipeTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/WipeTokenException.php', 'OC\\Authentication\\LoginCredentials\\Credentials' => $baseDir . '/lib/private/Authentication/LoginCredentials/Credentials.php', 'OC\\Authentication\\LoginCredentials\\Store' => $baseDir . '/lib/private/Authentication/LoginCredentials/Store.php', 'OC\\Authentication\\Login\\ALoginCommand' => $baseDir . '/lib/private/Authentication/Login/ALoginCommand.php', @@ -530,6 +531,7 @@ return array( 'OC\\Authentication\\Login\\UidLoginCommand' => $baseDir . '/lib/private/Authentication/Login/UidLoginCommand.php', 'OC\\Authentication\\Login\\UpdateLastPasswordConfirmCommand' => $baseDir . '/lib/private/Authentication/Login/UpdateLastPasswordConfirmCommand.php', 'OC\\Authentication\\Login\\UserDisabledCheckCommand' => $baseDir . '/lib/private/Authentication/Login/UserDisabledCheckCommand.php', + 'OC\\Authentication\\Notifications\\Notifier' => $baseDir . '/lib/private/Authentication/Notifications/Notifier.php', 'OC\\Authentication\\Token\\DefaultToken' => $baseDir . '/lib/private/Authentication/Token/DefaultToken.php', 'OC\\Authentication\\Token\\DefaultTokenCleanupJob' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenCleanupJob.php', 'OC\\Authentication\\Token\\DefaultTokenMapper' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenMapper.php', @@ -537,10 +539,12 @@ return array( 'OC\\Authentication\\Token\\INamedToken' => $baseDir . '/lib/private/Authentication/Token/INamedToken.php', 'OC\\Authentication\\Token\\IProvider' => $baseDir . '/lib/private/Authentication/Token/IProvider.php', 'OC\\Authentication\\Token\\IToken' => $baseDir . '/lib/private/Authentication/Token/IToken.php', + 'OC\\Authentication\\Token\\IWipeableToken' => $baseDir . '/lib/private/Authentication/Token/IWipeableToken.php', 'OC\\Authentication\\Token\\Manager' => $baseDir . '/lib/private/Authentication/Token/Manager.php', 'OC\\Authentication\\Token\\PublicKeyToken' => $baseDir . '/lib/private/Authentication/Token/PublicKeyToken.php', 'OC\\Authentication\\Token\\PublicKeyTokenMapper' => $baseDir . '/lib/private/Authentication/Token/PublicKeyTokenMapper.php', 'OC\\Authentication\\Token\\PublicKeyTokenProvider' => $baseDir . '/lib/private/Authentication/Token/PublicKeyTokenProvider.php', + 'OC\\Authentication\\Token\\RemoteWipe' => $baseDir . '/lib/private/Authentication/Token/RemoteWipe.php', 'OC\\Authentication\\TwoFactorAuth\\Db\\ProviderUserAssignmentDao' => $baseDir . '/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php', 'OC\\Authentication\\TwoFactorAuth\\EnforcementState' => $baseDir . '/lib/private/Authentication/TwoFactorAuth/EnforcementState.php', 'OC\\Authentication\\TwoFactorAuth\\Manager' => $baseDir . '/lib/private/Authentication/TwoFactorAuth/Manager.php', @@ -711,6 +715,7 @@ return array( 'OC\\Core\\Controller\\UserController' => $baseDir . '/core/Controller/UserController.php', 'OC\\Core\\Controller\\WalledGardenController' => $baseDir . '/core/Controller/WalledGardenController.php', 'OC\\Core\\Controller\\WhatsNewController' => $baseDir . '/core/Controller/WhatsNewController.php', + 'OC\\Core\\Controller\\WipeController' => $baseDir . '/core/Controller/WipeController.php', 'OC\\Core\\Data\\LoginFlowV2Credentials' => $baseDir . '/core/Data/LoginFlowV2Credentials.php', 'OC\\Core\\Data\\LoginFlowV2Tokens' => $baseDir . '/core/Data/LoginFlowV2Tokens.php', 'OC\\Core\\Db\\LoginFlowV2' => $baseDir . '/core/Db/LoginFlowV2.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index d5dccfc1028..cb9e152a770 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -542,6 +542,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Authentication\\Exceptions\\PasswordlessTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/PasswordlessTokenException.php', 'OC\\Authentication\\Exceptions\\TwoFactorAuthRequiredException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/TwoFactorAuthRequiredException.php', 'OC\\Authentication\\Exceptions\\UserAlreadyLoggedInException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/UserAlreadyLoggedInException.php', + 'OC\\Authentication\\Exceptions\\WipeTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/WipeTokenException.php', 'OC\\Authentication\\LoginCredentials\\Credentials' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Credentials.php', 'OC\\Authentication\\LoginCredentials\\Store' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Store.php', 'OC\\Authentication\\Login\\ALoginCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/ALoginCommand.php', @@ -560,6 +561,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Authentication\\Login\\UidLoginCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/UidLoginCommand.php', 'OC\\Authentication\\Login\\UpdateLastPasswordConfirmCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/UpdateLastPasswordConfirmCommand.php', 'OC\\Authentication\\Login\\UserDisabledCheckCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/UserDisabledCheckCommand.php', + 'OC\\Authentication\\Notifications\\Notifier' => __DIR__ . '/../../..' . '/lib/private/Authentication/Notifications/Notifier.php', 'OC\\Authentication\\Token\\DefaultToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultToken.php', 'OC\\Authentication\\Token\\DefaultTokenCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenCleanupJob.php', 'OC\\Authentication\\Token\\DefaultTokenMapper' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenMapper.php', @@ -567,10 +569,12 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Authentication\\Token\\INamedToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/INamedToken.php', 'OC\\Authentication\\Token\\IProvider' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/IProvider.php', 'OC\\Authentication\\Token\\IToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/IToken.php', + 'OC\\Authentication\\Token\\IWipeableToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/IWipeableToken.php', 'OC\\Authentication\\Token\\Manager' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/Manager.php', 'OC\\Authentication\\Token\\PublicKeyToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/PublicKeyToken.php', 'OC\\Authentication\\Token\\PublicKeyTokenMapper' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/PublicKeyTokenMapper.php', 'OC\\Authentication\\Token\\PublicKeyTokenProvider' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/PublicKeyTokenProvider.php', + 'OC\\Authentication\\Token\\RemoteWipe' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/RemoteWipe.php', 'OC\\Authentication\\TwoFactorAuth\\Db\\ProviderUserAssignmentDao' => __DIR__ . '/../../..' . '/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php', 'OC\\Authentication\\TwoFactorAuth\\EnforcementState' => __DIR__ . '/../../..' . '/lib/private/Authentication/TwoFactorAuth/EnforcementState.php', 'OC\\Authentication\\TwoFactorAuth\\Manager' => __DIR__ . '/../../..' . '/lib/private/Authentication/TwoFactorAuth/Manager.php', @@ -741,6 +745,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Core\\Controller\\UserController' => __DIR__ . '/../../..' . '/core/Controller/UserController.php', 'OC\\Core\\Controller\\WalledGardenController' => __DIR__ . '/../../..' . '/core/Controller/WalledGardenController.php', 'OC\\Core\\Controller\\WhatsNewController' => __DIR__ . '/../../..' . '/core/Controller/WhatsNewController.php', + 'OC\\Core\\Controller\\WipeController' => __DIR__ . '/../../..' . '/core/Controller/WipeController.php', 'OC\\Core\\Data\\LoginFlowV2Credentials' => __DIR__ . '/../../..' . '/core/Data/LoginFlowV2Credentials.php', 'OC\\Core\\Data\\LoginFlowV2Tokens' => __DIR__ . '/../../..' . '/core/Data/LoginFlowV2Tokens.php', 'OC\\Core\\Db\\LoginFlowV2' => __DIR__ . '/../../..' . '/core/Db/LoginFlowV2.php', diff --git a/lib/private/Authentication/Exceptions/WipeTokenException.php b/lib/private/Authentication/Exceptions/WipeTokenException.php new file mode 100644 index 00000000000..c56059fd7b9 --- /dev/null +++ b/lib/private/Authentication/Exceptions/WipeTokenException.php @@ -0,0 +1,41 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @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 <http://www.gnu.org/licenses/>. + * + */ +namespace OC\Authentication\Exceptions; + +use OC\Authentication\Token\IToken; + +class WipeTokenException extends InvalidTokenException { + /** @var IToken */ + private $token; + + public function __construct(IToken $token) { + parent::__construct(); + + $this->token = $token; + } + + public function getToken(): IToken { + return $this->token; + } +} diff --git a/lib/private/Authentication/Notifications/Notifier.php b/lib/private/Authentication/Notifications/Notifier.php new file mode 100644 index 00000000000..0aafc115b22 --- /dev/null +++ b/lib/private/Authentication/Notifications/Notifier.php @@ -0,0 +1,77 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @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 <http://www.gnu.org/licenses/>. + */ + +namespace OC\Authentication\Notifications; + +use InvalidArgumentException; +use OCP\L10N\IFactory as IL10nFactory; +use OCP\Notification\INotification; +use OCP\Notification\INotifier; + +class Notifier implements INotifier { + + /** @var IL10nFactory */ + private $factory; + + public function __construct(IL10nFactory $l10nFactory) { + $this->factory = $l10nFactory; + } + + /** + * @inheritDoc + */ + public function prepare(INotification $notification, $languageCode) { + if ($notification->getApp() !== 'auth') { + // Not my app => throw + throw new InvalidArgumentException(); + } + + // Read the language from the notification + $l = $this->factory->get('lib', $languageCode); + + switch ($notification->getSubject()) { + case 'remote_wipe_start': + $notification->setParsedSubject( + $l->t('Remote wipe started') + )->setParsedMessage( + $l->t('A remote wipe was started on device %s', $notification->getSubjectParameters()) + ); + + return $notification; + case 'remote_wipe_finish': + $notification->setParsedSubject( + $l->t('Remote wipe finished') + )->setParsedMessage( + $l->t('The remote wipe on %s has finished', $notification->getSubjectParameters()) + ); + + return $notification; + default: + // Unknown subject => Unknown notification => throw + throw new InvalidArgumentException(); + } + } + +} diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index 21223cecdf7..e4403196583 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -29,6 +29,7 @@ namespace OC\Authentication\Token; use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; +use OC\Authentication\Exceptions\WipeTokenException; interface IProvider { @@ -59,6 +60,7 @@ interface IProvider { * @param string $tokenId * @throws InvalidTokenException * @throws ExpiredTokenException + * @throws WipeTokenException * @return IToken */ public function getToken(string $tokenId): IToken; @@ -69,6 +71,7 @@ interface IProvider { * @param int $tokenId * @throws InvalidTokenException * @throws ExpiredTokenException + * @throws WipeTokenException * @return IToken */ public function getTokenById(int $tokenId): IToken; diff --git a/lib/private/Authentication/Token/IToken.php b/lib/private/Authentication/Token/IToken.php index e122ec02764..c01cf43fe93 100644 --- a/lib/private/Authentication/Token/IToken.php +++ b/lib/private/Authentication/Token/IToken.php @@ -30,6 +30,7 @@ interface IToken extends JsonSerializable { const TEMPORARY_TOKEN = 0; const PERMANENT_TOKEN = 1; + const WIPE_TOKEN = 2; const DO_NOT_REMEMBER = 0; const REMEMBER = 1; diff --git a/lib/private/Authentication/Token/IWipeableToken.php b/lib/private/Authentication/Token/IWipeableToken.php new file mode 100644 index 00000000000..8d4d3a60781 --- /dev/null +++ b/lib/private/Authentication/Token/IWipeableToken.php @@ -0,0 +1,29 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @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 <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Authentication\Token; + +interface IWipeableToken { + public function wipe(): void; +} diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php index 3174599221d..c49bd1b1e19 100644 --- a/lib/private/Authentication/Token/Manager.php +++ b/lib/private/Authentication/Token/Manager.php @@ -26,6 +26,7 @@ namespace OC\Authentication\Token; use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; +use OC\Authentication\Exceptions\WipeTokenException; class Manager implements IProvider { @@ -113,6 +114,8 @@ class Manager implements IProvider { public function getToken(string $tokenId): IToken { try { return $this->publicKeyTokenProvider->getToken($tokenId); + } catch (WipeTokenException $e) { + throw $e; } catch (ExpiredTokenException $e) { throw $e; } catch(InvalidTokenException $e) { @@ -143,6 +146,8 @@ class Manager implements IProvider { return $this->publicKeyTokenProvider->getTokenById($tokenId); } catch (ExpiredTokenException $e) { throw $e; + } catch (WipeTokenException $e) { + throw $e; } catch (InvalidTokenException $e) { return $this->defaultTokenProvider->getTokenById($tokenId); } diff --git a/lib/private/Authentication/Token/PublicKeyToken.php b/lib/private/Authentication/Token/PublicKeyToken.php index b3d87fea7ea..c575273d7bd 100644 --- a/lib/private/Authentication/Token/PublicKeyToken.php +++ b/lib/private/Authentication/Token/PublicKeyToken.php @@ -44,7 +44,7 @@ use OCP\AppFramework\Db\Entity; * @method void setVersion(int $version) * @method bool getPasswordInvalid() */ -class PublicKeyToken extends Entity implements INamedToken { +class PublicKeyToken extends Entity implements INamedToken, IWipeableToken { const VERSION = 2; @@ -226,4 +226,8 @@ class PublicKeyToken extends Entity implements INamedToken { public function setPasswordInvalid(bool $invalid) { parent::setPasswordInvalid($invalid); } + + public function wipe(): void { + parent::setType(IToken::WIPE_TOKEN); + } } diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php index fa9f11a65ab..6e6d7acf242 100644 --- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php +++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php @@ -26,6 +26,7 @@ namespace OC\Authentication\Token; use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; +use OC\Authentication\Exceptions\WipeTokenException; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; @@ -85,6 +86,10 @@ class PublicKeyTokenProvider implements IProvider { throw new ExpiredTokenException($token); } + if ($token->getType() === IToken::WIPE_TOKEN) { + throw new WipeTokenException($token); + } + return $token; } @@ -99,6 +104,10 @@ class PublicKeyTokenProvider implements IProvider { throw new ExpiredTokenException($token); } + if ($token->getType() === IToken::WIPE_TOKEN) { + throw new WipeTokenException($token); + } + return $token; } diff --git a/lib/private/Authentication/Token/RemoteWipe.php b/lib/private/Authentication/Token/RemoteWipe.php new file mode 100644 index 00000000000..6091d30fc25 --- /dev/null +++ b/lib/private/Authentication/Token/RemoteWipe.php @@ -0,0 +1,149 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @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 <http://www.gnu.org/licenses/>. + */ + +namespace OC\Authentication\Token; + +use BadMethodCallException; +use OC\Authentication\Exceptions\InvalidTokenException; +use OC\Authentication\Exceptions\WipeTokenException; +use OCP\Activity\IManager as IActivityManager; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\ILogger; +use OCP\Notification\IManager as INotificationManager; + +class RemoteWipe { + + /** @var IProvider */ + private $tokenProvider; + + /** @var IActivityManager */ + private $activityManager; + + /** @var INotificationManager */ + private $notificationManager; + + /** @var ITimeFactory */ + private $timeFactory; + + /** @var ILogger */ + private $logger; + + public function __construct(IProvider $tokenProvider, + IActivityManager $activityManager, + INotificationManager $notificationManager, + ITimeFactory $timeFactory, + ILogger $logger) { + $this->tokenProvider = $tokenProvider; + $this->activityManager = $activityManager; + $this->notificationManager = $notificationManager; + $this->timeFactory = $timeFactory; + $this->logger = $logger; + } + + /** + * @param string $token + * + * @return bool whether wiping was started + * @throws InvalidTokenException + * + */ + public function start(string $token): bool { + try { + $this->tokenProvider->getToken($token); + + // We expect a WipedTokenException here. If we reach this point this + // is an ordinary token + return false; + } catch (WipeTokenException $e) { + // Expected -> continue below + } + + $dbToken = $e->getToken(); + + $this->logger->info("user " . $dbToken->getUID() . " started a remote wipe"); + $this->sendNotification('remote_wipe_start', $e->getToken()); + $this->publishActivity('remote_wipe_start', $e->getToken()); + + return true; + } + + /** + * @param string $token + * + * @return bool whether wiping could be finished + * @throws InvalidTokenException + */ + public function finish(string $token): bool { + try { + $this->tokenProvider->getToken($token); + + // We expect a WipedTokenException here. If we reach this point this + // is an ordinary token + return false; + } catch (WipeTokenException $e) { + // Expected -> continue below + } + + $dbToken = $e->getToken(); + + $this->tokenProvider->invalidateToken($token); + + $this->logger->info("user " . $dbToken->getUID() . " finished a remote wipe"); + $this->sendNotification('remote_wipe_finish', $e->getToken()); + $this->publishActivity('remote_wipe_finish', $e->getToken()); + + return true; + } + + private function publishActivity(string $event, IToken $token): void { + $activity = $this->activityManager->generateEvent(); + $activity->setApp('core') + ->setType('security') + ->setAuthor($token->getUID()) + ->setAffectedUser($token->getUID()) + ->setSubject($event, [ + 'name' => $token->getName(), + ]); + try { + $this->activityManager->publish($activity); + } catch (BadMethodCallException $e) { + $this->logger->warning('could not publish activity', ['app' => 'core']); + $this->logger->logException($e, ['app' => 'core']); + } + } + + private function sendNotification(string $event, IToken $token): void { + $notification = $this->notificationManager->createNotification(); + $notification->setApp('auth') + ->setUser($token->getUID()) + ->setDateTime($this->timeFactory->getDateTime()) + ->setObject('token', $token->getId()) + ->setSubject($event, [ + 'name' => $token->getName(), + ]); + $this->notificationManager->notify($notification); + } + +} |