diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2018-08-22 11:21:36 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2018-08-22 11:21:36 +0300 |
commit | 743c69e9a9dad819445020c96c1b8fc0102a3d6e (patch) | |
tree | 9259008ea7cbe3ea28d0e0d724277f9e2971f308 /lib/Service | |
parent | c15e1e879e9854c5feaae71a8681878a099ed408 (diff) |
Split settings to work with all three gateway types independently
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib/Service')
-rw-r--r-- | lib/Service/Gateway/Factory.php | 64 | ||||
-rw-r--r-- | lib/Service/Gateway/IGateway.php | 8 | ||||
-rw-r--r-- | lib/Service/Gateway/SMS/Gateway.php | 10 | ||||
-rw-r--r-- | lib/Service/Gateway/Signal/Gateway.php | 10 | ||||
-rw-r--r-- | lib/Service/Gateway/Telegram/Gateway.php | 10 | ||||
-rw-r--r-- | lib/Service/Gateway/TestGateway.php | 10 | ||||
-rw-r--r-- | lib/Service/SetupService.php | 35 | ||||
-rw-r--r-- | lib/Service/StateStorage.php | 78 |
8 files changed, 130 insertions, 95 deletions
diff --git a/lib/Service/Gateway/Factory.php b/lib/Service/Gateway/Factory.php new file mode 100644 index 0000000..a0dac01 --- /dev/null +++ b/lib/Service/Gateway/Factory.php @@ -0,0 +1,64 @@ +<?php + +declare(strict_types=1); + +/** + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * + * Nextcloud - Two-factor Gateway + * + * 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 <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\TwoFactorGateway\Service\Gateway; + +use Exception; +use OCA\TwoFactorGateway\Service\Gateway\Signal\Gateway as SignalGateway; +use OCA\TwoFactorGateway\Service\Gateway\SMS\Gateway as SMSGateway; +use OCA\TwoFactorGateway\Service\Gateway\Telegram\Gateway as TelegramGateway; + +class Factory { + + /** @var SignalGateway */ + private $signalGateway; + + /** @var SMSGateway */ + private $smsGateway; + + /** @var TelegramGateway */ + private $telegramGateway; + + public function __construct(SignalGateway $signalGateway, + SMSGateway $smsGateway, + TelegramGateway $telegramGateway) { + + $this->signalGateway = $signalGateway; + $this->smsGateway = $smsGateway; + $this->telegramGateway = $telegramGateway; + } + + public function getGateway(string $name): IGateway { + switch ($name) { + case 'signal': + return $this->signalGateway; + case 'sms': + return $this->smsGateway; + case 'telegram': + return $this->telegramGateway; + default: + throw new Exception("Invalid gateway <$name>"); + } + } + +} diff --git a/lib/Service/Gateway/IGateway.php b/lib/Service/Gateway/IGateway.php index da467c5..5d0d881 100644 --- a/lib/Service/Gateway/IGateway.php +++ b/lib/Service/Gateway/IGateway.php @@ -29,14 +29,6 @@ use OCP\IUser; interface IGateway { /** - * Get a short description of this gateway's name so that users know how - * their messages are delivered, e.g. "Telegram" - * - * @return string - */ - public function getShortName(): string; - - /** * Get the gateway-specific configuration * * @return IGatewayConfig diff --git a/lib/Service/Gateway/SMS/Gateway.php b/lib/Service/Gateway/SMS/Gateway.php index 53f985d..e91456f 100644 --- a/lib/Service/Gateway/SMS/Gateway.php +++ b/lib/Service/Gateway/SMS/Gateway.php @@ -49,16 +49,6 @@ class Gateway implements IGateway { } /** - * Get a short description of this gateway's name so that users know how - * their messages are delivered, e.g. "Telegram" - * - * @return string - */ - public function getShortName(): string { - return 'SMS'; - } - - /** * Get the gateway-specific configuration * * @return GatewayConfig diff --git a/lib/Service/Gateway/Signal/Gateway.php b/lib/Service/Gateway/Signal/Gateway.php index c3c77f0..02d3f50 100644 --- a/lib/Service/Gateway/Signal/Gateway.php +++ b/lib/Service/Gateway/Signal/Gateway.php @@ -82,16 +82,6 @@ class Gateway implements IGateway { } /** - * Get a short description of this gateway's name so that users know how - * their messages are delivered, e.g. "Telegram" - * - * @return string - */ - public function getShortName(): string { - return 'Signal'; - } - - /** * Get the gateway-specific configuration * * @return IGatewayConfig diff --git a/lib/Service/Gateway/Telegram/Gateway.php b/lib/Service/Gateway/Telegram/Gateway.php index f8295ad..d8b355c 100644 --- a/lib/Service/Gateway/Telegram/Gateway.php +++ b/lib/Service/Gateway/Telegram/Gateway.php @@ -96,16 +96,6 @@ class Gateway implements IGateway { } /** - * Get a short description of this gateway's name so that users know how - * their messages are delivered, e.g. "Telegram" - * - * @return string - */ - public function getShortName(): string { - return 'Telegram'; - } - - /** * Get the gateway-specific configuration * * @return IGatewayConfig diff --git a/lib/Service/Gateway/TestGateway.php b/lib/Service/Gateway/TestGateway.php index 9cf7bb7..7d7f34c 100644 --- a/lib/Service/Gateway/TestGateway.php +++ b/lib/Service/Gateway/TestGateway.php @@ -42,16 +42,6 @@ class TestGateway implements IGateway { } /** - * Get a short description of this gateway's name so that users know how - * their messages are delivered, e.g. "Telegram" - * - * @return string - */ - public function getShortName(): string { - return 'Test'; - } - - /** * @return string */ public function getProviderDescription(): string { diff --git a/lib/Service/SetupService.php b/lib/Service/SetupService.php index 15f5945..a5c7d51 100644 --- a/lib/Service/SetupService.php +++ b/lib/Service/SetupService.php @@ -29,9 +29,9 @@ use OCA\TwoFactorGateway\Exception\IdentifierMissingException; use OCA\TwoFactorGateway\Exception\SmsTransmissionException; use OCA\TwoFactorGateway\Exception\VerificationException; use OCA\TwoFactorGateway\Exception\VerificationTransmissionException; +use OCA\TwoFactorGateway\Service\Gateway\Factory as GatewayFactory; use OCA\TwoFactorGateway\Provider\SmsProvider; use OCA\TwoFactorGateway\Provider\State; -use OCA\TwoFactorGateway\Service\Gateway\IGateway; use OCP\Authentication\TwoFactorAuth\IRegistry; use OCP\IUser; use OCP\Security\ISecureRandom; @@ -41,8 +41,8 @@ class SetupService { /** @var StateStorage */ private $stateStorage; - /** @var IGateway */ - private $smsService; + /** @var GatewayFactory */ + private $gatewayFactory; /** @var ISecureRandom */ private $random; @@ -54,29 +54,29 @@ class SetupService { private $providerRegistry; public function __construct(StateStorage $stateStorage, - IGateway $smsService, + GatewayFactory $gatewayFactory, ISecureRandom $random, SmsProvider $provider, IRegistry $providerRegistry) { $this->stateStorage = $stateStorage; - $this->smsService = $smsService; + $this->gatewayFactory = $gatewayFactory; $this->random = $random; $this->provider = $provider; $this->providerRegistry = $providerRegistry; } - public function getState(IUser $user): State { - return $this->stateStorage->get($user); + public function getState(IUser $user, string $gatewayName): State { + return $this->stateStorage->get($user, $gatewayName); } /** * @throws IdentifierMissingException */ - public function getChallengePhoneNumber(IUser $user): string { - $state = $this->stateStorage->get($user); + public function getChallengePhoneNumber(IUser $user, string $gatewayName): string { + $state = $this->stateStorage->get($user, $gatewayName); $identifier = $state->getIdentifier(); if (is_null($identifier)) { - throw new IdentifierMissingException('verified identifier is missing'); + throw new IdentifierMissingException("verified identifier for $gatewayName is missing"); } return $identifier; @@ -85,21 +85,22 @@ class SetupService { /** * Send out confirmation message and save current identifier in user settings */ - public function startSetup(IUser $user, string $identifier): State { + public function startSetup(IUser $user, string $gatewayName, string $identifier): State { $verificationNumber = $this->random->generate(6, ISecureRandom::CHAR_DIGITS); + $gateway = $this->gatewayFactory->getGateway($gatewayName); try { - $this->smsService->send($user, $identifier, "$verificationNumber is your Nextcloud verification code."); + $gateway->send($user, $identifier, "$verificationNumber is your Nextcloud verification code."); } catch (SmsTransmissionException $ex) { throw new VerificationTransmissionException('could not send verification code'); } return $this->stateStorage->persist( - State::verifying($user, $this->smsService->getShortName(), $identifier, $verificationNumber) + State::verifying($user, $gatewayName, $identifier, $verificationNumber) ); } - public function finishSetup(IUser $user, string $token): State { - $state = $this->stateStorage->get($user); + public function finishSetup(IUser $user, string $gatewayName, string $token): State { + $state = $this->stateStorage->get($user, $gatewayName); if (is_null($state->getVerificationCode())) { throw new Exception('no verification code set'); } @@ -115,11 +116,11 @@ class SetupService { ); } - public function disable(IUser $user): State { + public function disable(IUser $user, string $gatewayName): State { $this->providerRegistry->disableProviderFor($this->provider, $user); return $this->stateStorage->persist( - State::disabled($user) + State::disabled($user, $gatewayName) ); } diff --git a/lib/Service/StateStorage.php b/lib/Service/StateStorage.php index 75e3f0f..10307d5 100644 --- a/lib/Service/StateStorage.php +++ b/lib/Service/StateStorage.php @@ -28,7 +28,6 @@ use Exception; use OCA\TwoFactorGateway\AppInfo\Application; use OCA\TwoFactorGateway\Provider\SmsProvider; use OCA\TwoFactorGateway\Provider\State; -use OCA\TwoFactorGateway\Service\Gateway\IGateway; use OCP\IConfig; use OCP\IUser; @@ -41,10 +40,29 @@ class StateStorage { $this->config = $config; } - public function get(IUser $user): State { - $isVerified = $this->config->getUserValue($user->getUID(), Application::APP_NAME, 'verified', 'false') === 'true'; - $identifier = $this->config->getUserValue($user->getUID(), 'twofactor_gateway', 'identifier', null); - $verificationCode = $this->config->getUserValue($user->getUID(), 'twofactor_gateway', 'verification_code', null); + private function buildConfigKey(string $gatewayName, string $key) { + return "twofactor_gateway_$gatewayName" . "_$key"; + } + + private function getUserValue(IUser $user, string $gatewayName, string $key, $default = '') { + $gatewayKey = $this->buildConfigKey($gatewayName, $key); + return $this->config->getUserValue($user->getUID(), Application::APP_NAME, $gatewayKey, $default); + } + + private function setUserValue(IUser $user, string $gatewayName, string $key, $value) { + $gatewayKey = $this->buildConfigKey($gatewayName, $key); + $this->config->setUserValue($user->getUID(), Application::APP_NAME, $gatewayKey, $value); + } + + private function deleteUserValue(IUser $user, string $gatewayName, string $key) { + $gatewayKey = $this->buildConfigKey($gatewayName, $key); + $this->config->deleteUserValue($user->getUID(), Application::APP_NAME, $gatewayKey); + } + + public function get(IUser $user, string $gatewayName): State { + $isVerified = $this->getUserValue($user, $gatewayName, 'verified', 'false') === 'true'; + $identifier = $this->getUserValue($user, $gatewayName, 'identifier', null); + $verificationCode = $this->getUserValue($user, $gatewayName, 'verification_code', null); if ($isVerified) { $state = SmsProvider::STATE_ENABLED; @@ -57,7 +75,7 @@ class StateStorage { return new State( $user, $state, - '', // TODO: fix + $gatewayName, $identifier, $verificationCode ); @@ -66,55 +84,55 @@ class StateStorage { public function persist(State $state): State { switch ($state->getState()) { case SmsProvider::STATE_DISABLED: - $this->config->deleteUserValue( - $state->getUser()->getUID(), - Application::APP_NAME, + $this->deleteUserValue( + $state->getUser(), + $state->getGatewayName(), 'verified' ); - $this->config->deleteUserValue( - $state->getUser()->getUID(), - Application::APP_NAME, + $this->deleteUserValue( + $state->getUser(), + $state->getGatewayName(), 'verification_code' ); break; case SmsProvider::STATE_VERIFYING: - $this->config->setUserValue( - $state->getUser()->getUID(), - Application::APP_NAME, + $this->setUserValue( + $state->getUser(), + $state->getGatewayName(), 'identifier', $state->getIdentifier() ); - $this->config->setUserValue( - $state->getUser()->getUID(), - Application::APP_NAME, + $this->setUserValue( + $state->getUser(), + $state->getGatewayName(), 'verification_code', $state->getVerificationCode() ); - $this->config->setUserValue( - $state->getUser()->getUID(), - Application::APP_NAME, + $this->setUserValue( + $state->getUser(), + $state->getGatewayName(), 'verified', 'false' ); break; case SmsProvider::STATE_ENABLED: - $this->config->setUserValue( - $state->getUser()->getUID(), - Application::APP_NAME, + $this->setUserValue( + $state->getUser(), + $state->getGatewayName(), 'identifier', $state->getIdentifier() ); - $this->config->setUserValue( - $state->getUser()->getUID(), - Application::APP_NAME, + $this->setUserValue( + $state->getUser(), + $state->getGatewayName(), 'verification_code', $state->getVerificationCode() ); - $this->config->setUserValue( - $state->getUser()->getUID(), - Application::APP_NAME, + $this->setUserValue( + $state->getUser(), + $state->getGatewayName(), 'verified', 'true' ); |