Clear backupcode reminder when no 2fatags/v16.0.0beta1
@@ -17,6 +17,7 @@ return array( | |||
'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\\ProviderDisabled' => $baseDir . '/../lib/Listener/ProviderDisabled.php', | |||
'OCA\\TwoFactorBackupCodes\\Listener\\ProviderEnabled' => $baseDir . '/../lib/Listener/ProviderEnabled.php', | |||
'OCA\\TwoFactorBackupCodes\\Listener\\RegistryUpdater' => $baseDir . '/../lib/Listener/RegistryUpdater.php', | |||
'OCA\\TwoFactorBackupCodes\\Migration\\CheckBackupCodes' => $baseDir . '/../lib/Migration/CheckBackupCodes.php', |
@@ -32,6 +32,7 @@ class ComposerStaticInitTwoFactorBackupCodes | |||
'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\\ProviderDisabled' => __DIR__ . '/..' . '/../lib/Listener/ProviderDisabled.php', | |||
'OCA\\TwoFactorBackupCodes\\Listener\\ProviderEnabled' => __DIR__ . '/..' . '/../lib/Listener/ProviderEnabled.php', | |||
'OCA\\TwoFactorBackupCodes\\Listener\\RegistryUpdater' => __DIR__ . '/..' . '/../lib/Listener/RegistryUpdater.php', | |||
'OCA\\TwoFactorBackupCodes\\Migration\\CheckBackupCodes' => __DIR__ . '/..' . '/../lib/Migration/CheckBackupCodes.php', |
@@ -30,6 +30,7 @@ use OCA\TwoFactorBackupCodes\Event\CodesGenerated; | |||
use OCA\TwoFactorBackupCodes\Listener\ActivityPublisher; | |||
use OCA\TwoFactorBackupCodes\Listener\ClearNotifications; | |||
use OCA\TwoFactorBackupCodes\Listener\IListener; | |||
use OCA\TwoFactorBackupCodes\Listener\ProviderDisabled; | |||
use OCA\TwoFactorBackupCodes\Listener\ProviderEnabled; | |||
use OCA\TwoFactorBackupCodes\Listener\RegistryUpdater; | |||
use OCA\TwoFactorBackupCodes\Notifications\Notifier; | |||
@@ -81,6 +82,12 @@ class Application extends App { | |||
$listener = $container->query(ProviderEnabled::class); | |||
$listener->handle($event); | |||
}); | |||
$eventDispatcher->addListener(IRegistry::EVENT_PROVIDER_DISABLED, function(RegistryEvent $event) use ($container) { | |||
/** @var IListener $listener */ | |||
$listener = $container->query(ProviderDisabled::class); | |||
$listener->handle($event); | |||
}); | |||
} | |||
public function registerNotification() { |
@@ -70,7 +70,15 @@ class RememberBackupCodesJob extends TimedJob { | |||
} | |||
$providers = $this->registry->getProviderStates($user); | |||
if (isset($providers['backup_codes']) && $providers['backup_codes'] === true) { | |||
$state2fa = array_reduce($providers, function(bool $carry, bool $state) { | |||
return $carry || $state; | |||
}, false); | |||
/* | |||
* If no provider is active or if the backup codes are already generate | |||
* we can remove the job | |||
*/ | |||
if ($state2fa === false || (isset($providers['backup_codes']) && $providers['backup_codes'] === true)) { | |||
// Backup codes already generated lets remove this job | |||
$this->jobList->remove(self::class, $argument); | |||
return; |
@@ -0,0 +1,65 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2019, 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 ProviderDisabled 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()); | |||
// Loop over all providers. If all are disabled we remove the job | |||
$state = array_reduce($providers, function (bool $carry, bool $enabled) { | |||
return $carry || $enabled; | |||
}, false); | |||
if ($state === false) { | |||
$this->jobList->remove(RememberBackupCodesJob::class, ['uid' => $event->getUser()->getUID()]); | |||
} | |||
} | |||
} |
@@ -114,6 +114,34 @@ class RememberBackupCodesJobTest extends TestCase { | |||
$this->invokePrivate($this->job, 'run', [['uid' => 'validUID']]); | |||
} | |||
public function testNoActiveProvider() { | |||
$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, | |||
'foo' => false, | |||
]); | |||
$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') | |||
@@ -125,7 +153,8 @@ class RememberBackupCodesJobTest extends TestCase { | |||
$this->registry->method('getProviderStates') | |||
->with($user) | |||
->willReturn([ | |||
'backup_codes' => false | |||
'backup_codes' => false, | |||
'foo' => true, | |||
]); | |||
$this->jobList->expects($this->never()) |
@@ -0,0 +1,110 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2019, 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\ProviderDisabled; | |||
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 ProviderDisabledTest extends TestCase { | |||
/** @var IRegistry|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $registy; | |||
/** @var IJobList|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $jobList; | |||
/** @var ProviderDisabled */ | |||
private $listener; | |||
protected function setUp() { | |||
parent::setUp(); | |||
$this->registy = $this->createMock(IRegistry::class); | |||
$this->jobList = $this->createMock(IJobList::class); | |||
$this->listener = new ProviderDisabled($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 testHandleStillActiveProvider() { | |||
$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, | |||
'foo' => true, | |||
]); | |||
$this->jobList->expects($this->never()) | |||
->method($this->anything()); | |||
$this->listener->handle($event); | |||
} | |||
public function testHandleNoActiveProvider() { | |||
$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, | |||
'foo' => false, | |||
]); | |||
$this->jobList->expects($this->once()) | |||
->method('remove') | |||
->with( | |||
$this->equalTo(RememberBackupCodesJob::class), | |||
$this->equalTo(['uid' => 'myUID']) | |||
); | |||
$this->listener->handle($event); | |||
} | |||
} |