mirror of
https://github.com/nextcloud/server.git
synced 2026-02-03 20:41:22 -05:00
Otherwise as the tokens were removed from the database but not from the configuration the next time that the tokens were cleared the previous tokens were still got from the configuration, and trying to remove them again from the database ended in a DoesNotExistException being thrown. Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
730 lines
20 KiB
PHP
730 lines
20 KiB
PHP
<?php
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
namespace Test\Authentication\TwoFactorAuth;
|
|
|
|
use OC;
|
|
use OC\Authentication\Token\IProvider as TokenProvider;
|
|
use OC\Authentication\TwoFactorAuth\Manager;
|
|
use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
|
|
use OC\Authentication\TwoFactorAuth\ProviderLoader;
|
|
use OCP\Activity\IEvent;
|
|
use OCP\Activity\IManager;
|
|
use OCP\AppFramework\Utility\ITimeFactory;
|
|
use OCP\Authentication\TwoFactorAuth\IActivatableAtLogin;
|
|
use OCP\Authentication\TwoFactorAuth\IProvider;
|
|
use OCP\Authentication\TwoFactorAuth\IRegistry;
|
|
use OCP\EventDispatcher\IEventDispatcher;
|
|
use OCP\IConfig;
|
|
use OCP\ISession;
|
|
use OCP\IUser;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use Psr\Log\LoggerInterface;
|
|
use Test\TestCase;
|
|
use function reset;
|
|
|
|
class ManagerTest extends TestCase {
|
|
/** @var IUser|MockObject */
|
|
private $user;
|
|
|
|
/** @var ProviderLoader|MockObject */
|
|
private $providerLoader;
|
|
|
|
/** @var IRegistry|MockObject */
|
|
private $providerRegistry;
|
|
|
|
/** @var MandatoryTwoFactor|MockObject */
|
|
private $mandatoryTwoFactor;
|
|
|
|
/** @var ISession|MockObject */
|
|
private $session;
|
|
|
|
/** @var Manager */
|
|
private $manager;
|
|
|
|
/** @var IConfig|MockObject */
|
|
private $config;
|
|
|
|
/** @var IManager|MockObject */
|
|
private $activityManager;
|
|
|
|
/** @var LoggerInterface|MockObject */
|
|
private $logger;
|
|
|
|
/** @var IProvider|MockObject */
|
|
private $fakeProvider;
|
|
|
|
/** @var IProvider|MockObject */
|
|
private $backupProvider;
|
|
|
|
/** @var TokenProvider|MockObject */
|
|
private $tokenProvider;
|
|
|
|
/** @var ITimeFactory|MockObject */
|
|
private $timeFactory;
|
|
|
|
/** @var IEventDispatcher|MockObject */
|
|
private $dispatcher;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
$this->user = $this->createMock(IUser::class);
|
|
$this->providerLoader = $this->createMock(ProviderLoader::class);
|
|
$this->providerRegistry = $this->createMock(IRegistry::class);
|
|
$this->mandatoryTwoFactor = $this->createMock(MandatoryTwoFactor::class);
|
|
$this->session = $this->createMock(ISession::class);
|
|
$this->config = $this->createMock(IConfig::class);
|
|
$this->activityManager = $this->createMock(IManager::class);
|
|
$this->logger = $this->createMock(LoggerInterface::class);
|
|
$this->tokenProvider = $this->createMock(TokenProvider::class);
|
|
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
|
$this->dispatcher = $this->createMock(IEventDispatcher::class);
|
|
|
|
$this->manager = new Manager(
|
|
$this->providerLoader,
|
|
$this->providerRegistry,
|
|
$this->mandatoryTwoFactor,
|
|
$this->session,
|
|
$this->config,
|
|
$this->activityManager,
|
|
$this->logger,
|
|
$this->tokenProvider,
|
|
$this->timeFactory,
|
|
$this->dispatcher,
|
|
);
|
|
|
|
$this->fakeProvider = $this->createMock(IProvider::class);
|
|
$this->fakeProvider->method('getId')->willReturn('email');
|
|
|
|
$this->backupProvider = $this->getMockBuilder('\OCP\Authentication\TwoFactorAuth\IProvider')->getMock();
|
|
$this->backupProvider->method('getId')->willReturn('backup_codes');
|
|
$this->backupProvider->method('isTwoFactorAuthEnabledForUser')->willReturn(true);
|
|
}
|
|
|
|
private function prepareNoProviders() {
|
|
$this->providerLoader->method('getProviders')
|
|
->with($this->user)
|
|
->willReturn([]);
|
|
}
|
|
|
|
private function prepareProviders() {
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->with($this->user)
|
|
->willReturn([
|
|
$this->fakeProvider->getId() => true,
|
|
]);
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->with($this->user)
|
|
->willReturn([$this->fakeProvider]);
|
|
}
|
|
|
|
private function prepareProvidersWitBackupProvider() {
|
|
$this->providerLoader->method('getProviders')
|
|
->with($this->user)
|
|
->willReturn([
|
|
$this->fakeProvider,
|
|
$this->backupProvider,
|
|
]);
|
|
}
|
|
|
|
public function testIsTwoFactorAuthenticatedEnforced() {
|
|
$this->mandatoryTwoFactor->expects($this->once())
|
|
->method('isEnforcedFor')
|
|
->with($this->user)
|
|
->willReturn(true);
|
|
|
|
$enabled = $this->manager->isTwoFactorAuthenticated($this->user);
|
|
|
|
$this->assertTrue($enabled);
|
|
}
|
|
|
|
public function testIsTwoFactorAuthenticatedNoProviders() {
|
|
$this->mandatoryTwoFactor->expects($this->once())
|
|
->method('isEnforcedFor')
|
|
->with($this->user)
|
|
->willReturn(false);
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->willReturn([]); // No providers registered
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->willReturn([]); // No providers loadable
|
|
|
|
$this->assertFalse($this->manager->isTwoFactorAuthenticated($this->user));
|
|
}
|
|
|
|
public function testIsTwoFactorAuthenticatedOnlyBackupCodes() {
|
|
$this->mandatoryTwoFactor->expects($this->once())
|
|
->method('isEnforcedFor')
|
|
->with($this->user)
|
|
->willReturn(false);
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->willReturn([
|
|
'backup_codes' => true,
|
|
]);
|
|
$backupCodesProvider = $this->createMock(IProvider::class);
|
|
$backupCodesProvider
|
|
->method('getId')
|
|
->willReturn('backup_codes');
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->willReturn([
|
|
$backupCodesProvider,
|
|
]);
|
|
|
|
$this->assertFalse($this->manager->isTwoFactorAuthenticated($this->user));
|
|
}
|
|
|
|
public function testIsTwoFactorAuthenticatedFailingProviders() {
|
|
$this->mandatoryTwoFactor->expects($this->once())
|
|
->method('isEnforcedFor')
|
|
->with($this->user)
|
|
->willReturn(false);
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->willReturn([
|
|
'twofactor_totp' => true,
|
|
'twofactor_u2f' => false,
|
|
]); // Two providers registered, but …
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->willReturn([]); // … none of them is able to load, however …
|
|
|
|
// … 2FA is still enforced
|
|
$this->assertTrue($this->manager->isTwoFactorAuthenticated($this->user));
|
|
}
|
|
|
|
public function providerStatesFixData(): array {
|
|
return [
|
|
[false, false],
|
|
[true, true],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* If the 2FA registry has not been populated when a user logs in,
|
|
* the 2FA manager has to first fix the state before it checks for
|
|
* enabled providers.
|
|
*
|
|
* If any of these providers is active, 2FA is enabled
|
|
*
|
|
* @dataProvider providerStatesFixData
|
|
*/
|
|
public function testIsTwoFactorAuthenticatedFixesProviderStates(bool $providerEnabled, bool $expected) {
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->willReturn([]); // Nothing registered yet
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->willReturn([
|
|
$this->fakeProvider
|
|
]);
|
|
$this->fakeProvider->expects($this->once())
|
|
->method('isTwoFactorAuthEnabledForUser')
|
|
->with($this->user)
|
|
->willReturn($providerEnabled);
|
|
if ($providerEnabled) {
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('enableProviderFor')
|
|
->with(
|
|
$this->fakeProvider,
|
|
$this->user
|
|
);
|
|
} else {
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('disableProviderFor')
|
|
->with(
|
|
$this->fakeProvider,
|
|
$this->user
|
|
);
|
|
}
|
|
|
|
$this->assertEquals($expected, $this->manager->isTwoFactorAuthenticated($this->user));
|
|
}
|
|
|
|
public function testGetProvider() {
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->with($this->user)
|
|
->willReturn([
|
|
$this->fakeProvider->getId() => true,
|
|
]);
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->with($this->user)
|
|
->willReturn([$this->fakeProvider]);
|
|
|
|
$provider = $this->manager->getProvider($this->user, $this->fakeProvider->getId());
|
|
|
|
$this->assertSame($this->fakeProvider, $provider);
|
|
}
|
|
|
|
public function testGetInvalidProvider() {
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->with($this->user)
|
|
->willReturn([]);
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->with($this->user)
|
|
->willReturn([]);
|
|
|
|
$provider = $this->manager->getProvider($this->user, 'nonexistent');
|
|
|
|
$this->assertNull($provider);
|
|
}
|
|
|
|
public function testGetLoginSetupProviders() {
|
|
$provider1 = $this->createMock(IProvider::class);
|
|
$provider2 = $this->createMock(IActivatableAtLogin::class);
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->with($this->user)
|
|
->willReturn([
|
|
$provider1,
|
|
$provider2,
|
|
]);
|
|
|
|
$providers = $this->manager->getLoginSetupProviders($this->user);
|
|
|
|
$this->assertCount(1, $providers);
|
|
$this->assertSame($provider2, reset($providers));
|
|
}
|
|
|
|
public function testGetProviders() {
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->with($this->user)
|
|
->willReturn([
|
|
$this->fakeProvider->getId() => true,
|
|
]);
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->with($this->user)
|
|
->willReturn([$this->fakeProvider]);
|
|
$expectedProviders = [
|
|
'email' => $this->fakeProvider,
|
|
];
|
|
|
|
$providerSet = $this->manager->getProviderSet($this->user);
|
|
$providers = $providerSet->getProviders();
|
|
|
|
$this->assertEquals($expectedProviders, $providers);
|
|
$this->assertFalse($providerSet->isProviderMissing());
|
|
}
|
|
|
|
public function testGetProvidersOneMissing() {
|
|
$this->providerRegistry->expects($this->once())
|
|
->method('getProviderStates')
|
|
->with($this->user)
|
|
->willReturn([
|
|
$this->fakeProvider->getId() => true,
|
|
]);
|
|
$this->providerLoader->expects($this->once())
|
|
->method('getProviders')
|
|
->with($this->user)
|
|
->willReturn([]);
|
|
$expectedProviders = [
|
|
'email' => $this->fakeProvider,
|
|
];
|
|
|
|
$providerSet = $this->manager->getProviderSet($this->user);
|
|
|
|
$this->assertTrue($providerSet->isProviderMissing());
|
|
}
|
|
|
|
public function testVerifyChallenge() {
|
|
$this->prepareProviders();
|
|
|
|
$challenge = 'passme';
|
|
$event = $this->createMock(IEvent::class);
|
|
$this->fakeProvider->expects($this->once())
|
|
->method('verifyChallenge')
|
|
->with($this->user, $challenge)
|
|
->willReturn(true);
|
|
$this->session->expects($this->once())
|
|
->method('get')
|
|
->with('two_factor_remember_login')
|
|
->willReturn(false);
|
|
$this->session->expects($this->exactly(2))
|
|
->method('remove')
|
|
->withConsecutive(
|
|
['two_factor_auth_uid'],
|
|
['two_factor_remember_login']
|
|
);
|
|
$this->session->expects($this->once())
|
|
->method('set')
|
|
->with(Manager::SESSION_UID_DONE, 'jos');
|
|
$this->session->method('getId')
|
|
->willReturn('mysessionid');
|
|
$this->activityManager->expects($this->once())
|
|
->method('generateEvent')
|
|
->willReturn($event);
|
|
$this->user->expects($this->any())
|
|
->method('getUID')
|
|
->willReturn('jos');
|
|
$event->expects($this->once())
|
|
->method('setApp')
|
|
->with($this->equalTo('core'))
|
|
->willReturnSelf();
|
|
$event->expects($this->once())
|
|
->method('setType')
|
|
->with($this->equalTo('security'))
|
|
->willReturnSelf();
|
|
$event->expects($this->once())
|
|
->method('setAuthor')
|
|
->with($this->equalTo('jos'))
|
|
->willReturnSelf();
|
|
$event->expects($this->once())
|
|
->method('setAffectedUser')
|
|
->with($this->equalTo('jos'))
|
|
->willReturnSelf();
|
|
$this->fakeProvider
|
|
->method('getDisplayName')
|
|
->willReturn('Fake 2FA');
|
|
$event->expects($this->once())
|
|
->method('setSubject')
|
|
->with($this->equalTo('twofactor_success'), $this->equalTo([
|
|
'provider' => 'Fake 2FA',
|
|
]))
|
|
->willReturnSelf();
|
|
$token = $this->createMock(OC\Authentication\Token\IToken::class);
|
|
$this->tokenProvider->method('getToken')
|
|
->with('mysessionid')
|
|
->willReturn($token);
|
|
$token->method('getId')
|
|
->willReturn(42);
|
|
$this->config->expects($this->once())
|
|
->method('deleteUserValue')
|
|
->with('jos', 'login_token_2fa', '42');
|
|
|
|
$result = $this->manager->verifyChallenge('email', $this->user, $challenge);
|
|
|
|
$this->assertTrue($result);
|
|
}
|
|
|
|
public function testVerifyChallengeInvalidProviderId() {
|
|
$this->prepareProviders();
|
|
|
|
$challenge = 'passme';
|
|
$this->fakeProvider->expects($this->never())
|
|
->method('verifyChallenge')
|
|
->with($this->user, $challenge);
|
|
$this->session->expects($this->never())
|
|
->method('remove');
|
|
|
|
$this->assertFalse($this->manager->verifyChallenge('dontexist', $this->user, $challenge));
|
|
}
|
|
|
|
public function testVerifyInvalidChallenge() {
|
|
$this->prepareProviders();
|
|
|
|
$challenge = 'dontpassme';
|
|
$event = $this->createMock(IEvent::class);
|
|
$this->fakeProvider->expects($this->once())
|
|
->method('verifyChallenge')
|
|
->with($this->user, $challenge)
|
|
->willReturn(false);
|
|
$this->session->expects($this->never())
|
|
->method('remove');
|
|
$this->activityManager->expects($this->once())
|
|
->method('generateEvent')
|
|
->willReturn($event);
|
|
$this->user->expects($this->any())
|
|
->method('getUID')
|
|
->willReturn('jos');
|
|
$event->expects($this->once())
|
|
->method('setApp')
|
|
->with($this->equalTo('core'))
|
|
->willReturnSelf();
|
|
$event->expects($this->once())
|
|
->method('setType')
|
|
->with($this->equalTo('security'))
|
|
->willReturnSelf();
|
|
$event->expects($this->once())
|
|
->method('setAuthor')
|
|
->with($this->equalTo('jos'))
|
|
->willReturnSelf();
|
|
$event->expects($this->once())
|
|
->method('setAffectedUser')
|
|
->with($this->equalTo('jos'))
|
|
->willReturnSelf();
|
|
$this->fakeProvider
|
|
->method('getDisplayName')
|
|
->willReturn('Fake 2FA');
|
|
$event->expects($this->once())
|
|
->method('setSubject')
|
|
->with($this->equalTo('twofactor_failed'), $this->equalTo([
|
|
'provider' => 'Fake 2FA',
|
|
]))
|
|
->willReturnSelf();
|
|
|
|
$this->assertFalse($this->manager->verifyChallenge('email', $this->user, $challenge));
|
|
}
|
|
|
|
public function testNeedsSecondFactor() {
|
|
$user = $this->createMock(IUser::class);
|
|
$this->session->expects($this->exactly(3))
|
|
->method('exists')
|
|
->withConsecutive(
|
|
['app_password'],
|
|
['two_factor_auth_uid'],
|
|
[Manager::SESSION_UID_DONE],
|
|
)
|
|
->willReturn(false);
|
|
|
|
$this->session->method('getId')
|
|
->willReturn('mysessionid');
|
|
$token = $this->createMock(OC\Authentication\Token\IToken::class);
|
|
$this->tokenProvider->method('getToken')
|
|
->with('mysessionid')
|
|
->willReturn($token);
|
|
$token->method('getId')
|
|
->willReturn(42);
|
|
|
|
$user->method('getUID')
|
|
->willReturn('user');
|
|
$this->config->method('getUserKeys')
|
|
->with('user', 'login_token_2fa')
|
|
->willReturn([
|
|
'42'
|
|
]);
|
|
|
|
$manager = $this->getMockBuilder(Manager::class)
|
|
->setConstructorArgs([
|
|
$this->providerLoader,
|
|
$this->providerRegistry,
|
|
$this->mandatoryTwoFactor,
|
|
$this->session,
|
|
$this->config,
|
|
$this->activityManager,
|
|
$this->logger,
|
|
$this->tokenProvider,
|
|
$this->timeFactory,
|
|
$this->dispatcher,
|
|
])
|
|
->setMethods(['loadTwoFactorApp', 'isTwoFactorAuthenticated'])// Do not actually load the apps
|
|
->getMock();
|
|
|
|
$manager->method('isTwoFactorAuthenticated')
|
|
->with($user)
|
|
->willReturn(true);
|
|
|
|
$this->assertTrue($manager->needsSecondFactor($user));
|
|
}
|
|
|
|
public function testNeedsSecondFactorUserIsNull() {
|
|
$user = null;
|
|
$this->session->expects($this->never())
|
|
->method('exists');
|
|
|
|
$this->assertFalse($this->manager->needsSecondFactor($user));
|
|
}
|
|
|
|
public function testNeedsSecondFactorWithNoProviderAvailableAnymore() {
|
|
$this->prepareNoProviders();
|
|
|
|
$user = null;
|
|
$this->session->expects($this->never())
|
|
->method('exists')
|
|
->with('two_factor_auth_uid')
|
|
->willReturn(true);
|
|
$this->session->expects($this->never())
|
|
->method('remove')
|
|
->with('two_factor_auth_uid');
|
|
|
|
$this->assertFalse($this->manager->needsSecondFactor($user));
|
|
}
|
|
|
|
public function testPrepareTwoFactorLogin() {
|
|
$this->user->method('getUID')
|
|
->willReturn('ferdinand');
|
|
|
|
$this->session->expects($this->exactly(2))
|
|
->method('set')
|
|
->withConsecutive(
|
|
['two_factor_auth_uid', 'ferdinand'],
|
|
['two_factor_remember_login', true]
|
|
);
|
|
|
|
$this->session->method('getId')
|
|
->willReturn('mysessionid');
|
|
$token = $this->createMock(OC\Authentication\Token\IToken::class);
|
|
$this->tokenProvider->method('getToken')
|
|
->with('mysessionid')
|
|
->willReturn($token);
|
|
$token->method('getId')
|
|
->willReturn(42);
|
|
|
|
$this->timeFactory->method('getTime')
|
|
->willReturn(1337);
|
|
|
|
$this->config->method('setUserValue')
|
|
->with('ferdinand', 'login_token_2fa', '42', '1337');
|
|
|
|
|
|
$this->manager->prepareTwoFactorLogin($this->user, true);
|
|
}
|
|
|
|
public function testPrepareTwoFactorLoginDontRemember() {
|
|
$this->user->method('getUID')
|
|
->willReturn('ferdinand');
|
|
|
|
$this->session->expects($this->exactly(2))
|
|
->method('set')
|
|
->withConsecutive(
|
|
['two_factor_auth_uid', 'ferdinand'],
|
|
['two_factor_remember_login', false]
|
|
);
|
|
|
|
$this->session->method('getId')
|
|
->willReturn('mysessionid');
|
|
$token = $this->createMock(OC\Authentication\Token\IToken::class);
|
|
$this->tokenProvider->method('getToken')
|
|
->with('mysessionid')
|
|
->willReturn($token);
|
|
$token->method('getId')
|
|
->willReturn(42);
|
|
|
|
$this->timeFactory->method('getTime')
|
|
->willReturn(1337);
|
|
|
|
$this->config->method('setUserValue')
|
|
->with('ferdinand', 'login_token_2fa', '42', '1337');
|
|
|
|
$this->manager->prepareTwoFactorLogin($this->user, false);
|
|
}
|
|
|
|
public function testNeedsSecondFactorSessionAuth() {
|
|
$user = $this->createMock(IUser::class);
|
|
$user->method('getUID')
|
|
->willReturn('user');
|
|
|
|
$this->session->method('exists')
|
|
->willReturnCallback(function ($var) {
|
|
if ($var === Manager::SESSION_UID_KEY) {
|
|
return false;
|
|
} elseif ($var === 'app_password') {
|
|
return false;
|
|
} elseif ($var === 'app_api') {
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
$this->session->method('get')
|
|
->willReturnCallback(function ($var) {
|
|
if ($var === Manager::SESSION_UID_KEY) {
|
|
return 'user';
|
|
} elseif ($var === 'app_api') {
|
|
return true;
|
|
}
|
|
return null;
|
|
});
|
|
$this->session->expects($this->once())
|
|
->method('get')
|
|
->willReturnMap([
|
|
[Manager::SESSION_UID_DONE, 'user'],
|
|
['app_api', true]
|
|
]);
|
|
|
|
$this->assertFalse($this->manager->needsSecondFactor($user));
|
|
}
|
|
|
|
public function testNeedsSecondFactorSessionAuthFailDBPass() {
|
|
$user = $this->createMock(IUser::class);
|
|
$user->method('getUID')
|
|
->willReturn('user');
|
|
|
|
$this->session->method('exists')
|
|
->willReturn(false);
|
|
$this->session->method('getId')
|
|
->willReturn('mysessionid');
|
|
|
|
$token = $this->createMock(OC\Authentication\Token\IToken::class);
|
|
$token->method('getId')
|
|
->willReturn(40);
|
|
|
|
$this->tokenProvider->method('getToken')
|
|
->with('mysessionid')
|
|
->willReturn($token);
|
|
|
|
$this->config->method('getUserKeys')
|
|
->with('user', 'login_token_2fa')
|
|
->willReturn([
|
|
'42', '43', '44'
|
|
]);
|
|
|
|
$this->session->expects($this->once())
|
|
->method('set')
|
|
->with(Manager::SESSION_UID_DONE, 'user');
|
|
|
|
$this->assertFalse($this->manager->needsSecondFactor($user));
|
|
}
|
|
|
|
public function testNeedsSecondFactorInvalidToken() {
|
|
$this->prepareNoProviders();
|
|
|
|
$user = $this->createMock(IUser::class);
|
|
$user->method('getUID')
|
|
->willReturn('user');
|
|
|
|
$this->session->method('exists')
|
|
->willReturn(false);
|
|
$this->session->method('getId')
|
|
->willReturn('mysessionid');
|
|
|
|
$this->tokenProvider->method('getToken')
|
|
->with('mysessionid')
|
|
->willThrowException(new OC\Authentication\Exceptions\InvalidTokenException());
|
|
|
|
$this->config->method('getUserKeys')->willReturn([]);
|
|
|
|
$this->assertFalse($this->manager->needsSecondFactor($user));
|
|
}
|
|
|
|
public function testNeedsSecondFactorAppPassword() {
|
|
$user = $this->createMock(IUser::class);
|
|
$this->session->method('exists')
|
|
->willReturnMap([
|
|
['app_password', true],
|
|
['app_api', true]
|
|
]);
|
|
|
|
$this->assertFalse($this->manager->needsSecondFactor($user));
|
|
}
|
|
|
|
public function testClearTwoFactorPending() {
|
|
$this->config->method('getUserKeys')
|
|
->with('theUserId', 'login_token_2fa')
|
|
->willReturn([
|
|
'42', '43', '44'
|
|
]);
|
|
|
|
$this->config->expects($this->exactly(3))
|
|
->method('deleteUserValue')
|
|
->withConsecutive(
|
|
['theUserId', 'login_token_2fa', '42'],
|
|
['theUserId', 'login_token_2fa', '43'],
|
|
['theUserId', 'login_token_2fa', '44'],
|
|
);
|
|
|
|
$this->tokenProvider->expects($this->exactly(3))
|
|
->method('invalidateTokenById')
|
|
->withConsecutive(
|
|
['theUserId', 42],
|
|
['theUserId', 43],
|
|
['theUserId', 44],
|
|
);
|
|
|
|
$this->manager->clearTwoFactorPending('theUserId');
|
|
}
|
|
}
|