Skip to content

Commit

Permalink
Merge pull request #1169 from nextcloud/2fa-single-provider
Browse files Browse the repository at this point in the history
redirect to 2fa provider if there's only one active for the user
  • Loading branch information
LukasReschke authored Aug 29, 2016
2 parents 9ebc58c + 291dd0b commit 1702abc
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 5 deletions.
22 changes: 18 additions & 4 deletions core/Controller/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,26 @@ public function tryLogin($user, $password, $redirect_url) {

if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) {
$this->twoFactorManager->prepareTwoFactorLogin($loginResult);

$providers = $this->twoFactorManager->getProviders($loginResult);
if (count($providers) === 1) {
// Single provider, hence we can redirect to that provider's challenge page directly
/* @var $provider IProvider */
$provider = array_pop($providers);
$url = 'core.TwoFactorChallenge.showChallenge';
$urlParams = [
'challengeProviderId' => $provider->getId(),
];
} else {
$url = 'core.TwoFactorChallenge.selectChallenge';
$urlParams = [];
}

if (!is_null($redirect_url)) {
return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge', [
'redirect_url' => $redirect_url
]));
$urlParams['redirect_url'] = $redirect_url;
}
return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));

return new RedirectResponse($this->urlGenerator->linkToRoute($url, $urlParams));
}

return $this->generateRedirect($redirect_url);
Expand Down
76 changes: 75 additions & 1 deletion tests/Core/Controller/LoginControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -505,14 +505,15 @@ public function testLoginWithValidCredentialsAndRedirectUrl() {
$this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl));
}

public function testLoginWithTwoFactorEnforced() {
public function testLoginWithOneTwoFactorProvider() {
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->getMockBuilder('\OCP\IUser')->getMock();
$user->expects($this->any())
->method('getUID')
->will($this->returnValue('john'));
$password = 'secret';
$challengeUrl = 'challenge/url';
$provider = $this->getMockBuilder('\OCP\Authentication\TwoFactorAuth\IProvider')->getMock();

$this->request
->expects($this->exactly(2))
Expand Down Expand Up @@ -547,6 +548,79 @@ public function testLoginWithTwoFactorEnforced() {
$this->twoFactorManager->expects($this->once())
->method('prepareTwoFactorLogin')
->with($user);
$this->twoFactorManager->expects($this->once())
->method('getProviders')
->with($user)
->will($this->returnValue([$provider]));
$provider->expects($this->once())
->method('getId')
->will($this->returnValue('u2f'));
$this->urlGenerator->expects($this->once())
->method('linkToRoute')
->with('core.TwoFactorChallenge.showChallenge', [
'challengeProviderId' => 'u2f',
])
->will($this->returnValue($challengeUrl));
$this->config->expects($this->once())
->method('deleteUserValue')
->with('john', 'core', 'lostpassword');

$expected = new RedirectResponse($challengeUrl);
$this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', $password, null));
}

public function testLoginWithMultpleTwoFactorProviders() {
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->getMockBuilder('\OCP\IUser')->getMock();
$user->expects($this->any())
->method('getUID')
->will($this->returnValue('john'));
$password = 'secret';
$challengeUrl = 'challenge/url';
$provider1 = $this->getMockBuilder('\OCP\Authentication\TwoFactorAuth\IProvider')->getMock();
$provider2 = $this->getMockBuilder('\OCP\Authentication\TwoFactorAuth\IProvider')->getMock();

$this->request
->expects($this->exactly(2))
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->request
->expects($this->once())
->method('passesCSRFCheck')
->willReturn(true);
$this->throttler
->expects($this->once())
->method('sleepDelay')
->with('192.168.0.1');
$this->throttler
->expects($this->once())
->method('getDelay')
->with('192.168.0.1')
->willReturn(200);
$this->userManager->expects($this->once())
->method('checkPassword')
->will($this->returnValue($user));
$this->userSession->expects($this->once())
->method('login')
->with('john@doe.com', $password);
$this->userSession->expects($this->once())
->method('createSessionToken')
->with($this->request, $user->getUID(), 'john@doe.com', $password);
$this->twoFactorManager->expects($this->once())
->method('isTwoFactorAuthenticated')
->with($user)
->will($this->returnValue(true));
$this->twoFactorManager->expects($this->once())
->method('prepareTwoFactorLogin')
->with($user);
$this->twoFactorManager->expects($this->once())
->method('getProviders')
->with($user)
->will($this->returnValue([$provider1, $provider2]));
$provider1->expects($this->never())
->method('getId');
$provider2->expects($this->never())
->method('getId');
$this->urlGenerator->expects($this->once())
->method('linkToRoute')
->with('core.TwoFactorChallenge.selectChallenge')
Expand Down

0 comments on commit 1702abc

Please sign in to comment.