diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2018-08-21 23:52:07 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2018-08-21 23:52:07 +0300 |
commit | 8612cfde1dc43b7bed026735eb056617211d16b1 (patch) | |
tree | 5e19a24f5b4feb2ec21e9132c956e45e33980d66 /lib | |
parent | bd8e9bc6821092d6b6049d43b53f0e1f5512dcca (diff) |
Add a separate provider for each gateway type
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Provider/AProvider.php | 141 | ||||
-rw-r--r-- | lib/Provider/SignalProvider.php | 64 | ||||
-rw-r--r-- | lib/Provider/SmsProvider.php | 106 | ||||
-rw-r--r-- | lib/Provider/TelegramProvider.php | 71 |
4 files changed, 285 insertions, 97 deletions
diff --git a/lib/Provider/AProvider.php b/lib/Provider/AProvider.php new file mode 100644 index 0000000..a69cb75 --- /dev/null +++ b/lib/Provider/AProvider.php @@ -0,0 +1,141 @@ +<?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\Provider; + +use OCA\TwoFactorGateway\Service\Gateway\IGateway; +use OCA\TwoFactorGateway\Service\StateStorage; +use OCP\Authentication\TwoFactorAuth\IProvider; +use OCP\IL10N; +use OCP\ISession; +use OCP\IUser; +use OCP\Security\ISecureRandom; +use OCP\Template; + +abstract class AProvider implements IProvider { + + const STATE_DISABLED = 0; + const STATE_START_VERIFICATION = 1; + const STATE_VERIFYING = 2; + const STATE_ENABLED = 3; + + /** @var string */ + protected $gatewayId; + + /** @var IGateway */ + protected $gateway; + + /** @var StateStorage */ + protected $stateStorage; + + /** @var ISession */ + protected $session; + + /** @var ISecureRandom */ + protected $secureRandom; + + /** @var IL10N */ + protected $l10n; + + private function getSessionKey() { + return "twofactor_gateway_$this->gatewayId_secret"; + } + + public function __construct(string $gatewayId, + IGateway $gateway, + StateStorage $stateStorage, + ISession $session, + ISecureRandom $secureRandom, + IL10N $l10n) { + $this->gateway = $gateway; + $this->gatewayId = $gatewayId; + $this->stateStorage = $stateStorage; + $this->session = $session; + $this->secureRandom = $secureRandom; + $this->l10n = $l10n; + } + + /** + * Get unique identifier of this 2FA provider + */ + public function getId(): string { + return "gateway_$this->gatewayId"; + } + + private function getSecret(): string { + if ($this->session->exists($this->getSessionKey())) { + return $this->session->get($this->getSessionKey()); + } + + $secret = $this->secureRandom->generate(6, ISecureRandom::CHAR_DIGITS); + $this->session->set($this->getSessionKey(), $secret); + + return $secret; + } + + /** + * Get the template for rending the 2FA provider view + */ + public function getTemplate(IUser $user): Template { + $secret = $this->getSecret(); + + try { + $identifier = $this->stateStorage->get($user)->getIdentifier(); + $this->gateway->send( + $user, + $identifier, + $this->l10n->t('%s is your Nextcloud authentication code', [ + $secret + ]) + ); + } catch (SmsTransmissionException $ex) { + return new Template('twofactor_gateway', 'error'); + } + + $tmpl = new Template('twofactor_gateway', 'challenge'); + $tmpl->assign('phone', PhoneNumberMask::maskNumber($identifier)); + return $tmpl; + } + + /** + * Verify the given challenge + */ + public function verifyChallenge(IUser $user, string $challenge): bool { + $valid = $this->session->exists($this->getSessionKey()) + && $this->session->get($this->getSessionKey()) === $challenge; + + if ($valid) { + $this->session->remove($this->getSessionKey()); + } + + return $valid; + } + + /** + * Decides whether 2FA is enabled for the given user + */ + public function isTwoFactorAuthEnabledForUser(IUser $user): bool { + return $this->stateStorage->get($user)->getState() === self::STATE_ENABLED; + } + +} diff --git a/lib/Provider/SignalProvider.php b/lib/Provider/SignalProvider.php new file mode 100644 index 0000000..0e162b4 --- /dev/null +++ b/lib/Provider/SignalProvider.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\Provider; + +use OCA\TwoFactorGateway\Service\Gateway\IGateway; +use OCA\TwoFactorGateway\Service\Gateway\Signal\Gateway; +use OCA\TwoFactorGateway\Service\StateStorage; +use OCP\IL10N; +use OCP\ISession; +use OCP\Security\ISecureRandom; + +class SignalProvider extends AProvider { + + public function __construct(Gateway $smsGateway, + StateStorage $stateStorage, + ISession $session, + ISecureRandom $secureRandom, + IL10N $l10n) { + parent::__construct( + 'signal', + $smsGateway, + $stateStorage, + $session, + $secureRandom, + $l10n + ); + } + + /** + * Get the display name for selecting the 2FA provider + */ + public function getDisplayName(): string { + return $this->l10n->t('Signal verification'); + } + + /** + * Get the description for selecting the 2FA provider + */ + public function getDescription(): string { + return $this->l10n->t('Authenticate via Signal'); + } + +} diff --git a/lib/Provider/SmsProvider.php b/lib/Provider/SmsProvider.php index dea399c..297dac5 100644 --- a/lib/Provider/SmsProvider.php +++ b/lib/Provider/SmsProvider.php @@ -23,64 +23,32 @@ declare(strict_types=1); namespace OCA\TwoFactorGateway\Provider; -use OCA\TwoFactorGateway\Exception\SmsTransmissionException; -use OCA\TwoFactorGateway\PhoneNumberMask; use OCA\TwoFactorGateway\Service\Gateway\IGateway; use OCA\TwoFactorGateway\Service\Gateway\SMS\Gateway; use OCA\TwoFactorGateway\Service\StateStorage; -use OCP\Authentication\TwoFactorAuth\IProvider; use OCP\IL10N; use OCP\ISession; -use OCP\IUser; use OCP\Security\ISecureRandom; -use OCP\Template; -class SmsProvider implements IProvider { - - const STATE_DISABLED = 0; - const STATE_START_VERIFICATION = 1; - const STATE_VERIFYING = 2; - const STATE_ENABLED = 3; - const SESSION_KEY = 'twofactor_gateway_secret'; - - /** @var IGateway */ - private $gateway; - - /** @var StateStorage */ - private $stateStorage; - - /** @var ISession */ - private $session; - - /** @var ISecureRandom */ - private $secureRandom; - - /** @var IL10N */ - private $l10n; +class SmsProvider extends AProvider { public function __construct(Gateway $smsGateway, StateStorage $stateStorage, ISession $session, ISecureRandom $secureRandom, IL10N $l10n) { - $this->gateway = $smsGateway; - $this->stateStorage = $stateStorage; - $this->session = $session; - $this->secureRandom = $secureRandom; - $this->l10n = $l10n; - } - - /** - * Get unique identifier of this 2FA provider - */ - public function getId(): string { - return 'gateway'; + parent::__construct( + 'sms', + $smsGateway, + $stateStorage, + $session, + $secureRandom, + $l10n + ); } /** * Get the display name for selecting the 2FA provider - * - * @todo use gateway-specific display name */ public function getDisplayName(): string { return $this->l10n->t('Message gateway verification'); @@ -93,60 +61,4 @@ class SmsProvider implements IProvider { return $this->l10n->t('Authenticate via SMS'); } - private function getSecret(): string { - if ($this->session->exists(self::SESSION_KEY)) { - return $this->session->get(self::SESSION_KEY); - } - - $secret = $this->secureRandom->generate(6, ISecureRandom::CHAR_DIGITS); - $this->session->set(self::SESSION_KEY, $secret); - - return $secret; - } - - /** - * Get the template for rending the 2FA provider view - */ - public function getTemplate(IUser $user): Template { - $secret = $this->getSecret(); - - try { - $identifier = $this->stateStorage->get($user)->getIdentifier(); - $this->gateway->send( - $user, - $identifier, - $this->l10n->t('%s is your Nextcloud authentication code', [ - $secret - ]) - ); - } catch (SmsTransmissionException $ex) { - return new Template('twofactor_gateway', 'error'); - } - - $tmpl = new Template('twofactor_gateway', 'challenge'); - $tmpl->assign('phone', PhoneNumberMask::maskNumber($identifier)); - return $tmpl; - } - - /** - * Verify the given challenge - */ - public function verifyChallenge(IUser $user, string $challenge): bool { - $valid = $this->session->exists(self::SESSION_KEY) - && $this->session->get(self::SESSION_KEY) === $challenge; - - if ($valid) { - $this->session->remove(self::SESSION_KEY); - } - - return $valid; - } - - /** - * Decides whether 2FA is enabled for the given user - */ - public function isTwoFactorAuthEnabledForUser(IUser $user): bool { - return $this->stateStorage->get($user)->getState() === self::STATE_ENABLED; - } - } diff --git a/lib/Provider/TelegramProvider.php b/lib/Provider/TelegramProvider.php new file mode 100644 index 0000000..ad25f75 --- /dev/null +++ b/lib/Provider/TelegramProvider.php @@ -0,0 +1,71 @@ +<?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\Provider; + +use OCA\TwoFactorGateway\Service\Gateway\IGateway; +use OCA\TwoFactorGateway\Service\Gateway\Telegram\Gateway; +use OCA\TwoFactorGateway\Service\StateStorage; +use OCP\IL10N; +use OCP\ISession; +use OCP\Security\ISecureRandom; + +class TelegramProvider extends AProvider { + + public function __construct(Gateway $smsGateway, + StateStorage $stateStorage, + ISession $session, + ISecureRandom $secureRandom, + IL10N $l10n) { + parent::__construct( + 'telegram', + $smsGateway, + $stateStorage, + $session, + $secureRandom, + $l10n + ); + } + + /** + * Get unique identifier of this 2FA provider + */ + public function getId(): string { + return 'gateway_telegram'; + } + + /** + * Get the display name for selecting the 2FA provider + */ + public function getDisplayName(): string { + return $this->l10n->t('Telegram verification'); + } + + /** + * Get the description for selecting the 2FA provider + */ + public function getDescription(): string { + return $this->l10n->t('Authenticate via Telegram'); + } + +} |