Generate backups code notification if not enable but 2fa is

Generate a notification to generate backup codes if you enable an other
2FA provider but backup codes are not yet generated.

* Add event listner
* Insert background job
* Background job tests and emits notification every 2 weeks
* If the backup codes are generated the next run will remove the job

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
Roeland Jago Douma 2018-09-29 20:56:23 +02:00
parent a95154642d
commit 956fe1b867
No known key found for this signature in database
GPG Key ID: F941078878347C0C
10 changed files with 658 additions and 1 deletions

View File

@ -8,18 +8,21 @@ $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\\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',

View File

@ -23,18 +23,21 @@ 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\\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',

View File

@ -29,8 +29,14 @@ use OCA\TwoFactorBackupCodes\Db\BackupCodeMapper;
use OCA\TwoFactorBackupCodes\Event\CodesGenerated;
use OCA\TwoFactorBackupCodes\Listener\ActivityPublisher;
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 +50,7 @@ class Application extends App {
*/
public function register() {
$this->registerHooksAndEvents();
$this->registerNotification();
}
/**
@ -66,6 +73,27 @@ class Application extends App {
$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) {

View File

@ -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);
}
}

View 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()]);
}
}

View 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();
}
}
}

View File

@ -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']]);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}