nextcloud/tests/lib/User/SessionTest.php

1223 lines
41 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;
use OC\Authentication\Token\DefaultTokenMapper;
use OC\Authentication\Token\DefaultTokenProvider;
2016-09-12 22:53:21 +03:00
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken;
use OC\Security\Bruteforce\Throttler;
2014-10-13 18:31:26 +04:00
use OC\Session\Memory;
2016-09-12 22:53:21 +03:00
use OC\User\Manager;
use OC\User\Session;
2014-10-13 18:31:26 +04:00
use OC\User\User;
2016-09-12 22:53:21 +03:00
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IConfig;
use OCP\ILogger;
2016-09-12 22:53:21 +03:00
use OCP\IRequest;
use OCP\ISession;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Security\ICrypto;
2016-09-12 22:53:21 +03:00
use OCP\Security\ISecureRandom;
2014-10-13 18:31:26 +04:00
2016-01-04 17:05:28 +03:00
/**
* @group DB
* @package Test\User
*/
class SessionTest extends \Test\TestCase {
/** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
2016-05-02 20:58:19 +03:00
private $timeFactory;
/** @var DefaultTokenProvider|\PHPUnit_Framework_MockObject_MockObject */
protected $tokenProvider;
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config;
/** @var Throttler|\PHPUnit_Framework_MockObject_MockObject */
private $throttler;
/** @var ISecureRandom|\PHPUnit_Framework_MockObject_MockObject */
private $random;
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
private $manager;
/** @var ISession|\PHPUnit_Framework_MockObject_MockObject */
private $session;
/** @var Session|\PHPUnit_Framework_MockObject_MockObject */
private $userSession;
2016-04-28 11:52:28 +03:00
protected function setUp() {
parent::setUp();
2013-05-29 01:46:57 +04:00
2016-09-12 22:53:21 +03:00
$this->timeFactory = $this->createMock(ITimeFactory::class);
2016-05-02 20:58:19 +03:00
$this->timeFactory->expects($this->any())
->method('getTime')
->will($this->returnValue(10000));
2016-09-12 22:53:21 +03:00
$this->tokenProvider = $this->createMock(IProvider::class);
$this->config = $this->createMock(IConfig::class);
$this->throttler = $this->createMock(Throttler::class);
$this->random = $this->createMock(ISecureRandom::class);
$this->manager = $this->createMock(IUserManager::class);
$this->session = $this->createMock(ISession::class);
$this->userSession = $this->getMockBuilder(Session::class)
->setConstructorArgs([
$this->manager,
$this->session,
$this->timeFactory,
$this->tokenProvider,
$this->config,
$this->random,
])
->setMethods([
'setMagicInCookie',
])
->getMock();
\OC_User::setIncognitoMode(false);
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();
$token->setLoginName('User123');
2016-06-20 10:10:11 +03:00
$token->setLastCheck(200);
2016-04-28 11:52:28 +03:00
2016-09-12 22:53:21 +03:00
$expectedUser = $this->createMock(IUser::class);
$expectedUser->expects($this->any())
->method('getUID')
->will($this->returnValue('user123'));
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
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-06-20 10:10:11 +03:00
$session->expects($this->at(1))
->method('get')
->with('app_password')
->will($this->returnValue(null)); // No password set -> browser session
2016-05-06 17:31:40 +03:00
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
$this->tokenProvider->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('getToken')
2016-06-20 10:10:11 +03:00
->with($sessionId)
2016-04-28 11:52:28 +03:00
->will($this->returnValue($token));
$this->tokenProvider->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('getPassword')
2016-05-06 17:31:40 +03:00
->with($token, $sessionId)
2016-06-20 10:10:11 +03:00
->will($this->returnValue('passme'));
2016-04-28 11:52:28 +03:00
$manager->expects($this->once())
->method('checkPassword')
2016-06-20 10:10:11 +03:00
->with('User123', 'passme')
->will($this->returnValue(true));
$expectedUser->expects($this->once())
->method('isEnabled')
->will($this->returnValue(true));
$this->tokenProvider->expects($this->once())
2016-06-20 10:10:11 +03:00
->method('updateTokenActivity')
2016-04-28 11:52:28 +03:00
->with($token);
$manager->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('get')
->with($expectedUser->getUID())
->will($this->returnValue($expectedUser));
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
2016-04-28 11:52:28 +03:00
$user = $userSession->getUser();
$this->assertSame($expectedUser, $user);
2016-06-20 10:10:11 +03:00
$this->assertSame(10000, $token->getLastCheck());
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) {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
2014-12-16 22:01:49 +03:00
$manager = $this->createMock(Manager::class);
2014-12-16 22:01:49 +03:00
$userSession = $this->getMockBuilder(Session::class)
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
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() {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
2013-05-29 01:46:57 +04:00
$session->expects($this->once())
->method('set')
->with('user_id', 'foo');
2016-09-12 22:53:21 +03:00
$manager = $this->createMock(Manager::class);
2013-05-29 01:46:57 +04:00
2016-09-12 22:53:21 +03:00
$backend = $this->createMock(\Test\Util\User\Dummy::class);
2013-05-29 01:46:57 +04:00
2016-09-12 22:53:21 +03:00
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock();
2013-05-29 01:46:57 +04:00
$user->expects($this->once())
->method('getUID')
->will($this->returnValue('foo'));
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
2013-05-29 01:46:57 +04:00
$userSession->setUser($user);
}
public function testLoginValidPasswordEnabled() {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$session->expects($this->once())
->method('regenerateId');
2016-06-20 10:10:11 +03:00
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('bar')
2016-06-20 11:41:23 +03:00
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
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;
}
}, 'foo'));
2013-05-29 01:46:57 +04:00
$managerMethods = get_class_methods(Manager::class);
//keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->getMock();
2013-05-29 01:46:57 +04:00
2016-09-12 22:53:21 +03:00
$backend = $this->createMock(\Test\Util\User\Dummy::class);
2013-05-29 01:46:57 +04:00
2016-09-12 22:53:21 +03:00
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock();
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));
$userSession = $this->getMockBuilder(Session::class)
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
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() {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
2013-05-29 01:46:57 +04:00
$session->expects($this->never())
->method('set');
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2016-06-20 10:10:11 +03:00
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('bar')
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
2013-05-29 01:46:57 +04:00
$managerMethods = get_class_methods(\OC\User\Manager::class);
//keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->getMock();
2013-05-29 01:46:57 +04:00
2016-09-12 22:53:21 +03:00
$backend = $this->createMock(\Test\Util\User\Dummy::class);
2013-05-29 01:46:57 +04:00
2016-09-12 22:53:21 +03:00
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock();
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));
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
2013-05-29 01:46:57 +04:00
$userSession->login('foo', 'bar');
}
public function testLoginInvalidPassword() {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$managerMethods = get_class_methods(\OC\User\Manager::class);
//keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->getMock();
2016-09-12 22:53:21 +03:00
$backend = $this->createMock(\Test\Util\User\Dummy::class);
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
2013-05-29 01:46:57 +04:00
2016-09-12 22:53:21 +03:00
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock();
2016-06-20 10:10:11 +03:00
$session->expects($this->never())
->method('set');
$session->expects($this->once())
->method('regenerateId');
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('bar')
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
2013-05-29 01:46:57 +04:00
$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
$userSession->login('foo', 'bar');
}
public function testLoginNonExisting() {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$manager = $this->createMock(Manager::class);
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
2016-06-20 10:10:11 +03:00
2013-05-29 01:46:57 +04:00
$session->expects($this->never())
->method('set');
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2016-06-20 10:10:11 +03:00
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('bar')
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
2016-04-28 11:52:28 +03:00
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
$userSession->login('foo', 'bar');
}
2014-05-23 02:18:07 +04:00
/**
* When using a device token, the loginname must match the one that was used
* when generating the token on the browser.
*/
public function testLoginWithDifferentTokenLoginName() {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$manager = $this->createMock(Manager::class);
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
$username = 'user123';
$token = new \OC\Authentication\Token\DefaultToken();
$token->setLoginName($username);
$session->expects($this->never())
->method('set');
$session->expects($this->once())
->method('regenerateId');
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('bar')
->will($this->returnValue($token));
$manager->expects($this->once())
->method('checkPassword')
->with('foo', 'bar')
->will($this->returnValue(false));
$userSession->login('foo', 'bar');
}
2016-06-17 12:01:35 +03:00
/**
* @expectedException \OC\Authentication\Exceptions\PasswordLoginForbiddenException
*/
public function testLogClientInNoTokenPasswordWith2fa() {
$manager = $this->createMock(Manager::class);
2016-09-12 22:53:21 +03:00
$session = $this->createMock(ISession::class);
$request = $this->createMock(IRequest::class);
/** @var \OC\User\Session $userSession */
$userSession = $this->getMockBuilder(Session::class)
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser'])
->getMock();
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('doe')
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
$this->config->expects($this->once())
->method('getSystemValue')
->with('token_auth_enforced', false)
->will($this->returnValue(true));
$request
2016-08-26 16:10:03 +03:00
->expects($this->any())
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->throttler
->expects($this->once())
->method('sleepDelay')
->with('192.168.0.1');
2016-07-21 00:09:27 +03:00
$this->throttler
2016-08-26 16:10:03 +03:00
->expects($this->any())
2016-07-21 00:09:27 +03:00
->method('getDelay')
->with('192.168.0.1')
->willReturn(0);
$userSession->logClientIn('john', 'doe', $request, $this->throttler);
}
public function testLogClientInUnexist() {
$manager = $this->createMock(Manager::class);
$session = $this->createMock(ISession::class);
$request = $this->createMock(IRequest::class);
/** @var Session $userSession */
$userSession = $this->getMockBuilder(Session::class)
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser'])
->getMock();
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('doe')
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
$this->config->expects($this->once())
->method('getSystemValue')
->with('token_auth_enforced', false)
->will($this->returnValue(false));
$this->assertFalse($userSession->logClientIn('unexist', 'doe', $request, $this->throttler));
}
public function testLogClientInWithTokenPassword() {
$manager = $this->createMock(Manager::class);
2016-09-12 22:53:21 +03:00
$session = $this->createMock(ISession::class);
$request = $this->createMock(IRequest::class);
/** @var \OC\User\Session $userSession */
$userSession = $this->getMockBuilder(Session::class)
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser'])
->getMock();
$userSession->expects($this->once())
->method('isTokenPassword')
->will($this->returnValue(true));
$userSession->expects($this->once())
->method('login')
2016-06-20 10:10:11 +03:00
->with('john', 'I-AM-AN-APP-PASSWORD')
->will($this->returnValue(true));
2016-06-20 10:10:11 +03:00
$session->expects($this->once())
->method('set')
->with('app_password', 'I-AM-AN-APP-PASSWORD');
$request
2016-08-26 16:10:03 +03:00
->expects($this->any())
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->throttler
->expects($this->once())
->method('sleepDelay')
->with('192.168.0.1');
2016-07-21 00:09:27 +03:00
$this->throttler
2016-08-26 16:10:03 +03:00
->expects($this->any())
2016-07-21 00:09:27 +03:00
->method('getDelay')
->with('192.168.0.1')
->willReturn(0);
$this->assertTrue($userSession->logClientIn('john', 'I-AM-AN-APP-PASSWORD', $request, $this->throttler));
}
2016-06-17 12:01:35 +03:00
/**
* @expectedException \OC\Authentication\Exceptions\PasswordLoginForbiddenException
*/
public function testLogClientInNoTokenPasswordNo2fa() {
$manager = $this->createMock(Manager::class);
2016-09-12 22:53:21 +03:00
$session = $this->createMock(ISession::class);
$request = $this->createMock(IRequest::class);
/** @var \OC\User\Session $userSession */
$userSession = $this->getMockBuilder(Session::class)
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
->setMethods(['login', 'isTwoFactorEnforced'])
->getMock();
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('doe')
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
$this->config->expects($this->once())
->method('getSystemValue')
->with('token_auth_enforced', false)
->will($this->returnValue(false));
$userSession->expects($this->once())
->method('isTwoFactorEnforced')
->with('john')
->will($this->returnValue(true));
$request
2016-08-26 16:10:03 +03:00
->expects($this->any())
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->throttler
->expects($this->once())
->method('sleepDelay')
->with('192.168.0.1');
2016-07-21 00:09:27 +03:00
$this->throttler
2016-08-26 16:10:03 +03:00
->expects($this->any())
2016-07-21 00:09:27 +03:00
->method('getDelay')
->with('192.168.0.1')
->willReturn(0);
$userSession->logClientIn('john', 'doe', $request, $this->throttler);
}
2014-05-23 02:18:07 +04:00
public function testRememberLoginValidToken() {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$managerMethods = get_class_methods(\OC\User\Manager::class);
//keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->getMock();
$userSession = $this->getMockBuilder(Session::class)
//override, otherwise tests will fail because of setcookie()
->setMethods(['setMagicInCookie'])
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
->getMock();
2014-05-23 02:18:07 +04:00
$user = $this->createMock(IUser::class);
$token = 'goodToken';
$oldSessionId = 'sess321';
$sessionId = 'sess123';
2014-05-23 02:18:07 +04:00
$session->expects($this->once())
->method('regenerateId');
$manager->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($user));
$this->config->expects($this->once())
->method('getUserKeys')
->with('foo', 'login_token')
->will($this->returnValue([$token]));
$this->config->expects($this->once())
->method('deleteUserValue')
->with('foo', 'login_token', $token);
$this->random->expects($this->once())
->method('generate')
->with(32)
->will($this->returnValue('abcdefg123456'));
$this->config->expects($this->once())
->method('setUserValue')
->with('foo', 'login_token', 'abcdefg123456', 10000);
2014-05-23 02:18:07 +04:00
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
$this->tokenProvider->expects($this->once())
->method('renewSessionToken')
->with($oldSessionId, $sessionId)
->will($this->returnValue(true));
2014-05-23 02:18:07 +04:00
$user->expects($this->any())
->method('getUID')
->will($this->returnValue('foo'));
$userSession->expects($this->once())
->method('setMagicInCookie');
2014-05-23 02:54:17 +04:00
$user->expects($this->once())
->method('updateLastLoginTimestamp');
$session->expects($this->once())
->method('set')
->with('user_id', 'foo');
2014-05-23 02:18:07 +04:00
$granted = $userSession->loginWithCookie('foo', $token, $oldSessionId);
2014-05-23 02:18:07 +04:00
$this->assertTrue($granted);
}
2014-05-23 02:18:07 +04:00
public function testRememberLoginInvalidSessionToken() {
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$managerMethods = get_class_methods(\OC\User\Manager::class);
//keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->getMock();
2016-09-12 22:53:21 +03:00
$userSession = $this->getMockBuilder(Session::class)
2014-05-23 02:18:07 +04:00
//override, otherwise tests will fail because of setcookie()
2016-09-12 22:53:21 +03:00
->setMethods(['setMagicInCookie'])
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
2016-09-12 22:53:21 +03:00
->getMock();
2014-05-23 02:18:07 +04:00
$user = $this->createMock(IUser::class);
$token = 'goodToken';
$oldSessionId = 'sess321';
$sessionId = 'sess123';
2014-05-23 02:18:07 +04:00
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
$manager->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($user));
$this->config->expects($this->once())
->method('getUserKeys')
->with('foo', 'login_token')
->will($this->returnValue([$token]));
$this->config->expects($this->once())
->method('deleteUserValue')
->with('foo', 'login_token', $token);
$this->config->expects($this->once())
->method('setUserValue'); // TODO: mock new random value
2014-05-23 02:18:07 +04:00
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
$this->tokenProvider->expects($this->once())
->method('renewSessionToken')
->with($oldSessionId, $sessionId)
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
2014-05-23 02:18:07 +04:00
$user->expects($this->never())
2014-05-23 02:18:07 +04:00
->method('getUID')
->will($this->returnValue('foo'));
$userSession->expects($this->never())
->method('setMagicInCookie');
2014-05-23 02:54:17 +04:00
$user->expects($this->never())
->method('updateLastLoginTimestamp');
$session->expects($this->never())
->method('set')
->with('user_id', 'foo');
$granted = $userSession->loginWithCookie('foo', $token, $oldSessionId);
$this->assertFalse($granted);
}
2014-05-23 02:18:07 +04:00
public function testRememberLoginInvalidToken() {
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$managerMethods = get_class_methods(\OC\User\Manager::class);
//keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->getMock();
$userSession = $this->getMockBuilder(Session::class)
//override, otherwise tests will fail because of setcookie()
->setMethods(['setMagicInCookie'])
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
->getMock();
$user = $this->createMock(IUser::class);
$token = 'goodToken';
$oldSessionId = 'sess321';
$session->expects($this->once())
->method('regenerateId');
2014-05-23 02:18:07 +04:00
$manager->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($user));
$this->config->expects($this->once())
->method('getUserKeys')
->with('foo', 'login_token')
->will($this->returnValue(['anothertoken']));
$this->config->expects($this->never())
->method('deleteUserValue')
->with('foo', 'login_token', $token);
$this->tokenProvider->expects($this->never())
->method('renewSessionToken');
$userSession->expects($this->never())
->method('setMagicInCookie');
$user->expects($this->never())
->method('updateLastLoginTimestamp');
$session->expects($this->never())
->method('set')
->with('user_id', 'foo');
2014-05-23 02:18:07 +04:00
$granted = $userSession->loginWithCookie('foo', $token, $oldSessionId);
2014-05-23 02:18:07 +04:00
$this->assertFalse($granted);
2014-05-23 02:18:07 +04:00
}
public function testRememberLoginInvalidUser() {
2016-09-12 22:53:21 +03:00
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$managerMethods = get_class_methods(\OC\User\Manager::class);
//keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([$this->config])
->getMock();
$userSession = $this->getMockBuilder(Session::class)
//override, otherwise tests will fail because of setcookie()
->setMethods(['setMagicInCookie'])
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
->getMock();
$token = 'goodToken';
$oldSessionId = 'sess321';
$session->expects($this->once())
2016-04-28 11:52:28 +03:00
->method('regenerateId');
2014-05-23 02:18:07 +04:00
$manager->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue(null));
$this->config->expects($this->never())
->method('getUserKeys')
->with('foo', 'login_token')
->will($this->returnValue(['anothertoken']));
$this->tokenProvider->expects($this->never())
->method('renewSessionToken');
$userSession->expects($this->never())
->method('setMagicInCookie');
$session->expects($this->never())
->method('set')
->with('user_id', 'foo');
2014-05-23 02:18:07 +04:00
$granted = $userSession->loginWithCookie('foo', $token, $oldSessionId);
2014-05-23 02:18:07 +04:00
$this->assertFalse($granted);
2014-05-23 02:18:07 +04:00
}
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) {
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')
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
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 testCreateSessionToken() {
2016-09-12 22:53:21 +03:00
$manager = $this->createMock(Manager::class);
$session = $this->createMock(ISession::class);
$user = $this->createMock(IUser::class);
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
2016-09-12 22:53:21 +03:00
$random = $this->createMock(ISecureRandom::class);
$config = $this->createMock(IConfig::class);
$csrf = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager')
->disableOriginalConstructor()
->getMock();
$request = new \OC\AppFramework\Http\Request([
'server' => [
'HTTP_USER_AGENT' => 'Firefox',
]
], $random, $config, $csrf);
$uid = 'user123';
$loginName = 'User123';
$password = 'passme';
$sessionId = 'abcxyz';
$manager->expects($this->once())
->method('get')
->with($uid)
->will($this->returnValue($user));
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
$this->tokenProvider->expects($this->once())
->method('getToken')
->with($password)
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
$this->tokenProvider->expects($this->once())
->method('generateToken')
->with($sessionId, $uid, $loginName, $password, 'Firefox', IToken::DO_NOT_REMEMBER, IToken::TEMPORARY_TOKEN);
$this->assertTrue($userSession->createSessionToken($request, $uid, $loginName, $password));
}
public function testCreateRememberedSessionToken() {
$manager = $this->createMock(Manager::class);
$session = $this->createMock(ISession::class);
$user = $this->createMock(IUser::class);
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
$random = $this->createMock(ISecureRandom::class);
$config = $this->createMock(IConfig::class);
$csrf = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager')
->disableOriginalConstructor()
->getMock();
$request = new \OC\AppFramework\Http\Request([
'server' => [
'HTTP_USER_AGENT' => 'Firefox',
]
], $random, $config, $csrf);
$uid = 'user123';
$loginName = 'User123';
$password = 'passme';
$sessionId = 'abcxyz';
$manager->expects($this->once())
->method('get')
->with($uid)
->will($this->returnValue($user));
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
$this->tokenProvider->expects($this->once())
->method('getToken')
->with($password)
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
$this->tokenProvider->expects($this->once())
->method('generateToken')
->with($sessionId, $uid, $loginName, $password, 'Firefox', IToken::TEMPORARY_TOKEN, IToken::REMEMBER);
$this->assertTrue($userSession->createSessionToken($request, $uid, $loginName, $password, true));
}
public function testCreateSessionTokenWithTokenPassword() {
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();
2016-09-12 22:53:21 +03:00
$session = $this->createMock(ISession::class);
$token = $this->createMock(IToken::class);
$user = $this->createMock(IUser::class);
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
2016-09-12 22:53:21 +03:00
$random = $this->createMock(ISecureRandom::class);
$config = $this->createMock(IConfig::class);
$csrf = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager')
->disableOriginalConstructor()
->getMock();
$request = new \OC\AppFramework\Http\Request([
'server' => [
'HTTP_USER_AGENT' => 'Firefox',
]
], $random, $config, $csrf);
$uid = 'user123';
$loginName = 'User123';
$password = 'iamatoken';
$realPassword = 'passme';
$sessionId = 'abcxyz';
$manager->expects($this->once())
->method('get')
->with($uid)
->will($this->returnValue($user));
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
$this->tokenProvider->expects($this->once())
->method('getToken')
->with($password)
->will($this->returnValue($token));
$this->tokenProvider->expects($this->once())
->method('getPassword')
->with($token, $password)
->will($this->returnValue($realPassword));
$this->tokenProvider->expects($this->once())
->method('generateToken')
->with($sessionId, $uid, $loginName, $realPassword, 'Firefox', IToken::TEMPORARY_TOKEN, IToken::DO_NOT_REMEMBER);
$this->assertTrue($userSession->createSessionToken($request, $uid, $loginName, $password));
}
public function testCreateSessionTokenWithNonExistentUser() {
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();
2016-09-12 22:53:21 +03:00
$session = $this->createMock(ISession::class);
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random);
2016-09-12 22:53:21 +03:00
$request = $this->createMock(IRequest::class);
$uid = 'user123';
$loginName = 'User123';
$password = 'passme';
$manager->expects($this->once())
->method('get')
->with($uid)
->will($this->returnValue(null));
$this->assertFalse($userSession->createSessionToken($request, $uid, $loginName, $password));
}
/**
* @expectedException \OC\User\LoginException
*/
public function testTryTokenLoginWithDisabledUser() {
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();
$session = new Memory('');
2016-06-20 11:41:23 +03:00
$token = new \OC\Authentication\Token\DefaultToken();
$token->setLoginName('fritz');
$token->setUid('fritz0');
$token->setLastCheck(100); // Needs check
2016-09-12 22:53:21 +03:00
$user = $this->createMock(IUser::class);
2016-06-20 11:41:23 +03:00
$userSession = $this->getMockBuilder('\OC\User\Session')
->setMethods(['logout'])
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random])
2016-06-20 11:41:23 +03:00
->getMock();
2016-09-12 22:53:21 +03:00
$request = $this->createMock(IRequest::class);
$request->expects($this->once())
->method('getHeader')
->with('Authorization')
->will($this->returnValue('token xxxxx'));
$this->tokenProvider->expects($this->once())
2016-06-20 11:41:23 +03:00
->method('getToken')
->with('xxxxx')
->will($this->returnValue($token));
$manager->expects($this->once())
->method('get')
2016-06-20 11:41:23 +03:00
->with('fritz0')
->will($this->returnValue($user));
$user->expects($this->once())
->method('isEnabled')
->will($this->returnValue(false));
$userSession->tryTokenLogin($request);
}
public function testValidateSessionDisabledUser() {
2016-09-12 22:53:21 +03:00
$userManager = $this->createMock(IUserManager::class);
$session = $this->createMock(ISession::class);
$timeFactory = $this->createMock(ITimeFactory::class);
$tokenProvider = $this->createMock(IProvider::class);
$userSession = $this->getMockBuilder('\OC\User\Session')
->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random])
->setMethods(['logout'])
->getMock();
2016-09-12 22:53:21 +03:00
$user = $this->createMock(IUser::class);
2016-06-20 10:10:11 +03:00
$token = new \OC\Authentication\Token\DefaultToken();
$token->setLoginName('susan');
$token->setLastCheck(20);
$session->expects($this->once())
2016-06-20 10:10:11 +03:00
->method('get')
->with('app_password')
->will($this->returnValue('APP-PASSWORD'));
$tokenProvider->expects($this->once())
->method('getToken')
2016-06-20 10:10:11 +03:00
->with('APP-PASSWORD')
->will($this->returnValue($token));
$timeFactory->expects($this->once())
->method('getTime')
2016-06-20 10:10:11 +03:00
->will($this->returnValue(1000)); // more than 5min since last check
$tokenProvider->expects($this->once())
->method('getPassword')
2016-06-20 10:10:11 +03:00
->with($token, 'APP-PASSWORD')
->will($this->returnValue('123456'));
$userManager->expects($this->once())
->method('checkPassword')
2016-06-20 10:10:11 +03:00
->with('susan', '123456')
->will($this->returnValue(true));
$user->expects($this->once())
->method('isEnabled')
->will($this->returnValue(false));
2016-06-20 11:41:23 +03:00
$tokenProvider->expects($this->once())
2016-06-20 10:10:11 +03:00
->method('invalidateToken')
2016-06-20 11:41:23 +03:00
->with('APP-PASSWORD');
$userSession->expects($this->once())
->method('logout');
2016-06-20 11:41:23 +03:00
$userSession->setUser($user);
$this->invokePrivate($userSession, 'validateSession');
}
public function testValidateSessionNoPassword() {
2016-09-12 22:53:21 +03:00
$userManager = $this->createMock(IUserManager::class);
$session = $this->createMock(ISession::class);
$timeFactory = $this->createMock(ITimeFactory::class);
$tokenProvider = $this->createMock(IProvider::class);
$userSession = $this->getMockBuilder('\OC\User\Session')
->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random])
->setMethods(['logout'])
->getMock();
2016-09-12 22:53:21 +03:00
$user = $this->createMock(IUser::class);
2016-06-20 10:10:11 +03:00
$token = new \OC\Authentication\Token\DefaultToken();
$token->setLastCheck(20);
$session->expects($this->once())
2016-06-20 10:10:11 +03:00
->method('get')
->with('app_password')
->will($this->returnValue('APP-PASSWORD'));
$tokenProvider->expects($this->once())
->method('getToken')
2016-06-20 10:10:11 +03:00
->with('APP-PASSWORD')
->will($this->returnValue($token));
$timeFactory->expects($this->once())
->method('getTime')
2016-06-20 10:10:11 +03:00
->will($this->returnValue(1000)); // more than 5min since last check
$tokenProvider->expects($this->once())
->method('getPassword')
2016-06-20 10:10:11 +03:00
->with($token, 'APP-PASSWORD')
->will($this->throwException(new \OC\Authentication\Exceptions\PasswordlessTokenException()));
$this->invokePrivate($userSession, 'validateSession', [$user]);
2016-06-20 10:10:11 +03:00
$this->assertEquals(1000, $token->getLastCheck());
}
public function testUpdateSessionTokenPassword() {
2016-09-12 22:53:21 +03:00
$userManager = $this->createMock(IUserManager::class);
$session = $this->createMock(ISession::class);
$timeFactory = $this->createMock(ITimeFactory::class);
$tokenProvider = $this->createMock(IProvider::class);
$userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random);
$password = '123456';
$sessionId = 'session1234';
$token = new \OC\Authentication\Token\DefaultToken();
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
$tokenProvider->expects($this->once())
->method('getToken')
->with($sessionId)
->will($this->returnValue($token));
$tokenProvider->expects($this->once())
->method('setPassword')
->with($token, $sessionId, $password);
$userSession->updateSessionTokenPassword($password);
}
public function testUpdateSessionTokenPasswordNoSessionAvailable() {
2016-09-12 22:53:21 +03:00
$userManager = $this->createMock(IUserManager::class);
$session = $this->createMock(ISession::class);
$timeFactory = $this->createMock(ITimeFactory::class);
$tokenProvider = $this->createMock(IProvider::class);
$userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random);
$session->expects($this->once())
->method('getId')
->will($this->throwException(new \OCP\Session\Exceptions\SessionNotAvailableException()));
$userSession->updateSessionTokenPassword('1234');
}
public function testUpdateSessionTokenPasswordInvalidTokenException() {
2016-09-12 22:53:21 +03:00
$userManager = $this->createMock(IUserManager::class);
$session = $this->createMock(ISession::class);
$timeFactory = $this->createMock(ITimeFactory::class);
$tokenProvider = $this->createMock(IProvider::class);
$userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random);
$password = '123456';
$sessionId = 'session1234';
$token = new \OC\Authentication\Token\DefaultToken();
$session->expects($this->once())
->method('getId')
->will($this->returnValue($sessionId));
$tokenProvider->expects($this->once())
->method('getToken')
->with($sessionId)
->will($this->returnValue($token));
$tokenProvider->expects($this->once())
->method('setPassword')
->with($token, $sessionId, $password)
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
$userSession->updateSessionTokenPassword($password);
}
public function testUpdateAuthTokenLastCheck() {
$manager = $this->createMock(Manager::class);
$session = $this->createMock(ISession::class);
$request = $this->createMock(IRequest::class);
$token = new \OC\Authentication\Token\DefaultToken();
$token->setUid('john');
$token->setLoginName('john');
$token->setLastActivity(100);
$token->setLastCheck(100);
$mapper = $this->getMockBuilder(DefaultTokenMapper::class)
->disableOriginalConstructor()
->getMock();
$crypto = $this->createMock(ICrypto::class);
$logger = $this->createMock(ILogger::class);
$tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory);
/** @var \OC\User\Session $userSession */
$userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random);
$mapper->expects($this->any())
->method('getToken')
->will($this->returnValue($token));
$mapper->expects($this->once())
->method('update');
$request
->expects($this->any())
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->throttler
->expects($this->once())
->method('sleepDelay')
->with('192.168.0.1');
$this->throttler
->expects($this->any())
->method('getDelay')
->with('192.168.0.1')
->willReturn(0);
$this->timeFactory
->expects($this->any())
->method('getTime')
->will($this->returnValue(100));
$userSession->logClientIn('john', 'doe', $request, $this->throttler);
$this->assertEquals(10000, $token->getLastActivity());
$this->assertEquals(10000, $token->getLastCheck());
}
public function testNoUpdateAuthTokenLastCheckRecent() {
$manager = $this->createMock(Manager::class);
$session = $this->createMock(ISession::class);
$request = $this->createMock(IRequest::class);
$token = new \OC\Authentication\Token\DefaultToken();
$token->setUid('john');
$token->setLoginName('john');
$token->setLastActivity(10000);
$token->setLastCheck(100);
$mapper = $this->getMockBuilder(DefaultTokenMapper::class)
->disableOriginalConstructor()
->getMock();
$crypto = $this->createMock(ICrypto::class);
$logger = $this->createMock(ILogger::class);
$tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory);
/** @var \OC\User\Session $userSession */
$userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random);
$mapper->expects($this->any())
->method('getToken')
->will($this->returnValue($token));
$mapper->expects($this->never())
->method('update');
$request
->expects($this->any())
->method('getRemoteAddress')
->willReturn('192.168.0.1');
$this->throttler
->expects($this->once())
->method('sleepDelay')
->with('192.168.0.1');
$this->throttler
->expects($this->any())
->method('getDelay')
->with('192.168.0.1')
->willReturn(0);
$this->timeFactory
->expects($this->any())
->method('getTime')
->will($this->returnValue(100));
$userSession->logClientIn('john', 'doe', $request, $this->throttler);
}
public function testCreateRememberMeToken() {
$user = $this->createMock(IUser::class);
$user
->expects($this->exactly(2))
->method('getUID')
->willReturn('UserUid');
$this->random
->expects($this->once())
->method('generate')
->with(32)
->willReturn('LongRandomToken');
$this->config
->expects($this->once())
->method('setUserValue')
->with('UserUid', 'login_token', 'LongRandomToken', 10000);
$this->userSession
->expects($this->once())
->method('setMagicInCookie')
->with('UserUid', 'LongRandomToken');
$this->userSession->createRememberMeToken($user);
}
2013-05-29 01:46:57 +04:00
}