nextcloud/tests/lib/User/SessionTest.php

560 lines
17 KiB
PHP
Raw Normal View History

2013-05-29 01:46:57 +04:00
<?php
/**
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace Test\User;
2014-10-13 18:31:26 +04:00
use OC\Session\Memory;
use OC\User\User;
2016-01-04 17:05:28 +03:00
/**
* @group DB
* @package Test\User
*/
class SessionTest extends \Test\TestCase {
2013-05-29 01:46:57 +04:00
2016-05-02 20:58:19 +03:00
/** @var \OCP\AppFramework\Utility\ITimeFactory */
private $timeFactory;
2016-04-28 11:52:28 +03:00
/** @var \OC\Authentication\Token\DefaultTokenProvider */
protected $defaultProvider;
2013-05-29 01:46:57 +04:00
2016-04-28 11:52:28 +03:00
protected function setUp() {
parent::setUp();
2013-05-29 01:46:57 +04:00
2016-05-02 20:58:19 +03:00
$this->timeFactory = $this->getMock('\OCP\AppFramework\Utility\ITimeFactory');
$this->timeFactory->expects($this->any())
->method('getTime')
->will($this->returnValue(10000));
2016-04-28 11:52:28 +03:00
$this->defaultProvider = $this->getMockBuilder('\OC\Authentication\Token\DefaultTokenProvider')
->disableOriginalConstructor()
->getMock();
2013-05-29 01:46:57 +04:00
}
2016-04-28 11:52:28 +03:00
public function testGetUser() {
$token = new \OC\Authentication\Token\DefaultToken();
$expectedUser = new User('foo', null);
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
2016-04-28 11:52:28 +03:00
$session->expects($this->at(0))
->method('get')
->with('user_id')
2016-04-28 11:52:28 +03:00
->will($this->returnValue($expectedUser->getUID()));
2016-05-06 17:31:40 +03:00
$sessionId = 'abcdef12345';
2016-04-28 11:52:28 +03:00
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();
2016-05-06 17:31:40 +03:00
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
2016-04-28 11:52:28 +03:00
$this->defaultProvider->expects($this->once())
->method('getToken')
->will($this->returnValue($token));
2016-05-06 17:31:40 +03:00
$session->expects($this->at(2))
->method('get')
->with('last_login_check')
2016-04-28 11:52:28 +03:00
->will($this->returnValue(null)); // No check has been run yet
$this->defaultProvider->expects($this->once())
->method('getPassword')
2016-05-06 17:31:40 +03:00
->with($token, $sessionId)
2016-04-28 11:52:28 +03:00
->will($this->returnValue('password123'));
$manager->expects($this->once())
->method('checkPassword')
->with($expectedUser->getUID(), 'password123')
->will($this->returnValue(true));
2016-05-06 17:31:40 +03:00
$session->expects($this->at(3))
2016-04-28 11:52:28 +03:00
->method('set')
2016-05-02 20:58:19 +03:00
->with('last_login_check', 10000);
2016-05-06 17:31:40 +03:00
$session->expects($this->at(4))
2016-04-28 11:52:28 +03:00
->method('get')
->with('last_token_update')
->will($this->returnValue(null)); // No check run so far
$this->defaultProvider->expects($this->once())
->method('updateToken')
->with($token);
2016-05-06 17:31:40 +03:00
$session->expects($this->at(5))
2016-04-28 11:52:28 +03:00
->method('set')
2016-05-06 17:31:40 +03:00
->with('last_token_update', $this->equalTo(10000));
2016-04-28 11:52:28 +03:00
$manager->expects($this->any())
->method('get')
->with($expectedUser->getUID())
->will($this->returnValue($expectedUser));
2016-05-17 18:20:54 +03:00
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider);
2016-04-28 11:52:28 +03:00
$user = $userSession->getUser();
$this->assertSame($expectedUser, $user);
2014-12-16 22:01:49 +03:00
}
2016-04-28 11:52:28 +03:00
public function isLoggedInData() {
return [
[true],
[false],
];
}
2014-12-16 22:01:49 +03:00
2016-04-28 11:52:28 +03:00
/**
* @dataProvider isLoggedInData
*/
public function testIsLoggedIn($isLoggedIn) {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
2014-12-16 22:01:49 +03:00
2016-04-28 11:52:28 +03:00
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();
2014-12-16 22:01:49 +03:00
2016-04-28 11:52:28 +03:00
$userSession = $this->getMockBuilder('\OC\User\Session')
2016-05-17 18:20:54 +03:00
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->defaultProvider])
2016-04-28 11:52:28 +03:00
->setMethods([
'getUser'
])
->getMock();
$user = new User('sepp', null);
$userSession->expects($this->once())
->method('getUser')
->will($this->returnValue($isLoggedIn ? $user : null));
$this->assertEquals($isLoggedIn, $userSession->isLoggedIn());
}
2013-05-29 01:46:57 +04:00
public function testSetUser() {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->once())
->method('set')
->with('user_id', 'foo');
$manager = $this->getMock('\OC\User\Manager');
2015-09-22 01:56:36 +03:00
$backend = $this->getMock('\Test\Util\User\Dummy');
2013-05-29 01:46:57 +04:00
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
$user->expects($this->once())
->method('getUID')
->will($this->returnValue('foo'));
2016-05-17 18:20:54 +03:00
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider);
2013-05-29 01:46:57 +04:00
$userSession->setUser($user);
}
public function testLoginValidPasswordEnabled() {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->once())
->method('regenerateId');
2013-12-13 15:56:06 +04:00
$session->expects($this->exactly(2))
2013-05-29 01:46:57 +04:00
->method('set')
2014-10-13 18:31:26 +04:00
->with($this->callback(function ($key) {
switch ($key) {
case 'user_id':
case 'loginname':
return true;
break;
default:
return false;
break;
}
2016-04-28 11:52:28 +03:00
}, 'foo'));
2013-05-29 01:46:57 +04:00
2014-05-23 02:59:26 +04:00
$managerMethods = get_class_methods('\OC\User\Manager');
//keep following methods intact in order to ensure hooks are
//working
$doNotMock = array('__construct', 'emit', 'listen');
2014-10-13 18:31:26 +04:00
foreach ($doNotMock as $methodName) {
2014-05-23 02:59:26 +04:00
$i = array_search($methodName, $managerMethods, true);
2014-10-13 18:31:26 +04:00
if ($i !== false) {
2014-05-23 02:59:26 +04:00
unset($managerMethods[$i]);
}
}
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
2013-05-29 01:46:57 +04:00
2015-09-22 01:56:36 +03:00
$backend = $this->getMock('\Test\Util\User\Dummy');
2013-05-29 01:46:57 +04:00
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
2016-05-06 17:31:40 +03:00
$user->expects($this->any())
2013-05-29 01:46:57 +04:00
->method('isEnabled')
->will($this->returnValue(true));
$user->expects($this->any())
->method('getUID')
->will($this->returnValue('foo'));
2014-05-23 02:59:26 +04:00
$user->expects($this->once())
->method('updateLastLoginTimestamp');
2013-05-29 01:46:57 +04:00
$manager->expects($this->once())
->method('checkPassword')
->with('foo', 'bar')
2013-05-29 01:46:57 +04:00
->will($this->returnValue($user));
2016-04-28 11:52:28 +03:00
$userSession = $this->getMockBuilder('\OC\User\Session')
2016-05-17 18:20:54 +03:00
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->defaultProvider])
2016-04-28 11:52:28 +03:00
->setMethods([
'prepareUserLogin'
])
->getMock();
$userSession->expects($this->once())
->method('prepareUserLogin');
2013-05-29 01:46:57 +04:00
$userSession->login('foo', 'bar');
$this->assertEquals($user, $userSession->getUser());
}
2016-05-06 17:31:40 +03:00
/**
* @expectedException \OC\User\LoginException
*/
2013-05-29 01:46:57 +04:00
public function testLoginValidPasswordDisabled() {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2013-05-29 01:46:57 +04:00
2014-05-23 02:59:26 +04:00
$managerMethods = get_class_methods('\OC\User\Manager');
//keep following methods intact in order to ensure hooks are
//working
$doNotMock = array('__construct', 'emit', 'listen');
2014-10-13 18:31:26 +04:00
foreach ($doNotMock as $methodName) {
2014-05-23 02:59:26 +04:00
$i = array_search($methodName, $managerMethods, true);
2014-10-13 18:31:26 +04:00
if ($i !== false) {
2014-05-23 02:59:26 +04:00
unset($managerMethods[$i]);
}
}
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
2013-05-29 01:46:57 +04:00
2015-09-22 01:56:36 +03:00
$backend = $this->getMock('\Test\Util\User\Dummy');
2013-05-29 01:46:57 +04:00
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
2016-05-06 17:31:40 +03:00
$user->expects($this->any())
2013-05-29 01:46:57 +04:00
->method('isEnabled')
->will($this->returnValue(false));
2014-05-23 02:59:26 +04:00
$user->expects($this->never())
->method('updateLastLoginTimestamp');
2013-05-29 01:46:57 +04:00
$manager->expects($this->once())
->method('checkPassword')
->with('foo', 'bar')
2013-05-29 01:46:57 +04:00
->will($this->returnValue($user));
2016-05-17 18:20:54 +03:00
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider);
2013-05-29 01:46:57 +04:00
$userSession->login('foo', 'bar');
}
public function testLoginInvalidPassword() {
2013-05-29 01:46:57 +04:00
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2013-05-29 01:46:57 +04:00
2014-05-23 02:59:26 +04:00
$managerMethods = get_class_methods('\OC\User\Manager');
//keep following methods intact in order to ensure hooks are
//working
$doNotMock = array('__construct', 'emit', 'listen');
2014-10-13 18:31:26 +04:00
foreach ($doNotMock as $methodName) {
2014-05-23 02:59:26 +04:00
$i = array_search($methodName, $managerMethods, true);
2014-10-13 18:31:26 +04:00
if ($i !== false) {
2014-05-23 02:59:26 +04:00
unset($managerMethods[$i]);
}
}
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
2013-05-29 01:46:57 +04:00
2015-09-22 01:56:36 +03:00
$backend = $this->getMock('\Test\Util\User\Dummy');
2013-05-29 01:46:57 +04:00
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
$user->expects($this->never())
->method('isEnabled');
2014-05-23 02:59:26 +04:00
$user->expects($this->never())
->method('updateLastLoginTimestamp');
2013-05-29 01:46:57 +04:00
$manager->expects($this->once())
->method('checkPassword')
->with('foo', 'bar')
->will($this->returnValue(false));
2013-05-29 01:46:57 +04:00
2016-05-17 18:20:54 +03:00
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider);
2013-05-29 01:46:57 +04:00
$userSession->login('foo', 'bar');
}
public function testLoginNonExisting() {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2013-05-29 01:46:57 +04:00
$manager = $this->getMock('\OC\User\Manager');
2016-04-28 11:52:28 +03:00
$backend = $this->getMock('\Test\Util\User\Dummy');
2013-05-29 01:46:57 +04:00
$manager->expects($this->once())
->method('checkPassword')
->with('foo', 'bar')
->will($this->returnValue(false));
2013-05-29 01:46:57 +04:00
2016-05-17 18:20:54 +03:00
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider);
2013-05-29 01:46:57 +04:00
$userSession->login('foo', 'bar');
}
2014-05-23 02:18:07 +04:00
public function testRememberLoginValidToken() {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->exactly(1))
->method('set')
2014-10-13 18:31:26 +04:00
->with($this->callback(function ($key) {
switch ($key) {
case 'user_id':
return true;
default:
return false;
}
2016-04-28 11:52:28 +03:00
}, 'foo'));
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2014-05-23 02:18:07 +04:00
2014-05-23 02:54:17 +04:00
$managerMethods = get_class_methods('\OC\User\Manager');
//keep following methods intact in order to ensure hooks are
//working
$doNotMock = array('__construct', 'emit', 'listen');
2014-10-13 18:31:26 +04:00
foreach ($doNotMock as $methodName) {
2014-05-23 02:54:17 +04:00
$i = array_search($methodName, $managerMethods, true);
2014-10-13 18:31:26 +04:00
if ($i !== false) {
2014-05-23 02:54:17 +04:00
unset($managerMethods[$i]);
}
}
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
2014-05-23 02:18:07 +04:00
2015-09-22 01:56:36 +03:00
$backend = $this->getMock('\Test\Util\User\Dummy');
2014-05-23 02:18:07 +04:00
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
$user->expects($this->any())
->method('getUID')
->will($this->returnValue('foo'));
2014-05-23 02:54:17 +04:00
$user->expects($this->once())
->method('updateLastLoginTimestamp');
2014-05-23 02:18:07 +04:00
$manager->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($user));
//prepare login token
$token = 'goodToken';
\OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time());
2014-05-23 02:18:07 +04:00
$userSession = $this->getMock(
'\OC\User\Session',
//override, otherwise tests will fail because of setcookie()
array('setMagicInCookie'),
//there are passed as parameters to the constructor
2016-05-17 18:20:54 +03:00
array($manager, $session, $this->timeFactory, $this->defaultProvider));
2014-05-23 02:18:07 +04:00
$granted = $userSession->loginWithCookie('foo', $token);
$this->assertSame($granted, true);
}
public function testRememberLoginInvalidToken() {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2014-05-23 02:18:07 +04:00
2014-05-23 02:54:17 +04:00
$managerMethods = get_class_methods('\OC\User\Manager');
//keep following methods intact in order to ensure hooks are
//working
$doNotMock = array('__construct', 'emit', 'listen');
2014-10-13 18:31:26 +04:00
foreach ($doNotMock as $methodName) {
2014-05-23 02:54:17 +04:00
$i = array_search($methodName, $managerMethods, true);
2014-10-13 18:31:26 +04:00
if ($i !== false) {
2014-05-23 02:54:17 +04:00
unset($managerMethods[$i]);
}
}
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
2014-05-23 02:18:07 +04:00
2015-09-22 01:56:36 +03:00
$backend = $this->getMock('\Test\Util\User\Dummy');
2014-05-23 02:18:07 +04:00
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
$user->expects($this->any())
->method('getUID')
->will($this->returnValue('foo'));
2014-05-23 02:54:17 +04:00
$user->expects($this->never())
->method('updateLastLoginTimestamp');
2014-05-23 02:18:07 +04:00
$manager->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($user));
//prepare login token
$token = 'goodToken';
\OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time());
2014-05-23 02:18:07 +04:00
2016-05-17 18:20:54 +03:00
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider);
2014-05-23 02:18:07 +04:00
$granted = $userSession->loginWithCookie('foo', 'badToken');
$this->assertSame($granted, false);
}
public function testRememberLoginInvalidUser() {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$session->expects($this->never())
->method('set');
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2014-05-23 02:18:07 +04:00
2014-05-23 02:54:17 +04:00
$managerMethods = get_class_methods('\OC\User\Manager');
//keep following methods intact in order to ensure hooks are
//working
$doNotMock = array('__construct', 'emit', 'listen');
2014-10-13 18:31:26 +04:00
foreach ($doNotMock as $methodName) {
2014-05-23 02:54:17 +04:00
$i = array_search($methodName, $managerMethods, true);
2014-10-13 18:31:26 +04:00
if ($i !== false) {
2014-05-23 02:54:17 +04:00
unset($managerMethods[$i]);
}
}
$manager = $this->getMock('\OC\User\Manager', $managerMethods, array());
2014-05-23 02:18:07 +04:00
2015-09-22 01:56:36 +03:00
$backend = $this->getMock('\Test\Util\User\Dummy');
2014-05-23 02:18:07 +04:00
$user = $this->getMock('\OC\User\User', array(), array('foo', $backend));
$user->expects($this->never())
->method('getUID');
2014-05-23 02:54:17 +04:00
$user->expects($this->never())
->method('updateLastLoginTimestamp');
2014-05-23 02:18:07 +04:00
$manager->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue(null));
//prepare login token
$token = 'goodToken';
\OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time());
2014-05-23 02:18:07 +04:00
2016-05-17 18:20:54 +03:00
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider);
2014-05-23 02:18:07 +04:00
$granted = $userSession->loginWithCookie('foo', $token);
$this->assertSame($granted, false);
}
2014-10-13 18:31:26 +04:00
public function testActiveUserAfterSetSession() {
$users = array(
'foo' => new User('foo', null),
'bar' => new User('bar', null)
);
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();
$manager->expects($this->any())
->method('get')
->will($this->returnCallback(function ($uid) use ($users) {
2016-04-28 11:52:28 +03:00
return $users[$uid];
}));
2014-10-13 18:31:26 +04:00
$session = new Memory('');
$session->set('user_id', 'foo');
2016-04-28 11:52:28 +03:00
$userSession = $this->getMockBuilder('\OC\User\Session')
2016-05-17 18:20:54 +03:00
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->defaultProvider])
2016-04-28 11:52:28 +03:00
->setMethods([
'validateSession'
])
->getMock();
$userSession->expects($this->any())
->method('validateSession');
2014-10-13 18:31:26 +04:00
$this->assertEquals($users['foo'], $userSession->getUser());
$session2 = new Memory('');
$session2->set('user_id', 'bar');
$userSession->setSession($session2);
$this->assertEquals($users['bar'], $userSession->getUser());
}
2016-04-28 11:52:28 +03:00
public function testTryTokenLoginWithDisabledUser() {
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();
$session = new Memory('');
$token = $this->getMock('\OC\Authentication\Token\IToken');
$user = $this->getMock('\OCP\IUser');
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider);
$request = $this->getMock('\OCP\IRequest');
$request->expects($this->once())
->method('getHeader')
->with('Authorization')
->will($this->returnValue('token xxxxx'));
$this->defaultProvider->expects($this->once())
->method('validateToken')
->with('xxxxx')
->will($this->returnValue($token));
$token->expects($this->once())
->method('getUID')
->will($this->returnValue('user123'));
$manager->expects($this->once())
->method('get')
->with('user123')
->will($this->returnValue($user));
$user->expects($this->once())
->method('isEnabled')
->will($this->returnValue(false));
$this->assertFalse($userSession->tryTokenLogin($request));
}
public function testValidateSessionDisabledUser() {
$userManager = $this->getMock('\OCP\IUserManager');
$session = $this->getMock('\OCP\ISession');
$timeFactory = $this->getMock('\OCP\AppFramework\Utility\ITimeFactory');
$tokenProvider = $this->getMock('\OC\Authentication\Token\IProvider');
$userSession = $this->getMockBuilder('\OC\User\Session')
->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider])
->setMethods(['logout'])
->getMock();
$user = $this->getMock('\OCP\IUser');
$token = $this->getMock('\OC\Authentication\Token\IToken');
$session->expects($this->once())
->method('getId')
->will($this->returnValue('sessionid'));
$tokenProvider->expects($this->once())
->method('getToken')
->with('sessionid')
->will($this->returnValue($token));
$session->expects($this->once())
->method('get')
->with('last_login_check')
->will($this->returnValue(1000));
$timeFactory->expects($this->once())
->method('getTime')
->will($this->returnValue(5000));
$tokenProvider->expects($this->once())
->method('getPassword')
->with($token, 'sessionid')
->will($this->returnValue('123456'));
$user->expects($this->once())
->method('getUID')
->will($this->returnValue('user5'));
$userManager->expects($this->once())
->method('checkPassword')
->with('user5', '123456')
->will($this->returnValue(true));
$user->expects($this->once())
->method('isEnabled')
->will($this->returnValue(false));
$userSession->expects($this->once())
->method('logout');
$this->invokePrivate($userSession, 'validateSession', [$user]);
}
2013-05-29 01:46:57 +04:00
}