Merge pull request #11462 from nextcloud/feature/11380/2fa_backup_code_generation
Add notification to generate 2FA backup codes
This commit is contained in:
commit
6080d9d80a
18 changed files with 892 additions and 2 deletions
|
@ -8,18 +8,22 @@ $baseDir = $vendorDir;
|
|||
return array(
|
||||
'OCA\\TwoFactorBackupCodes\\Activity\\Provider' => $baseDir . '/../lib/Activity/Provider.php',
|
||||
'OCA\\TwoFactorBackupCodes\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
|
||||
'OCA\\TwoFactorBackupCodes\\BackgroundJob\\RememberBackupCodesJob' => $baseDir . '/../lib/BackgroundJob/RememberBackupCodesJob.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Controller\\SettingsController' => $baseDir . '/../lib/Controller/SettingsController.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Db\\BackupCode' => $baseDir . '/../lib/Db/BackupCode.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Db\\BackupCodeMapper' => $baseDir . '/../lib/Db/BackupCodeMapper.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Event\\CodesGenerated' => $baseDir . '/../lib/Event/CodesGenerated.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\ActivityPublisher' => $baseDir . '/../lib/Listener/ActivityPublisher.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\ClearNotifications' => $baseDir . '/../lib/Listener/ClearNotifications.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\IListener' => $baseDir . '/../lib/Listener/IListener.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\ProviderEnabled' => $baseDir . '/../lib/Listener/ProviderEnabled.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\RegistryUpdater' => $baseDir . '/../lib/Listener/RegistryUpdater.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170607104347' => $baseDir . '/../lib/Migration/Version1002Date20170607104347.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170607113030' => $baseDir . '/../lib/Migration/Version1002Date20170607113030.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170919123342' => $baseDir . '/../lib/Migration/Version1002Date20170919123342.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170926101419' => $baseDir . '/../lib/Migration/Version1002Date20170926101419.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20180821043638' => $baseDir . '/../lib/Migration/Version1002Date20180821043638.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Notifications\\Notifier' => $baseDir . '/../lib/Notifications/Notifier.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Provider\\BackupCodesProvider' => $baseDir . '/../lib/Provider/BackupCodesProvider.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Service\\BackupCodeStorage' => $baseDir . '/../lib/Service/BackupCodeStorage.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Settings\\Personal' => $baseDir . '/../lib/Settings/Personal.php',
|
||||
|
|
|
@ -23,18 +23,22 @@ class ComposerStaticInitTwoFactorBackupCodes
|
|||
public static $classMap = array (
|
||||
'OCA\\TwoFactorBackupCodes\\Activity\\Provider' => __DIR__ . '/..' . '/../lib/Activity/Provider.php',
|
||||
'OCA\\TwoFactorBackupCodes\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
|
||||
'OCA\\TwoFactorBackupCodes\\BackgroundJob\\RememberBackupCodesJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/RememberBackupCodesJob.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Controller\\SettingsController' => __DIR__ . '/..' . '/../lib/Controller/SettingsController.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Db\\BackupCode' => __DIR__ . '/..' . '/../lib/Db/BackupCode.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Db\\BackupCodeMapper' => __DIR__ . '/..' . '/../lib/Db/BackupCodeMapper.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Event\\CodesGenerated' => __DIR__ . '/..' . '/../lib/Event/CodesGenerated.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\ActivityPublisher' => __DIR__ . '/..' . '/../lib/Listener/ActivityPublisher.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\ClearNotifications' => __DIR__ . '/..' . '/../lib/Listener/ClearNotifications.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\IListener' => __DIR__ . '/..' . '/../lib/Listener/IListener.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\ProviderEnabled' => __DIR__ . '/..' . '/../lib/Listener/ProviderEnabled.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Listener\\RegistryUpdater' => __DIR__ . '/..' . '/../lib/Listener/RegistryUpdater.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170607104347' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20170607104347.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170607113030' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20170607113030.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170919123342' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20170919123342.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20170926101419' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20170926101419.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Migration\\Version1002Date20180821043638' => __DIR__ . '/..' . '/../lib/Migration/Version1002Date20180821043638.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Notifications\\Notifier' => __DIR__ . '/..' . '/../lib/Notifications/Notifier.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Provider\\BackupCodesProvider' => __DIR__ . '/..' . '/../lib/Provider/BackupCodesProvider.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Service\\BackupCodeStorage' => __DIR__ . '/..' . '/../lib/Service/BackupCodeStorage.php',
|
||||
'OCA\\TwoFactorBackupCodes\\Settings\\Personal' => __DIR__ . '/..' . '/../lib/Settings/Personal.php',
|
||||
|
|
|
@ -28,9 +28,16 @@ namespace OCA\TwoFactorBackupCodes\AppInfo;
|
|||
use OCA\TwoFactorBackupCodes\Db\BackupCodeMapper;
|
||||
use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
|
||||
use OCA\TwoFactorBackupCodes\Listener\ActivityPublisher;
|
||||
use OCA\TwoFactorBackupCodes\Listener\ClearNotifications;
|
||||
use OCA\TwoFactorBackupCodes\Listener\IListener;
|
||||
use OCA\TwoFactorBackupCodes\Listener\ProviderEnabled;
|
||||
use OCA\TwoFactorBackupCodes\Listener\RegistryUpdater;
|
||||
use OCA\TwoFactorBackupCodes\Notifications\Notifier;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
||||
use OCP\Authentication\TwoFactorAuth\RegistryEvent;
|
||||
use OCP\IL10N;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Util;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
|
@ -44,6 +51,7 @@ class Application extends App {
|
|||
*/
|
||||
public function register() {
|
||||
$this->registerHooksAndEvents();
|
||||
$this->registerNotification();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,12 +68,34 @@ class Application extends App {
|
|||
$listeners = [
|
||||
$container->query(ActivityPublisher::class),
|
||||
$container->query(RegistryUpdater::class),
|
||||
$container->query(ClearNotifications::class),
|
||||
];
|
||||
|
||||
foreach ($listeners as $listener) {
|
||||
$listener->handle($event);
|
||||
}
|
||||
});
|
||||
|
||||
$eventDispatcher->addListener(IRegistry::EVENT_PROVIDER_ENABLED, function(RegistryEvent $event) use ($container) {
|
||||
/** @var IListener $listener */
|
||||
$listener = $container->query(ProviderEnabled::class);
|
||||
$listener->handle($event);
|
||||
});
|
||||
}
|
||||
|
||||
public function registerNotification() {
|
||||
$container = $this->getContainer();
|
||||
/** @var IManager $manager */
|
||||
$manager = $container->query(IManager::class);
|
||||
$manager->registerNotifier(
|
||||
function() use ($container) {
|
||||
return $container->query(Notifier::class);
|
||||
},
|
||||
function () use ($container) {
|
||||
$l = $container->query(IL10N::class);
|
||||
return ['id' => 'twofactor_backupcodes', 'name' => $l->t('Second-factor backup codes')];
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function deleteUser($params) {
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCA\TwoFactorBackupCodes\BackgroundJob;
|
||||
|
||||
use OC\BackgroundJob\TimedJob;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Notification\IManager;
|
||||
|
||||
class RememberBackupCodesJob extends TimedJob {
|
||||
|
||||
/** @var IRegistry */
|
||||
private $registry;
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var ITimeFactory */
|
||||
private $time;
|
||||
|
||||
/** @var IManager */
|
||||
private $notificationManager;
|
||||
|
||||
/** @var IJobList */
|
||||
private $jobList;
|
||||
|
||||
public function __construct(IRegistry $registry,
|
||||
IUserManager $userManager,
|
||||
ITimeFactory $timeFactory,
|
||||
IManager $notificationManager,
|
||||
IJobList $jobList) {
|
||||
$this->registry = $registry;
|
||||
$this->userManager = $userManager;
|
||||
$this->time = $timeFactory;
|
||||
$this->notificationManager = $notificationManager;
|
||||
$this->jobList = $jobList;
|
||||
|
||||
$this->setInterval(60*60*24*14);
|
||||
}
|
||||
|
||||
protected function run($argument) {
|
||||
$uid = $argument['uid'];
|
||||
$user = $this->userManager->get($uid);
|
||||
|
||||
if ($user === null) {
|
||||
// We can't run with an invalid user
|
||||
return;
|
||||
}
|
||||
|
||||
$providers = $this->registry->getProviderStates($user);
|
||||
if (isset($providers['backup_codes']) && $providers['backup_codes'] === true) {
|
||||
// Backup codes already generated lets remove this job
|
||||
$this->jobList->remove(self::class, $argument);
|
||||
return;
|
||||
}
|
||||
|
||||
$date = new \DateTime();
|
||||
$date->setTimestamp($this->time->getTime());
|
||||
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification->setApp('twofactor_backupcodes')
|
||||
->setUser($user->getUID())
|
||||
->setDateTime($date)
|
||||
->setObject('create', 'codes')
|
||||
->setSubject('create_backupcodes');
|
||||
$this->notificationManager->notify($notification);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCA\TwoFactorBackupCodes\Listener;
|
||||
|
||||
use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
|
||||
use OCP\Notification\IManager;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
|
||||
class ClearNotifications implements IListener {
|
||||
|
||||
/** @var IManager */
|
||||
private $manager;
|
||||
|
||||
public function __construct(IManager $manager) {
|
||||
$this->manager = $manager;
|
||||
}
|
||||
|
||||
public function handle(Event $event) {
|
||||
if (!($event instanceof CodesGenerated)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notification = $this->manager->createNotification();
|
||||
$notification->setApp('twofactor_backupcodes')
|
||||
->setUser($event->getUser()->getUID())
|
||||
->setObject('create', 'codes');
|
||||
$this->manager->markProcessed($notification);
|
||||
}
|
||||
}
|
61
apps/twofactor_backupcodes/lib/Listener/ProviderEnabled.php
Normal file
61
apps/twofactor_backupcodes/lib/Listener/ProviderEnabled.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCA\TwoFactorBackupCodes\Listener;
|
||||
|
||||
use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
|
||||
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
||||
use OCP\Authentication\TwoFactorAuth\RegistryEvent;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
|
||||
class ProviderEnabled implements IListener {
|
||||
|
||||
/** @var IRegistry */
|
||||
private $registry;
|
||||
|
||||
/** @var IJobList */
|
||||
private $jobList;
|
||||
|
||||
public function __construct(IRegistry $registry,
|
||||
IJobList $jobList) {
|
||||
$this->registry = $registry;
|
||||
$this->jobList = $jobList;
|
||||
}
|
||||
|
||||
public function handle(Event $event) {
|
||||
if (!($event instanceof RegistryEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$providers = $this->registry->getProviderStates($event->getUser());
|
||||
if (isset($providers['backup_codes']) && $providers['backup_codes'] === true) {
|
||||
// Backup codes already generated nothing to do here
|
||||
return;
|
||||
}
|
||||
|
||||
$this->jobList->add(RememberBackupCodesJob::class, ['uid' => $event->getUser()->getUID()]);
|
||||
}
|
||||
|
||||
}
|
64
apps/twofactor_backupcodes/lib/Notifications/Notifier.php
Normal file
64
apps/twofactor_backupcodes/lib/Notifications/Notifier.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCA\TwoFactorBackupCodes\Notifications;
|
||||
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Notification\INotification;
|
||||
use OCP\Notification\INotifier;
|
||||
|
||||
class Notifier implements INotifier {
|
||||
|
||||
/** @var IFactory */
|
||||
private $factory;
|
||||
|
||||
public function __construct(IFactory $factory) {
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
public function prepare(INotification $notification, $languageCode) {
|
||||
if ($notification->getApp() !== 'twofactor_backupcodes') {
|
||||
// Not my app => throw
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
// Read the language from the notification
|
||||
$l = $this->factory->get('twofactor_backupcodes', $languageCode);
|
||||
|
||||
switch ($notification->getSubject()) {
|
||||
case 'create_backupcodes':
|
||||
$notification->setParsedSubject(
|
||||
$l->t('Generate backup codes')
|
||||
)->setParsedMessage(
|
||||
$l->t('You have enabled two-factor authentication but have not yet generated backup codes. Be sure to do this in case you lose access to your second factor.')
|
||||
);
|
||||
return $notification;
|
||||
|
||||
default:
|
||||
// Unknown subject => Unknown notification => throw
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,8 @@
|
|||
namespace OCA\TwoFactorBackupCodes\Tests\Service;
|
||||
|
||||
use OCA\TwoFactorBackupCodes\Service\BackupCodeStorage;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
use Test\TestCase;
|
||||
|
||||
/**
|
||||
|
@ -36,10 +38,18 @@ class BackupCodeStorageTest extends TestCase {
|
|||
/** @var string */
|
||||
private $testUID = 'test123456789';
|
||||
|
||||
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $notificationManager;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->storage = \OC::$server->query(BackupCodeStorage::class);
|
||||
|
||||
$this->notificationManager = $this->createMock(IManager::class);
|
||||
$this->notificationManager->method('createNotification')
|
||||
->willReturn(\OC::$server->query(IManager::class)->createNotification());
|
||||
$this->overwriteService(IManager::class, $this->notificationManager);
|
||||
}
|
||||
|
||||
public function testSimpleWorkFlow() {
|
||||
|
@ -48,6 +58,15 @@ class BackupCodeStorageTest extends TestCase {
|
|||
->method('getUID')
|
||||
->will($this->returnValue($this->testUID));
|
||||
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('markProcessed')
|
||||
->with($this->callback(function (INotification $notification) {
|
||||
return $notification->getUser() === $this->testUID &&
|
||||
$notification->getObjectType() === 'create' &&
|
||||
$notification->getObjectId() === 'codes' &&
|
||||
$notification->getApp() === 'twofactor_backupcodes';
|
||||
}));
|
||||
|
||||
// Create codes
|
||||
$codes = $this->storage->createCodes($user, 5);
|
||||
$this->assertCount(5, $codes);
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCA\TwoFactorBackupCodes\Tests\Unit\BackgroundJob;
|
||||
|
||||
use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
use Test\TestCase;
|
||||
|
||||
class RememberBackupCodesJobTest extends TestCase {
|
||||
|
||||
/** @var IRegistry|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $registry;
|
||||
|
||||
/** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $userManager;
|
||||
|
||||
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $time;
|
||||
|
||||
/** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $notificationManager;
|
||||
|
||||
/** @var IJobList|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $jobList;
|
||||
|
||||
/** @var RememberBackupCodesJob */
|
||||
private $job;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->registry = $this->createMock(IRegistry::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->time = $this->createMock(ITimeFactory::class);
|
||||
$this->time->method('getTime')
|
||||
->willReturn(10000000);
|
||||
$this->notificationManager = $this->createMock(IManager::class);
|
||||
$this->jobList = $this->createMock(IJobList::class);
|
||||
|
||||
$this->job = new RememberBackupCodesJob(
|
||||
$this->registry,
|
||||
$this->userManager,
|
||||
$this->time,
|
||||
$this->notificationManager,
|
||||
$this->jobList
|
||||
);
|
||||
}
|
||||
|
||||
public function testInvalidUID() {
|
||||
$this->userManager->method('get')
|
||||
->with('invalidUID')
|
||||
->willReturn(null);
|
||||
|
||||
$this->notificationManager->expects($this->never())
|
||||
->method($this->anything());
|
||||
$this->jobList->expects($this->never())
|
||||
->method($this->anything());
|
||||
|
||||
$this->invokePrivate($this->job, 'run', [['uid' => 'invalidUID']]);
|
||||
}
|
||||
|
||||
public function testBackupCodesGenerated() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')
|
||||
->willReturn('validUID');
|
||||
$this->userManager->method('get')
|
||||
->with('validUID')
|
||||
->willReturn($user);
|
||||
|
||||
$this->registry->method('getProviderStates')
|
||||
->with($user)
|
||||
->willReturn([
|
||||
'backup_codes' => true
|
||||
]);
|
||||
|
||||
$this->jobList->expects($this->once())
|
||||
->method('remove')
|
||||
->with(
|
||||
RememberBackupCodesJob::class,
|
||||
['uid' => 'validUID']
|
||||
);
|
||||
|
||||
$this->notificationManager->expects($this->never())
|
||||
->method($this->anything());
|
||||
|
||||
$this->invokePrivate($this->job, 'run', [['uid' => 'validUID']]);
|
||||
}
|
||||
|
||||
public function testNotificationSend() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')
|
||||
->willReturn('validUID');
|
||||
$this->userManager->method('get')
|
||||
->with('validUID')
|
||||
->willReturn($user);
|
||||
|
||||
$this->registry->method('getProviderStates')
|
||||
->with($user)
|
||||
->willReturn([
|
||||
'backup_codes' => false
|
||||
]);
|
||||
|
||||
$this->jobList->expects($this->never())
|
||||
->method($this->anything());
|
||||
|
||||
$date = new \DateTime();
|
||||
$date->setTimestamp($this->time->getTime());
|
||||
|
||||
$this->notificationManager->method('createNotification')
|
||||
->willReturn(\OC::$server->query(IManager::class)->createNotification());
|
||||
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('notify')
|
||||
->with($this->callback(function (INotification $n) {
|
||||
return $n->getApp() === 'twofactor_backupcodes' &&
|
||||
$n->getUser() === 'validUID' &&
|
||||
$n->getDateTime()->getTimestamp() === 10000000 &&
|
||||
$n->getObjectType() === 'create' &&
|
||||
$n->getObjectId() === 'codes' &&
|
||||
$n->getSubject() === 'create_backupcodes';
|
||||
}));
|
||||
|
||||
$this->invokePrivate($this->job, 'run', [['uid' => 'validUID']]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCA\TwoFactorBackupCodes\Tests\Unit\Listener;
|
||||
|
||||
use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
|
||||
use OCA\TwoFactorBackupCodes\Listener\ClearNotifications;
|
||||
use OCP\IUser;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Test\TestCase;
|
||||
|
||||
class ClearNotificationsTest extends TestCase {
|
||||
|
||||
/** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $notificationManager;
|
||||
|
||||
/** @var ClearNotifications */
|
||||
private $listener;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->notificationManager = $this->createMock(IManager::class);
|
||||
$this->notificationManager->method('createNotification')
|
||||
->willReturn(\OC::$server->query(IManager::class)->createNotification());
|
||||
|
||||
$this->listener = new ClearNotifications($this->notificationManager);
|
||||
}
|
||||
|
||||
public function testHandleGenericEvent() {
|
||||
$event = $this->createMock(Event::class);
|
||||
$this->notificationManager->expects($this->never())
|
||||
->method($this->anything());
|
||||
|
||||
$this->listener->handle($event);
|
||||
}
|
||||
|
||||
public function testHandleCodesGeneratedEvent() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')->willReturn('fritz');
|
||||
$event = new CodesGenerated($user);
|
||||
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('markProcessed')
|
||||
->with($this->callback(function(INotification $n) {
|
||||
return $n->getUser() === 'fritz' &&
|
||||
$n->getApp() === 'twofactor_backupcodes' &&
|
||||
$n->getObjectType() === 'create' &&
|
||||
$n->getObjectId() === 'codes';
|
||||
}));
|
||||
|
||||
$this->listener->handle($event);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCA\TwoFactorBackupCodes\Tests\Unit\Listener;
|
||||
|
||||
use OCA\TwoFactorBackupCodes\BackgroundJob\RememberBackupCodesJob;
|
||||
use OCA\TwoFactorBackupCodes\Listener\ProviderEnabled;
|
||||
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
||||
use OCP\Authentication\TwoFactorAuth\RegistryEvent;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\IUser;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Test\TestCase;
|
||||
|
||||
class ProviderEnabledTest extends TestCase {
|
||||
|
||||
/** @var IRegistry|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $registy;
|
||||
|
||||
/** @var IJobList|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $jobList;
|
||||
|
||||
/** @var ProviderEnabled */
|
||||
private $listener;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->registy = $this->createMock(IRegistry::class);
|
||||
$this->jobList = $this->createMock(IJobList::class);
|
||||
|
||||
$this->listener = new ProviderEnabled($this->registy, $this->jobList);
|
||||
}
|
||||
|
||||
public function testHandleGenericEvent() {
|
||||
$event = $this->createMock(Event::class);
|
||||
$this->jobList->expects($this->never())
|
||||
->method($this->anything());
|
||||
|
||||
$this->listener->handle($event);
|
||||
}
|
||||
|
||||
public function testHandleCodesGeneratedEventAlraedyBackupcodes() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')
|
||||
->willReturn('myUID');
|
||||
$event = $this->createMock(RegistryEvent::class);
|
||||
$event->method('getUser')
|
||||
->willReturn($user);
|
||||
|
||||
$this->registy->method('getProviderStates')
|
||||
->with($user)
|
||||
->willReturn([
|
||||
'backup_codes' => true,
|
||||
]);
|
||||
|
||||
$this->jobList->expects($this->never())
|
||||
->method($this->anything());
|
||||
|
||||
$this->listener->handle($event);
|
||||
}
|
||||
|
||||
public function testHandleCodesGeneratedEventNoBackupcodes() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')
|
||||
->willReturn('myUID');
|
||||
$event = $this->createMock(RegistryEvent::class);
|
||||
$event->method('getUser')
|
||||
->willReturn($user);
|
||||
|
||||
$this->registy->method('getProviderStates')
|
||||
->with($user)
|
||||
->willReturn([
|
||||
'backup_codes' => false,
|
||||
]);
|
||||
|
||||
$this->jobList->expects($this->once())
|
||||
->method('add')
|
||||
->with(
|
||||
$this->equalTo(RememberBackupCodesJob::class),
|
||||
$this->equalTo(['uid' => 'myUID'])
|
||||
);
|
||||
|
||||
$this->listener->handle($event);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCA\TwoFactorBackupCodes\Tests\Unit\Notification;
|
||||
|
||||
use OCA\TwoFactorBackupCodes\Notifications\Notifier;
|
||||
use OCP\IL10N;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Notification\INotification;
|
||||
use Test\TestCase;
|
||||
|
||||
class NotifierTest extends TestCase {
|
||||
/** @var Notifier */
|
||||
protected $notifier;
|
||||
|
||||
/** @var IFactory|\PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $factory;
|
||||
/** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $l;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->l = $this->createMock(IL10N::class);
|
||||
$this->l->expects($this->any())
|
||||
->method('t')
|
||||
->willReturnCallback(function($string, $args) {
|
||||
return vsprintf($string, $args);
|
||||
});
|
||||
$this->factory = $this->createMock(IFactory::class);
|
||||
$this->factory->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn($this->l);
|
||||
|
||||
$this->notifier = new Notifier(
|
||||
$this->factory
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testPrepareWrongApp() {
|
||||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->createMock(INotification::class);
|
||||
$notification->expects($this->once())
|
||||
->method('getApp')
|
||||
->willReturn('notifications');
|
||||
$notification->expects($this->never())
|
||||
->method('getSubject');
|
||||
|
||||
$this->notifier->prepare($notification, 'en');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testPrepareWrongSubject() {
|
||||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->createMock(INotification::class);
|
||||
$notification->expects($this->once())
|
||||
->method('getApp')
|
||||
->willReturn('twofactor_backupcodes');
|
||||
$notification->expects($this->once())
|
||||
->method('getSubject')
|
||||
->willReturn('wrong subject');
|
||||
|
||||
$this->notifier->prepare($notification, 'en');
|
||||
}
|
||||
|
||||
public function testPrepare() {
|
||||
/** @var \OCP\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->createMock(INotification::class);
|
||||
|
||||
$notification->expects($this->once())
|
||||
->method('getApp')
|
||||
->willReturn('twofactor_backupcodes');
|
||||
$notification->expects($this->once())
|
||||
->method('getSubject')
|
||||
->willReturn('create_backupcodes');
|
||||
|
||||
$this->factory->expects($this->once())
|
||||
->method('get')
|
||||
->with('twofactor_backupcodes', 'nl')
|
||||
->willReturn($this->l);
|
||||
|
||||
$notification->expects($this->once())
|
||||
->method('setParsedSubject')
|
||||
->with('Generate backup codes')
|
||||
->willReturnSelf();
|
||||
$notification->expects($this->once())
|
||||
->method('setParsedMessage')
|
||||
->with('You have enabled two-factor authentication but have not yet generated backup codes. Be sure to do this in case you lose access to your second factor.')
|
||||
->willReturnSelf();
|
||||
|
||||
$return = $this->notifier->prepare($notification, 'nl');
|
||||
$this->assertEquals($notification, $return);
|
||||
}
|
||||
}
|
|
@ -74,6 +74,7 @@ return array(
|
|||
'OCP\\Authentication\\TwoFactorAuth\\IProvider' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvider.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvidesCustomCSP' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvidesCustomCSP.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IRegistry' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IRegistry.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\RegistryEvent' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/RegistryEvent.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\TwoFactorException' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/TwoFactorException.php',
|
||||
'OCP\\AutoloadNotAllowedException' => $baseDir . '/lib/public/AutoloadNotAllowedException.php',
|
||||
'OCP\\BackgroundJob' => $baseDir . '/lib/public/BackgroundJob.php',
|
||||
|
|
|
@ -104,6 +104,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
|||
'OCP\\Authentication\\TwoFactorAuth\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvider.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvidesCustomCSP' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvidesCustomCSP.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IRegistry' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IRegistry.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\RegistryEvent' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/RegistryEvent.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\TwoFactorException' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/TwoFactorException.php',
|
||||
'OCP\\AutoloadNotAllowedException' => __DIR__ . '/../../..' . '/lib/public/AutoloadNotAllowedException.php',
|
||||
'OCP\\BackgroundJob' => __DIR__ . '/../../..' . '/lib/public/BackgroundJob.php',
|
||||
|
|
|
@ -29,15 +29,23 @@ namespace OC\Authentication\TwoFactorAuth;
|
|||
use OC\Authentication\TwoFactorAuth\Db\ProviderUserAssignmentDao;
|
||||
use OCP\Authentication\TwoFactorAuth\IProvider;
|
||||
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
||||
use OCP\Authentication\TwoFactorAuth\RegistryEvent;
|
||||
use OCP\IUser;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
class Registry implements IRegistry {
|
||||
|
||||
/** @var ProviderUserAssignmentDao */
|
||||
private $assignmentDao;
|
||||
|
||||
public function __construct(ProviderUserAssignmentDao $assignmentDao) {
|
||||
/** @var EventDispatcherInterface */
|
||||
private $dispatcher;
|
||||
|
||||
public function __construct(ProviderUserAssignmentDao $assignmentDao,
|
||||
EventDispatcherInterface $dispatcher) {
|
||||
$this->assignmentDao = $assignmentDao;
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
public function getProviderStates(IUser $user): array {
|
||||
|
@ -46,10 +54,16 @@ class Registry implements IRegistry {
|
|||
|
||||
public function enableProviderFor(IProvider $provider, IUser $user) {
|
||||
$this->assignmentDao->persist($provider->getId(), $user->getUID(), 1);
|
||||
|
||||
$event = new RegistryEvent($provider, $user);
|
||||
$this->dispatcher->dispatch(self::EVENT_PROVIDER_ENABLED, $event);
|
||||
}
|
||||
|
||||
public function disableProviderFor(IProvider $provider, IUser $user) {
|
||||
$this->assignmentDao->persist($provider->getId(), $user->getUID(), 0);
|
||||
|
||||
$event = new RegistryEvent($provider, $user);
|
||||
$this->dispatcher->dispatch(self::EVENT_PROVIDER_DISABLED, $event);
|
||||
}
|
||||
|
||||
public function cleanUp(string $providerId) {
|
||||
|
|
|
@ -39,6 +39,10 @@ use OCP\IUser;
|
|||
*/
|
||||
interface IRegistry {
|
||||
|
||||
|
||||
const EVENT_PROVIDER_ENABLED = self::class . '::enable';
|
||||
const EVENT_PROVIDER_DISABLED = self::class . '::disable';
|
||||
|
||||
/**
|
||||
* Get a key-value map of providers and their enabled/disabled state for
|
||||
* the given user.
|
||||
|
|
62
lib/public/Authentication/TwoFactorAuth/RegistryEvent.php
Normal file
62
lib/public/Authentication/TwoFactorAuth/RegistryEvent.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2018, 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 OCP\Authentication\TwoFactorAuth;
|
||||
|
||||
use OCP\IUser;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
class RegistryEvent extends Event {
|
||||
|
||||
/** @var IProvider */
|
||||
private $provider;
|
||||
|
||||
/** @IUser */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function __construct(IProvider $provider, IUser $user) {
|
||||
$this->provider = $provider;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getProvider(): IProvider {
|
||||
return $this->provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getUser(): IUser {
|
||||
return $this->user;
|
||||
}
|
||||
}
|
|
@ -27,8 +27,11 @@ namespace Test\Authentication\TwoFactorAuth;
|
|||
use OC\Authentication\TwoFactorAuth\Db\ProviderUserAssignmentDao;
|
||||
use OC\Authentication\TwoFactorAuth\Registry;
|
||||
use OCP\Authentication\TwoFactorAuth\IProvider;
|
||||
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
||||
use OCP\Authentication\TwoFactorAuth\RegistryEvent;
|
||||
use OCP\IUser;
|
||||
use PHPUnit_Framework_MockObject_MockObject;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class RegistryTest extends TestCase {
|
||||
|
@ -39,12 +42,16 @@ class RegistryTest extends TestCase {
|
|||
/** @var Registry */
|
||||
private $registry;
|
||||
|
||||
/** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $dispatcher;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->dao = $this->createMock(ProviderUserAssignmentDao::class);
|
||||
$this->dispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||
|
||||
$this->registry = new Registry($this->dao);
|
||||
$this->registry = new Registry($this->dao, $this->dispatcher);
|
||||
}
|
||||
|
||||
public function testGetProviderStates() {
|
||||
|
@ -68,6 +75,15 @@ class RegistryTest extends TestCase {
|
|||
$this->dao->expects($this->once())->method('persist')->with('p1', 'user123',
|
||||
true);
|
||||
|
||||
$this->dispatcher->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(
|
||||
$this->equalTo(IRegistry::EVENT_PROVIDER_ENABLED),
|
||||
$this->callback(function(RegistryEvent $e) use ($user, $provider) {
|
||||
return $e->getUser() === $user && $e->getProvider() === $provider;
|
||||
})
|
||||
);
|
||||
|
||||
$this->registry->enableProviderFor($provider, $user);
|
||||
}
|
||||
|
||||
|
@ -79,6 +95,16 @@ class RegistryTest extends TestCase {
|
|||
$this->dao->expects($this->once())->method('persist')->with('p1', 'user123',
|
||||
false);
|
||||
|
||||
|
||||
$this->dispatcher->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(
|
||||
$this->equalTo(IRegistry::EVENT_PROVIDER_DISABLED),
|
||||
$this->callback(function(RegistryEvent $e) use ($user, $provider) {
|
||||
return $e->getUser() === $user && $e->getProvider() === $provider;
|
||||
})
|
||||
);
|
||||
|
||||
$this->registry->disableProviderFor($provider, $user);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue