Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/twofactor_totp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2018-07-30 13:37:12 +0300
committerChristoph Wurst <christoph@winzerhof-wurst.at>2018-07-31 10:01:11 +0300
commit4252b9b778a7ffed10e39857095932d474531e16 (patch)
tree015417a6fe285420aab4f8fce830509de59abd31 /lib
parent279860969dbcae7b7cd9953030c864f2dc03dce6 (diff)
Refactor state change to use events
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib')
-rw-r--r--lib/AppInfo/Application.php17
-rw-r--r--lib/Event/StateChanged.php57
-rw-r--r--lib/Listener/IListener.php33
-rw-r--r--lib/Listener/StateChangeActivity.php54
-rw-r--r--lib/Service/Totp.php42
5 files changed, 176 insertions, 27 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 45be45f..d3dd60b 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -1,6 +1,6 @@
<?php
-declare(strict_types = 1);
+declare(strict_types=1);
/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
@@ -23,6 +23,9 @@ declare(strict_types = 1);
namespace OCA\TwoFactorTOTP\AppInfo;
+use OCA\TwoFactorTOTP\Event\StateChanged;
+use OCA\TwoFactorTOTP\Listener\IListener;
+use OCA\TwoFactorTOTP\Listener\StateChangeActivity;
use OCA\TwoFactorTOTP\Service\ITotp;
use OCA\TwoFactorTOTP\Service\Totp;
use OCP\AppFramework\App;
@@ -34,6 +37,18 @@ class Application extends App {
$container = $this->getContainer();
$container->registerAlias(ITotp::class, Totp::class);
+
+ $dispatcher = $container->getServer()->getEventDispatcher();
+ $dispatcher->addListener(StateChanged::class, function (StateChanged $event) use ($container) {
+ /** @var IListener[] $listeners */
+ $listeners = [
+ $container->query(StateChangeActivity::class),
+ ];
+
+ foreach ($listeners as $listener) {
+ $listener->handle($event);
+ }
+ });
}
}
diff --git a/lib/Event/StateChanged.php b/lib/Event/StateChanged.php
new file mode 100644
index 0000000..4abf896
--- /dev/null
+++ b/lib/Event/StateChanged.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
+ * @copyright Copyright (c) 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * Two-factor TOTP
+ *
+ * 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\TwoFactorTOTP\Event;
+
+use OCP\IUser;
+use Symfony\Component\EventDispatcher\Event;
+
+class StateChanged extends Event {
+
+ /** @var IUser */
+ private $user;
+
+ /** @var bool */
+ private $enabled;
+
+ public function __construct(IUser $user, bool $enabled) {
+ $this->user = $user;
+ $this->enabled = $enabled;
+ }
+
+ /**
+ * @return IUser
+ */
+ public function getUser(): IUser {
+ return $this->user;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isEnabled(): bool {
+ return $this->enabled;
+ }
+
+} \ No newline at end of file
diff --git a/lib/Listener/IListener.php b/lib/Listener/IListener.php
new file mode 100644
index 0000000..7e5f13d
--- /dev/null
+++ b/lib/Listener/IListener.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
+ * @copyright Copyright (c) 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * Two-factor TOTP
+ *
+ * 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\TwoFactorTOTP\Listener;
+
+use Symfony\Component\EventDispatcher\Event;
+
+interface IListener {
+
+ public function handle(Event $event);
+
+}
diff --git a/lib/Listener/StateChangeActivity.php b/lib/Listener/StateChangeActivity.php
new file mode 100644
index 0000000..d60af3f
--- /dev/null
+++ b/lib/Listener/StateChangeActivity.php
@@ -0,0 +1,54 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
+ * @copyright Copyright (c) 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * Two-factor TOTP
+ *
+ * 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\TwoFactorTOTP\Listener;
+
+use OCA\TwoFactorTOTP\Event\StateChanged;
+use OCP\Activity\IManager as ActivityManager;
+use Symfony\Component\EventDispatcher\Event;
+
+class StateChangeActivity implements IListener {
+
+ /** @var ActivityManager */
+ private $activityManager;
+
+ public function __construct(ActivityManager $activityManager) {
+ $this->activityManager = $activityManager;
+ }
+
+ public function handle(Event $event) {
+ if ($event instanceof StateChanged) {
+ $user = $event->getUser();
+ $subject = $event->isEnabled() ? 'totp_enabled_subject' : 'totp_disabled_subject';
+
+ $activity = $this->activityManager->generateEvent();
+ $activity->setApp('twofactor_totp')
+ ->setType('security')
+ ->setAuthor($user->getUID())
+ ->setAffectedUser($user->getUID());
+ $activity->setSubject($subject);
+ $this->activityManager->publish($activity);
+ }
+ }
+} \ No newline at end of file
diff --git a/lib/Service/Totp.php b/lib/Service/Totp.php
index 47ec8cc..f40716c 100644
--- a/lib/Service/Totp.php
+++ b/lib/Service/Totp.php
@@ -1,6 +1,6 @@
<?php
-declare(strict_types = 1);
+declare(strict_types=1);
/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
@@ -27,13 +27,14 @@ namespace OCA\TwoFactorTOTP\Service;
use Base32\Base32;
use OCA\TwoFactorTOTP\Db\TotpSecret;
use OCA\TwoFactorTOTP\Db\TotpSecretMapper;
+use OCA\TwoFactorTOTP\Event\StateChanged;
use OCA\TwoFactorTOTP\Exception\NoTotpSecretFoundException;
-use OCP\Activity\IManager as ActivityManager;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\IUser;
use OCP\Security\ICrypto;
use Otp\GoogleAuthenticator;
use Otp\Otp;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class Totp implements ITotp {
@@ -43,19 +44,21 @@ class Totp implements ITotp {
/** @var ICrypto */
private $crypto;
- /** @var ActivityManager */
- private $activityManager;
+ /** @var EventDispatcherInterface */
+ private $eventDispatcher;
- public function __construct(TotpSecretMapper $secretMapper, ICrypto $crypto, ActivityManager $activityManager) {
+ public function __construct(TotpSecretMapper $secretMapper,
+ ICrypto $crypto,
+ EventDispatcherInterface $eventDispatcher) {
$this->secretMapper = $secretMapper;
$this->crypto = $crypto;
- $this->activityManager = $activityManager;
+ $this->eventDispatcher = $eventDispatcher;
}
public function hasSecret(IUser $user) {
try {
$secret = $this->secretMapper->getSecret($user);
- return ITotp::STATE_ENABLED === (int) $secret->getState();
+ return ITotp::STATE_ENABLED === (int)$secret->getState();
} catch (DoesNotExistException $ex) {
return false;
}
@@ -66,7 +69,7 @@ class Totp implements ITotp {
*/
public function createSecret(IUser $user): string {
try {
- // Delet existing one
+ // Delete existing one
$oldSecret = $this->secretMapper->getSecret($user);
$this->secretMapper->delete($oldSecret);
} catch (DoesNotExistException $ex) {
@@ -85,22 +88,6 @@ class Totp implements ITotp {
return $secret;
}
- /**
- * Push an TOTP event the user's activity stream
- *
- * @param IUser $user
- * @param string $event
- */
- private function publishEvent(IUser $user, $event) {
- $activity = $this->activityManager->generateEvent();
- $activity->setApp('twofactor_totp')
- ->setType('security')
- ->setAuthor($user->getUID())
- ->setAffectedUser($user->getUID());
- $activity->setSubject($event . '_subject');
- $this->activityManager->publish($activity);
- }
-
public function enable(IUser $user, $key): bool {
if (!$this->validateSecret($user, $key)) {
return false;
@@ -108,7 +95,9 @@ class Totp implements ITotp {
$dbSecret = $this->secretMapper->getSecret($user);
$dbSecret->setState(ITotp::STATE_ENABLED);
$this->secretMapper->update($dbSecret);
- $this->publishEvent($user, 'totp_enabled');
+
+ $this->eventDispatcher->dispatch(StateChanged::class, new StateChanged($user, true));
+
return true;
}
@@ -120,7 +109,8 @@ class Totp implements ITotp {
} catch (DoesNotExistException $ex) {
// Ignore
}
- $this->publishEvent($user, 'totp_disabled');
+
+ $this->eventDispatcher->dispatch(StateChanged::class, new StateChanged($user, false));
}
public function validateSecret(IUser $user, $key): bool {