* * @copyright Copyright (c) 2016, ownCloud, Inc. * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * 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, version 3, * along with this program. If not, see * */ namespace Tests\Core\Controller; use OC\Authentication\TwoFactorAuth\Manager; use OC\Core\Controller\LoginController; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; use OCP\IRequest; use OCP\ISession; use OCP\IURLGenerator; use OCP\IUserManager; use OCP\IUserSession; use Test\TestCase; class LoginControllerTest extends TestCase { /** @var LoginController */ private $loginController; /** @var IRequest */ private $request; /** @var IUserManager */ private $userManager; /** @var IConfig */ private $config; /** @var ISession */ private $session; /** @var IUserSession */ private $userSession; /** @var IURLGenerator */ private $urlGenerator; /** @var Manager */ private $twoFactorManager; public function setUp() { parent::setUp(); $this->request = $this->getMock('\\OCP\\IRequest'); $this->userManager = $this->getMock('\\OCP\\IUserManager'); $this->config = $this->getMock('\\OCP\\IConfig'); $this->session = $this->getMock('\\OCP\\ISession'); $this->userSession = $this->getMockBuilder('\\OC\\User\\Session') ->disableOriginalConstructor() ->getMock(); $this->urlGenerator = $this->getMock('\\OCP\\IURLGenerator'); $this->twoFactorManager = $this->getMockBuilder('\OC\Authentication\TwoFactorAuth\Manager') ->disableOriginalConstructor() ->getMock(); $this->loginController = new LoginController( 'core', $this->request, $this->userManager, $this->config, $this->session, $this->userSession, $this->urlGenerator, $this->twoFactorManager ); } public function testLogoutWithoutToken() { $this->request ->expects($this->once()) ->method('getCookie') ->with('oc_token') ->willReturn(null); $this->config ->expects($this->never()) ->method('deleteUserValue'); $this->urlGenerator ->expects($this->once()) ->method('linkToRouteAbsolute') ->with('core.login.showLoginForm') ->willReturn('/login'); $expected = new RedirectResponse('/login'); $this->assertEquals($expected, $this->loginController->logout()); } public function testLogoutWithToken() { $this->request ->expects($this->once()) ->method('getCookie') ->with('oc_token') ->willReturn('MyLoginToken'); $user = $this->getMock('\\OCP\\IUser'); $user ->expects($this->once()) ->method('getUID') ->willReturn('JohnDoe'); $this->userSession ->expects($this->once()) ->method('getUser') ->willReturn($user); $this->config ->expects($this->once()) ->method('deleteUserValue') ->with('JohnDoe', 'login_token', 'MyLoginToken'); $this->urlGenerator ->expects($this->once()) ->method('linkToRouteAbsolute') ->with('core.login.showLoginForm') ->willReturn('/login'); $expected = new RedirectResponse('/login'); $this->assertEquals($expected, $this->loginController->logout()); } public function testShowLoginFormForLoggedInUsers() { $this->userSession ->expects($this->once()) ->method('isLoggedIn') ->willReturn(true); $expectedResponse = new RedirectResponse(\OC_Util::getDefaultPageUrl()); $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '', '')); } public function testShowLoginFormWithErrorsInSession() { $this->userSession ->expects($this->once()) ->method('isLoggedIn') ->willReturn(false); $this->session ->expects($this->once()) ->method('get') ->with('loginMessages') ->willReturn( [ [ 'ErrorArray1', 'ErrorArray2', ], [ 'MessageArray1', 'MessageArray2', ], ] ); $expectedResponse = new TemplateResponse( 'core', 'login', [ 'ErrorArray1' => true, 'ErrorArray2' => true, 'messages' => [ 'MessageArray1', 'MessageArray2', ], 'loginName' => '', 'user_autofocus' => true, 'canResetPassword' => true, 'alt_login' => [], 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(), 'rememberLoginState' => 0, ], 'guest' ); $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '', '')); } /** * @return array */ public function passwordResetDataProvider() { return [ [ true, true, ], [ false, false, ], ]; } /** * @dataProvider passwordResetDataProvider */ public function testShowLoginFormWithPasswordResetOption($canChangePassword, $expectedResult) { $this->userSession ->expects($this->once()) ->method('isLoggedIn') ->willReturn(false); $this->config ->expects($this->once()) ->method('getSystemValue') ->with('lost_password_link') ->willReturn(false); $user = $this->getMock('\\OCP\\IUser'); $user ->expects($this->once()) ->method('canChangePassword') ->willReturn($canChangePassword); $this->userManager ->expects($this->once()) ->method('get') ->with('LdapUser') ->willReturn($user); $expectedResponse = new TemplateResponse( 'core', 'login', [ 'messages' => [], 'loginName' => 'LdapUser', 'user_autofocus' => false, 'canResetPassword' => $expectedResult, 'alt_login' => [], 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(), 'rememberLoginState' => 0, ], 'guest' ); $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('LdapUser', '', '')); } public function testShowLoginFormForUserNamedNull() { $this->userSession ->expects($this->once()) ->method('isLoggedIn') ->willReturn(false); $this->config ->expects($this->once()) ->method('getSystemValue') ->with('lost_password_link') ->willReturn(false); $user = $this->getMock('\\OCP\\IUser'); $user ->expects($this->once()) ->method('canChangePassword') ->willReturn(false); $this->userManager ->expects($this->once()) ->method('get') ->with('0') ->willReturn($user); $expectedResponse = new TemplateResponse( 'core', 'login', [ 'messages' => [], 'loginName' => '0', 'user_autofocus' => false, 'canResetPassword' => false, 'alt_login' => [], 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(), 'rememberLoginState' => 0, ], 'guest' ); $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('0', '', '')); } public function testLoginWithInvalidCredentials() { $user = $this->getMock('\OCP\IUser'); $password = 'secret'; $loginPageUrl = 'some url'; $this->userManager->expects($this->once()) ->method('checkPassword') ->will($this->returnValue(false)); $this->urlGenerator->expects($this->once()) ->method('linkToRoute') ->with('core.login.showLoginForm') ->will($this->returnValue($loginPageUrl)); $this->userSession->expects($this->never()) ->method('createSessionToken'); $expected = new \OCP\AppFramework\Http\RedirectResponse($loginPageUrl); $this->assertEquals($expected, $this->loginController->tryLogin($user, $password, '')); } public function testLoginWithValidCredentials() { $user = $this->getMock('\OCP\IUser'); $password = 'secret'; $indexPageUrl = 'some url'; $this->userManager->expects($this->once()) ->method('checkPassword') ->will($this->returnValue($user)); $this->userSession->expects($this->once()) ->method('createSessionToken') ->with($this->request, $user->getUID(), $password); $this->twoFactorManager->expects($this->once()) ->method('isTwoFactorAuthenticated') ->with($user) ->will($this->returnValue(false)); $this->urlGenerator->expects($this->once()) ->method('linkToRoute') ->with('files.view.index') ->will($this->returnValue($indexPageUrl)); $expected = new \OCP\AppFramework\Http\RedirectResponse($indexPageUrl); $this->assertEquals($expected, $this->loginController->tryLogin($user, $password, null)); } public function testLoginWithValidCredentialsAndRedirectUrl() { $user = $this->getMock('\OCP\IUser'); $user->expects($this->any()) ->method('getUID') ->will($this->returnValue('jane')); $password = 'secret'; $originalUrl = 'another%20url'; $redirectUrl = 'http://localhost/another url'; $this->userManager->expects($this->once()) ->method('checkPassword') ->with('jane', $password) ->will($this->returnValue($user)); $this->userSession->expects($this->once()) ->method('createSessionToken') ->with($this->request, $user->getUID(), $password); $this->userSession->expects($this->once()) ->method('isLoggedIn') ->with() ->will($this->returnValue(true)); $this->urlGenerator->expects($this->once()) ->method('getAbsoluteURL') ->with(urldecode($originalUrl)) ->will($this->returnValue($redirectUrl)); $expected = new \OCP\AppFramework\Http\RedirectResponse(urldecode($redirectUrl)); $this->assertEquals($expected, $this->loginController->tryLogin($user->getUID(), $password, $originalUrl)); } public function testLoginWithTwoFactorEnforced() { $user = $this->getMock('\OCP\IUser'); $password = 'secret'; $challengeUrl = 'challenge/url'; $this->userManager->expects($this->once()) ->method('checkPassword') ->will($this->returnValue($user)); $this->userSession->expects($this->once()) ->method('createSessionToken') ->with($this->request, $user->getUID(), $password); $this->twoFactorManager->expects($this->once()) ->method('isTwoFactorAuthenticated') ->with($user) ->will($this->returnValue(true)); $this->twoFactorManager->expects($this->once()) ->method('prepareTwoFactorLogin') ->with($user); $this->urlGenerator->expects($this->once()) ->method('linkToRoute') ->with('core.TwoFactorChallenge.selectChallenge') ->will($this->returnValue($challengeUrl)); $expected = new \OCP\AppFramework\Http\RedirectResponse($challengeUrl); $this->assertEquals($expected, $this->loginController->tryLogin($user, $password, null)); } }