fix remember me logintags/v11.0RC2
@@ -196,9 +196,10 @@ class LoginController extends Controller { | |||
* @param string $user | |||
* @param string $password | |||
* @param string $redirect_url | |||
* @param boolean $remember_login | |||
* @return RedirectResponse | |||
*/ | |||
public function tryLogin($user, $password, $redirect_url) { | |||
public function tryLogin($user, $password, $redirect_url, $remember_login = false) { | |||
$currentDelay = $this->throttler->getDelay($this->request->getRemoteAddress()); | |||
$this->throttler->sleepDelay($this->request->getRemoteAddress()); | |||
@@ -236,13 +237,13 @@ class LoginController extends Controller { | |||
// TODO: remove password checks from above and let the user session handle failures | |||
// requires https://github.com/owncloud/core/pull/24616 | |||
$this->userSession->login($user, $password); | |||
$this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password); | |||
$this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password, $remember_login); | |||
// User has successfully logged in, now remove the password reset link, when it is available | |||
$this->config->deleteUserValue($loginResult->getUID(), 'core', 'lostpassword'); | |||
if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) { | |||
$this->twoFactorManager->prepareTwoFactorLogin($loginResult); | |||
$this->twoFactorManager->prepareTwoFactorLogin($loginResult, $remember_login); | |||
$providers = $this->twoFactorManager->getProviders($loginResult); | |||
if (count($providers) === 1) { | |||
@@ -265,6 +266,10 @@ class LoginController extends Controller { | |||
return new RedirectResponse($this->urlGenerator->linkToRoute($url, $urlParams)); | |||
} | |||
if ($remember_login) { | |||
$this->userSession->createRememberMeToken($loginResult); | |||
} | |||
return $this->generateRedirect($redirect_url); | |||
} | |||
@@ -1125,6 +1125,15 @@ | |||
<length>2</length> | |||
</field> | |||
<field> | |||
<name>remember</name> | |||
<type>integer</type> | |||
<default>0</default> | |||
<notnull>true</notnull> | |||
<unsigned>true</unsigned> | |||
<length>1</length> | |||
</field> | |||
<field> | |||
<name>last_activity</name> | |||
<type>integer</type> |
@@ -1035,6 +1035,12 @@ class OC { | |||
if ($userSession->tryTokenLogin($request)) { | |||
return true; | |||
} | |||
if (isset($_COOKIE['nc_username']) | |||
&& isset($_COOKIE['nc_token']) | |||
&& isset($_COOKIE['nc_session_id']) | |||
&& $userSession->loginWithCookie($_COOKIE['nc_username'], $_COOKIE['nc_token'], $_COOKIE['nc_session_id'])) { | |||
return true; | |||
} | |||
if ($userSession->tryBasicAuthLogin($request, \OC::$server->getBruteForceThrottler())) { | |||
return true; | |||
} |
@@ -290,6 +290,7 @@ class DIContainer extends SimpleContainer implements IAppContainer { | |||
$this->registerService('OCP\\IUserSession', function($c) { | |||
return $this->getServer()->getUserSession(); | |||
}); | |||
$this->registerAlias(\OC\User\Session::class, \OCP\IUserSession::class); | |||
$this->registerService('OCP\\ISession', function($c) { | |||
return $this->getServer()->getSession(); |
@@ -35,6 +35,8 @@ use OCP\AppFramework\Db\Entity; | |||
* @method string getToken() | |||
* @method void setType(string $type) | |||
* @method int getType() | |||
* @method void setRemember(int $remember) | |||
* @method int getRemember() | |||
* @method void setLastActivity(int $lastActivity) | |||
* @method int getLastActivity() | |||
*/ | |||
@@ -70,6 +72,11 @@ class DefaultToken extends Entity implements IToken { | |||
*/ | |||
protected $type; | |||
/** | |||
* @var int | |||
*/ | |||
protected $remember; | |||
/** | |||
* @var int | |||
*/ |
@@ -40,24 +40,25 @@ class DefaultTokenMapper extends Mapper { | |||
* @param string $token | |||
*/ | |||
public function invalidate($token) { | |||
/* @var $qb IQueryBuilder */ | |||
$qb = $this->db->getQueryBuilder(); | |||
$qb->delete('authtoken') | |||
->andWhere($qb->expr()->eq('token', $qb->createParameter('token'))) | |||
->where($qb->expr()->eq('token', $qb->createParameter('token'))) | |||
->setParameter('token', $token) | |||
->execute(); | |||
} | |||
/** | |||
* @param int $olderThan | |||
* @param int $remember | |||
*/ | |||
public function invalidateOld($olderThan) { | |||
public function invalidateOld($olderThan, $remember = IToken::DO_NOT_REMEMBER) { | |||
/* @var $qb IQueryBuilder */ | |||
$qb = $this->db->getQueryBuilder(); | |||
$qb->delete('authtoken') | |||
->where($qb->expr()->lt('last_activity', $qb->createParameter('last_activity'))) | |||
->andWhere($qb->expr()->eq('type', $qb->createParameter('type'))) | |||
->setParameter('last_activity', $olderThan, IQueryBuilder::PARAM_INT) | |||
->setParameter('type', IToken::TEMPORARY_TOKEN, IQueryBuilder::PARAM_INT) | |||
->where($qb->expr()->lt('last_activity', $qb->createNamedParameter($olderThan, IQueryBuilder::PARAM_INT))) | |||
->andWhere($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN, IQueryBuilder::PARAM_INT))) | |||
->andWhere($qb->expr()->eq('remember', $qb->createNamedParameter($remember, IQueryBuilder::PARAM_INT))) | |||
->execute(); | |||
} | |||
@@ -71,7 +72,7 @@ class DefaultTokenMapper extends Mapper { | |||
public function getToken($token) { | |||
/* @var $qb IQueryBuilder */ | |||
$qb = $this->db->getQueryBuilder(); | |||
$result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'token', 'last_activity', 'last_check') | |||
$result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'remember', 'token', 'last_activity', 'last_check') | |||
->from('authtoken') | |||
->where($qb->expr()->eq('token', $qb->createParameter('token'))) | |||
->setParameter('token', $token) | |||
@@ -97,7 +98,7 @@ class DefaultTokenMapper extends Mapper { | |||
public function getTokenByUser(IUser $user) { | |||
/* @var $qb IQueryBuilder */ | |||
$qb = $this->db->getQueryBuilder(); | |||
$qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'token', 'last_activity', 'last_check') | |||
$qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'remember', 'token', 'last_activity', 'last_check') | |||
->from('authtoken') | |||
->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID()))) | |||
->setMaxResults(1000); |
@@ -1,6 +1,7 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @copyright Copyright (c) 2016, Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @author Christoph Wurst <christoph@owncloud.com> | |||
* | |||
@@ -56,7 +57,11 @@ class DefaultTokenProvider implements IProvider { | |||
* @param ILogger $logger | |||
* @param ITimeFactory $time | |||
*/ | |||
public function __construct(DefaultTokenMapper $mapper, ICrypto $crypto, IConfig $config, ILogger $logger, ITimeFactory $time) { | |||
public function __construct(DefaultTokenMapper $mapper, | |||
ICrypto $crypto, | |||
IConfig $config, | |||
ILogger $logger, | |||
ITimeFactory $time) { | |||
$this->mapper = $mapper; | |||
$this->crypto = $crypto; | |||
$this->config = $config; | |||
@@ -73,9 +78,10 @@ class DefaultTokenProvider implements IProvider { | |||
* @param string|null $password | |||
* @param string $name | |||
* @param int $type token type | |||
* @param int $remember whether the session token should be used for remember-me | |||
* @return IToken | |||
*/ | |||
public function generateToken($token, $uid, $loginName, $password, $name, $type = IToken::TEMPORARY_TOKEN) { | |||
public function generateToken($token, $uid, $loginName, $password, $name, $type = IToken::TEMPORARY_TOKEN, $remember = IToken::DO_NOT_REMEMBER) { | |||
$dbToken = new DefaultToken(); | |||
$dbToken->setUid($uid); | |||
$dbToken->setLoginName($loginName); | |||
@@ -85,6 +91,7 @@ class DefaultTokenProvider implements IProvider { | |||
$dbToken->setName($name); | |||
$dbToken->setToken($this->hashToken($token)); | |||
$dbToken->setType($type); | |||
$dbToken->setRemember($remember); | |||
$dbToken->setLastActivity($this->time->getTime()); | |||
$this->mapper->insert($dbToken); | |||
@@ -96,6 +103,7 @@ class DefaultTokenProvider implements IProvider { | |||
* Save the updated token | |||
* | |||
* @param IToken $token | |||
* @throws InvalidTokenException | |||
*/ | |||
public function updateToken(IToken $token) { | |||
if (!($token instanceof DefaultToken)) { | |||
@@ -151,6 +159,28 @@ class DefaultTokenProvider implements IProvider { | |||
} | |||
} | |||
/** | |||
* @param string $oldSessionId | |||
* @param string $sessionId | |||
* @throws InvalidTokenException | |||
*/ | |||
public function renewSessionToken($oldSessionId, $sessionId) { | |||
$token = $this->getToken($oldSessionId); | |||
$newToken = new DefaultToken(); | |||
$newToken->setUid($token->getUID()); | |||
$newToken->setLoginName($token->getLoginName()); | |||
if (!is_null($token->getPassword())) { | |||
$password = $this->decryptPassword($token->getPassword(), $oldSessionId); | |||
$newToken->setPassword($this->encryptPassword($password, $sessionId)); | |||
} | |||
$newToken->setName($token->getName()); | |||
$newToken->setToken($this->hashToken($sessionId)); | |||
$newToken->setType(IToken::TEMPORARY_TOKEN); | |||
$newToken->setLastActivity($this->time->getTime()); | |||
$this->mapper->insert($newToken); | |||
} | |||
/** | |||
* @param IToken $savedToken | |||
* @param string $tokenId session token | |||
@@ -207,8 +237,11 @@ class DefaultTokenProvider implements IProvider { | |||
*/ | |||
public function invalidateOldTokens() { | |||
$olderThan = $this->time->getTime() - (int) $this->config->getSystemValue('session_lifetime', 60 * 60 * 24); | |||
$this->logger->info('Invalidating tokens older than ' . date('c', $olderThan)); | |||
$this->mapper->invalidateOld($olderThan); | |||
$this->logger->info('Invalidating session tokens older than ' . date('c', $olderThan)); | |||
$this->mapper->invalidateOld($olderThan, IToken::DO_NOT_REMEMBER); | |||
$rememberThreshold = $this->time->getTime() - (int) $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15); | |||
$this->logger->info('Invalidating remembered session tokens older than ' . date('c', $rememberThreshold)); | |||
$this->mapper->invalidateOld($rememberThreshold, IToken::REMEMBER); | |||
} | |||
/** |
@@ -28,6 +28,7 @@ use OCP\IUser; | |||
interface IProvider { | |||
/** | |||
* Create and persist a new token | |||
* | |||
@@ -37,9 +38,10 @@ interface IProvider { | |||
* @param string|null $password | |||
* @param string $name | |||
* @param int $type token type | |||
* @param int $remember whether the session token should be used for remember-me | |||
* @return IToken | |||
*/ | |||
public function generateToken($token, $uid, $loginName, $password, $name, $type = IToken::TEMPORARY_TOKEN); | |||
public function generateToken($token, $uid, $loginName, $password, $name, $type = IToken::TEMPORARY_TOKEN, $remember = IToken::DO_NOT_REMEMBER); | |||
/** | |||
* Get a token by token id | |||
@@ -50,6 +52,15 @@ interface IProvider { | |||
*/ | |||
public function getToken($tokenId) ; | |||
/** | |||
* Duplicate an existing session token | |||
* | |||
* @param string $oldSessionId | |||
* @param string $sessionId | |||
* @throws InvalidTokenException | |||
*/ | |||
public function renewSessionToken($oldSessionId, $sessionId); | |||
/** | |||
* Invalidate (delete) the given session token | |||
* |
@@ -28,6 +28,8 @@ interface IToken extends JsonSerializable { | |||
const TEMPORARY_TOKEN = 0; | |||
const PERMANENT_TOKEN = 1; | |||
const DO_NOT_REMEMBER = 0; | |||
const REMEMBER = 1; | |||
/** | |||
* Get the token ID |
@@ -37,6 +37,7 @@ class Manager { | |||
const SESSION_UID_KEY = 'two_factor_auth_uid'; | |||
const BACKUP_CODES_APP_ID = 'twofactor_backupcodes'; | |||
const BACKUP_CODES_PROVIDER_ID = 'backup_codes'; | |||
const REMEMBER_LOGIN = 'two_factor_remember_login'; | |||
/** @var AppManager */ | |||
private $appManager; | |||
@@ -114,6 +115,7 @@ class Manager { | |||
* @param IUser $user | |||
* @param bool $includeBackupApp | |||
* @return IProvider[] | |||
* @throws Exception | |||
*/ | |||
public function getProviders(IUser $user, $includeBackupApp = false) { | |||
$allApps = $this->appManager->getEnabledAppsForUser($user); | |||
@@ -171,11 +173,16 @@ class Manager { | |||
return false; | |||
} | |||
$result = $provider->verifyChallenge($user, $challenge); | |||
if ($result) { | |||
$passed = $provider->verifyChallenge($user, $challenge); | |||
if ($passed) { | |||
if ($this->session->get(self::REMEMBER_LOGIN) === true) { | |||
// TODO: resolve cyclic dependency and use DI | |||
\OC::$server->getUserSession()->createRememberMeToken($user); | |||
} | |||
$this->session->remove(self::SESSION_UID_KEY); | |||
$this->session->remove(self::REMEMBER_LOGIN); | |||
} | |||
return $result; | |||
return $passed; | |||
} | |||
/** | |||
@@ -202,12 +209,14 @@ class Manager { | |||
} | |||
/** | |||
* Prepare the 2FA login (set session value) | |||
* Prepare the 2FA login | |||
* | |||
* @param IUser $user | |||
* @param boolean $rememberMe | |||
*/ | |||
public function prepareTwoFactorLogin(IUser $user) { | |||
public function prepareTwoFactorLogin(IUser $user, $rememberMe) { | |||
$this->session->set(self::SESSION_UID_KEY, $user->getUID()); | |||
$this->session->set(self::REMEMBER_LOGIN, $rememberMe); | |||
} | |||
} |
@@ -245,7 +245,7 @@ class Server extends ServerContainer implements IServerContainer { | |||
$defaultTokenProvider = null; | |||
} | |||
$userSession = new \OC\User\Session($manager, $session, $timeFactory, $defaultTokenProvider, $c->getConfig()); | |||
$userSession = new \OC\User\Session($manager, $session, $timeFactory, $defaultTokenProvider, $c->getConfig(), $c->getSecureRandom()); | |||
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) { | |||
\OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password)); | |||
}); | |||
@@ -286,7 +286,7 @@ class Server extends ServerContainer implements IServerContainer { | |||
return $userSession; | |||
}); | |||
$this->registerService('\OC\Authentication\TwoFactorAuth\Manager', function (Server $c) { | |||
$this->registerService(\OC\Authentication\TwoFactorAuth\Manager::class, function (Server $c) { | |||
return new \OC\Authentication\TwoFactorAuth\Manager($c->getAppManager(), $c->getSession(), $c->getConfig()); | |||
}); | |||
@@ -48,6 +48,7 @@ use OCP\ISession; | |||
use OCP\IUser; | |||
use OCP\IUserManager; | |||
use OCP\IUserSession; | |||
use OCP\Security\ISecureRandom; | |||
use OCP\Session\Exceptions\SessionNotAvailableException; | |||
use OCP\Util; | |||
@@ -89,23 +90,29 @@ class Session implements IUserSession, Emitter { | |||
/** @var User $activeUser */ | |||
protected $activeUser; | |||
/** @var ISecureRandom */ | |||
private $random; | |||
/** | |||
* @param IUserManager $manager | |||
* @param ISession $session | |||
* @param ITimeFactory $timeFacory | |||
* @param IProvider $tokenProvider | |||
* @param IConfig $config | |||
* @param ISecureRandom $random | |||
*/ | |||
public function __construct(IUserManager $manager, | |||
ISession $session, | |||
ITimeFactory $timeFacory, | |||
$tokenProvider, | |||
IConfig $config) { | |||
IConfig $config, | |||
ISecureRandom $random) { | |||
$this->manager = $manager; | |||
$this->session = $session; | |||
$this->timeFacory = $timeFacory; | |||
$this->tokenProvider = $tokenProvider; | |||
$this->config = $config; | |||
$this->random = $random; | |||
} | |||
/** | |||
@@ -526,9 +533,10 @@ class Session implements IUserSession, Emitter { | |||
* @param string $uid user UID | |||
* @param string $loginName login name | |||
* @param string $password | |||
* @param int $remember | |||
* @return boolean | |||
*/ | |||
public function createSessionToken(IRequest $request, $uid, $loginName, $password = null) { | |||
public function createSessionToken(IRequest $request, $uid, $loginName, $password = null, $remember = IToken::DO_NOT_REMEMBER) { | |||
if (is_null($this->manager->get($uid))) { | |||
// User does not exist | |||
return false; | |||
@@ -537,7 +545,7 @@ class Session implements IUserSession, Emitter { | |||
try { | |||
$sessionId = $this->session->getId(); | |||
$pwd = $this->getPassword($password); | |||
$this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name); | |||
$this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name, IToken::TEMPORARY_TOKEN, IToken::REMEMBER); | |||
return true; | |||
} catch (SessionNotAvailableException $ex) { | |||
// This can happen with OCC, where a memory session is used | |||
@@ -680,9 +688,10 @@ class Session implements IUserSession, Emitter { | |||
* | |||
* @param string $uid the username | |||
* @param string $currentToken | |||
* @param string $oldSessionId | |||
* @return bool | |||
*/ | |||
public function loginWithCookie($uid, $currentToken) { | |||
public function loginWithCookie($uid, $currentToken, $oldSessionId) { | |||
$this->session->regenerateId(); | |||
$this->manager->emit('\OC\User', 'preRememberedLogin', array($uid)); | |||
$user = $this->manager->get($uid); | |||
@@ -692,15 +701,26 @@ class Session implements IUserSession, Emitter { | |||
} | |||
// get stored tokens | |||
$tokens = OC::$server->getConfig()->getUserKeys($uid, 'login_token'); | |||
$tokens = $this->config->getUserKeys($uid, 'login_token'); | |||
// test cookies token against stored tokens | |||
if (!in_array($currentToken, $tokens, true)) { | |||
return false; | |||
} | |||
// replace successfully used token with a new one | |||
OC::$server->getConfig()->deleteUserValue($uid, 'login_token', $currentToken); | |||
$newToken = OC::$server->getSecureRandom()->generate(32); | |||
OC::$server->getConfig()->setUserValue($uid, 'login_token', $newToken, time()); | |||
$this->config->deleteUserValue($uid, 'login_token', $currentToken); | |||
$newToken = $this->random->generate(32); | |||
$this->config->setUserValue($uid, 'login_token', $newToken, $this->timeFacory->getTime()); | |||
try { | |||
$sessionId = $this->session->getId(); | |||
$this->tokenProvider->renewSessionToken($oldSessionId, $sessionId); | |||
} catch (SessionNotAvailableException $ex) { | |||
return false; | |||
} catch (InvalidTokenException $ex) { | |||
\OC::$server->getLogger()->warning('Renewing session token failed', ['app' => 'core']); | |||
return false; | |||
} | |||
$this->setMagicInCookie($user->getUID(), $newToken); | |||
//login | |||
@@ -709,6 +729,15 @@ class Session implements IUserSession, Emitter { | |||
return true; | |||
} | |||
/** | |||
* @param IUser $user | |||
*/ | |||
public function createRememberMeToken(IUser $user) { | |||
$token = $this->random->generate(32); | |||
$this->config->setUserValue($user->getUID(), 'login_token', $token, $this->timeFacory->getTime()); | |||
$this->setMagicInCookie($user->getUID(), $token); | |||
} | |||
/** | |||
* logout the user from the session | |||
*/ | |||
@@ -736,10 +765,19 @@ class Session implements IUserSession, Emitter { | |||
*/ | |||
public function setMagicInCookie($username, $token) { | |||
$secureCookie = OC::$server->getRequest()->getServerProtocol() === 'https'; | |||
$expires = time() + OC::$server->getConfig()->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15); | |||
setcookie('oc_username', $username, $expires, OC::$WEBROOT, '', $secureCookie, true); | |||
setcookie('oc_token', $token, $expires, OC::$WEBROOT, '', $secureCookie, true); | |||
setcookie('oc_remember_login', '1', $expires, OC::$WEBROOT, '', $secureCookie, true); | |||
$webRoot = \OC::$WEBROOT; | |||
if ($webRoot === '') { | |||
$webRoot = '/'; | |||
} | |||
$expires = $this->timeFacory->getTime() + $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15); | |||
setcookie('nc_username', $username, $expires, $webRoot, '', $secureCookie, true); | |||
setcookie('nc_token', $token, $expires, $webRoot, '', $secureCookie, true); | |||
try { | |||
setcookie('nc_session_id', $this->session->getId(), $expires, $webRoot, '', $secureCookie, true); | |||
} catch (SessionNotAvailableException $ex) { | |||
// ignore | |||
} | |||
} | |||
/** | |||
@@ -749,17 +787,17 @@ class Session implements IUserSession, Emitter { | |||
//TODO: DI for cookies and IRequest | |||
$secureCookie = OC::$server->getRequest()->getServerProtocol() === 'https'; | |||
unset($_COOKIE['oc_username']); //TODO: DI | |||
unset($_COOKIE['oc_token']); | |||
unset($_COOKIE['oc_remember_login']); | |||
setcookie('oc_username', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true); | |||
setcookie('oc_token', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true); | |||
setcookie('oc_remember_login', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true); | |||
unset($_COOKIE['nc_username']); //TODO: DI | |||
unset($_COOKIE['nc_token']); | |||
unset($_COOKIE['nc_session_id']); | |||
setcookie('nc_username', '', $this->timeFacory->getTime() - 3600, OC::$WEBROOT, '', $secureCookie, true); | |||
setcookie('nc_token', '', $this->timeFacory->getTime() - 3600, OC::$WEBROOT, '', $secureCookie, true); | |||
setcookie('nc_session_id', '', $this->timeFacory->getTime() - 3600, OC::$WEBROOT, '', $secureCookie, true); | |||
// old cookies might be stored under /webroot/ instead of /webroot | |||
// and Firefox doesn't like it! | |||
setcookie('oc_username', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true); | |||
setcookie('oc_token', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true); | |||
setcookie('oc_remember_login', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true); | |||
setcookie('nc_username', '', $this->timeFacory->getTime() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true); | |||
setcookie('nc_token', '', $this->timeFacory->getTime() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true); | |||
setcookie('nc_session_id', '', $this->timeFacory->getTime() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true); | |||
} | |||
/** | |||
@@ -779,4 +817,5 @@ class Session implements IUserSession, Emitter { | |||
} | |||
} | |||
} |
@@ -155,10 +155,11 @@ class OC_User { | |||
* @deprecated use \OCP\IUserSession::loginWithCookie() | |||
* @param string $uid The username of the user to log in | |||
* @param string $token | |||
* @param string $oldSessionId | |||
* @return bool | |||
*/ | |||
public static function loginWithCookie($uid, $token) { | |||
return self::getUserSession()->loginWithCookie($uid, $token); | |||
public static function loginWithCookie($uid, $token, $oldSessionId) { | |||
return self::getUserSession()->loginWithCookie($uid, $token, $oldSessionId); | |||
} | |||
/** |
@@ -145,7 +145,7 @@ interface IRequest { | |||
* Shortcut for getting cookie variables | |||
* | |||
* @param string $key the key that will be taken from the $_COOKIE array | |||
* @return string the value in the $_COOKIE element | |||
* @return string|null the value in the $_COOKIE element | |||
* @since 6.0.0 | |||
*/ | |||
public function getCookie($key); |
@@ -322,6 +322,8 @@ class LoginControllerTest extends TestCase { | |||
$this->userSession->expects($this->never()) | |||
->method('createSessionToken'); | |||
$this->userSession->expects($this->never()) | |||
->method('createRememberMeToken'); | |||
$this->config->expects($this->never()) | |||
->method('deleteUserValue'); | |||
@@ -363,7 +365,7 @@ class LoginControllerTest extends TestCase { | |||
->with($user, $password); | |||
$this->userSession->expects($this->once()) | |||
->method('createSessionToken') | |||
->with($this->request, $user->getUID(), $user, $password); | |||
->with($this->request, $user->getUID(), $user, $password, false); | |||
$this->twoFactorManager->expects($this->once()) | |||
->method('isTwoFactorAuthenticated') | |||
->with($user) | |||
@@ -371,11 +373,63 @@ class LoginControllerTest extends TestCase { | |||
$this->config->expects($this->once()) | |||
->method('deleteUserValue') | |||
->with('uid', 'core', 'lostpassword'); | |||
$this->userSession->expects($this->never()) | |||
->method('createRememberMeToken'); | |||
$expected = new \OCP\AppFramework\Http\RedirectResponse($indexPageUrl); | |||
$this->assertEquals($expected, $this->loginController->tryLogin($user, $password, null)); | |||
} | |||
public function testLoginWithValidCredentialsAndRememberMe() { | |||
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */ | |||
$user = $this->getMockBuilder('\OCP\IUser')->getMock(); | |||
$user->expects($this->any()) | |||
->method('getUID') | |||
->will($this->returnValue('uid')); | |||
$password = 'secret'; | |||
$indexPageUrl = \OC_Util::getDefaultPageUrl(); | |||
$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($user, $password); | |||
$this->userSession->expects($this->once()) | |||
->method('createSessionToken') | |||
->with($this->request, $user->getUID(), $user, $password, true); | |||
$this->twoFactorManager->expects($this->once()) | |||
->method('isTwoFactorAuthenticated') | |||
->with($user) | |||
->will($this->returnValue(false)); | |||
$this->config->expects($this->once()) | |||
->method('deleteUserValue') | |||
->with('uid', 'core', 'lostpassword'); | |||
$this->userSession->expects($this->once()) | |||
->method('createRememberMeToken') | |||
->with($user); | |||
$expected = new \OCP\AppFramework\Http\RedirectResponse($indexPageUrl); | |||
$this->assertEquals($expected, $this->loginController->tryLogin($user, $password, null, true)); | |||
} | |||
public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn() { | |||
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */ | |||
$user = $this->getMockBuilder('\OCP\IUser')->getMock(); | |||
@@ -408,6 +462,8 @@ class LoginControllerTest extends TestCase { | |||
->will($this->returnValue(false)); | |||
$this->config->expects($this->never()) | |||
->method('deleteUserValue'); | |||
$this->userSession->expects($this->never()) | |||
->method('createRememberMeToken'); | |||
$expected = new \OCP\AppFramework\Http\RedirectResponse(\OC_Util::getDefaultPageUrl()); | |||
$this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl)); | |||
@@ -450,6 +506,8 @@ class LoginControllerTest extends TestCase { | |||
->will($this->returnValue($redirectUrl)); | |||
$this->config->expects($this->never()) | |||
->method('deleteUserValue'); | |||
$this->userSession->expects($this->never()) | |||
->method('createRememberMeToken'); | |||
$expected = new \OCP\AppFramework\Http\RedirectResponse($redirectUrl); | |||
$this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl)); | |||
@@ -488,7 +546,7 @@ class LoginControllerTest extends TestCase { | |||
->will($this->returnValue($user)); | |||
$this->userSession->expects($this->once()) | |||
->method('createSessionToken') | |||
->with($this->request, $user->getUID(), 'Jane', $password); | |||
->with($this->request, $user->getUID(), 'Jane', $password, false); | |||
$this->userSession->expects($this->once()) | |||
->method('isLoggedIn') | |||
->with() | |||
@@ -540,7 +598,7 @@ class LoginControllerTest extends TestCase { | |||
->with('john@doe.com', $password); | |||
$this->userSession->expects($this->once()) | |||
->method('createSessionToken') | |||
->with($this->request, $user->getUID(), 'john@doe.com', $password); | |||
->with($this->request, $user->getUID(), 'john@doe.com', $password, false); | |||
$this->twoFactorManager->expects($this->once()) | |||
->method('isTwoFactorAuthenticated') | |||
->with($user) | |||
@@ -564,6 +622,8 @@ class LoginControllerTest extends TestCase { | |||
$this->config->expects($this->once()) | |||
->method('deleteUserValue') | |||
->with('john', 'core', 'lostpassword'); | |||
$this->userSession->expects($this->never()) | |||
->method('createRememberMeToken'); | |||
$expected = new RedirectResponse($challengeUrl); | |||
$this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', $password, null)); | |||
@@ -605,7 +665,7 @@ class LoginControllerTest extends TestCase { | |||
->with('john@doe.com', $password); | |||
$this->userSession->expects($this->once()) | |||
->method('createSessionToken') | |||
->with($this->request, $user->getUID(), 'john@doe.com', $password); | |||
->with($this->request, $user->getUID(), 'john@doe.com', $password, false); | |||
$this->twoFactorManager->expects($this->once()) | |||
->method('isTwoFactorAuthenticated') | |||
->with($user) | |||
@@ -628,6 +688,8 @@ class LoginControllerTest extends TestCase { | |||
$this->config->expects($this->once()) | |||
->method('deleteUserValue') | |||
->with('john', 'core', 'lostpassword'); | |||
$this->userSession->expects($this->never()) | |||
->method('createRememberMeToken'); | |||
$expected = new RedirectResponse($challengeUrl); | |||
$this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', $password, null)); | |||
@@ -680,6 +742,8 @@ class LoginControllerTest extends TestCase { | |||
->with('login', '192.168.0.1', ['user' => 'john@doe.com']); | |||
$this->config->expects($this->never()) | |||
->method('deleteUserValue'); | |||
$this->userSession->expects($this->never()) | |||
->method('createRememberMeToken'); | |||
$expected = new RedirectResponse(''); | |||
$this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', 'just wrong', null)); |
@@ -130,6 +130,7 @@ class DefaultTokenMapperTest extends TestCase { | |||
$token->setName('Firefox on Android'); | |||
$token->setToken('1504445f1524fc801035448a95681a9378ba2e83930c814546c56e5d6ebde221198792fd900c88ed5ead0555780dad1ebce3370d7e154941cd5de87eb419899b'); | |||
$token->setType(IToken::TEMPORARY_TOKEN); | |||
$token->setRemember(IToken::DO_NOT_REMEMBER); | |||
$token->setLastActivity($this->time - 60 * 60 * 24 * 3); | |||
$token->setLastCheck($this->time - 10); | |||
@@ -1,8 +1,8 @@ | |||
<?php | |||
/** | |||
* @author Christoph Wurst <christoph@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2016, Lukas Reschke <lukas@statuscode.ch> | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
@@ -25,7 +25,7 @@ namespace Test\Authentication\Token; | |||
use OC\Authentication\Token\DefaultToken; | |||
use OC\Authentication\Token\DefaultTokenProvider; | |||
use OC\Authentication\Token\IToken; | |||
use OCP\AppFramework\Db\DoesNotExistException; | |||
use OCP\AppFramework\Db\Mapper; | |||
use OCP\AppFramework\Utility\ITimeFactory; | |||
use OCP\IConfig; | |||
use OCP\ILogger; | |||
@@ -35,13 +35,19 @@ use Test\TestCase; | |||
class DefaultTokenProviderTest extends TestCase { | |||
/** @var DefaultTokenProvider */ | |||
/** @var DefaultTokenProvider|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $tokenProvider; | |||
/** @var Mapper|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $mapper; | |||
/** @var ICrypto|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $crypto; | |||
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $config; | |||
/** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $logger; | |||
/** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $timeFactory; | |||
/** @var int */ | |||
private $time; | |||
protected function setUp() { | |||
@@ -81,6 +87,7 @@ class DefaultTokenProviderTest extends TestCase { | |||
$toInsert->setName($name); | |||
$toInsert->setToken(hash('sha512', $token . '1f4h9s')); | |||
$toInsert->setType($type); | |||
$toInsert->setRemember(IToken::DO_NOT_REMEMBER); | |||
$toInsert->setLastActivity($this->time); | |||
$this->config->expects($this->any()) | |||
@@ -95,7 +102,7 @@ class DefaultTokenProviderTest extends TestCase { | |||
->method('insert') | |||
->with($this->equalTo($toInsert)); | |||
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type); | |||
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); | |||
$this->assertEquals($toInsert, $actual); | |||
} | |||
@@ -245,15 +252,128 @@ class DefaultTokenProviderTest extends TestCase { | |||
public function testInvalidateOldTokens() { | |||
$defaultSessionLifetime = 60 * 60 * 24; | |||
$this->config->expects($this->once()) | |||
$defaultRememberMeLifetime = 60 * 60 * 24 * 15; | |||
$this->config->expects($this->exactly(2)) | |||
->method('getSystemValue') | |||
->with('session_lifetime', $defaultSessionLifetime) | |||
->will($this->returnValue(150)); | |||
$this->mapper->expects($this->once()) | |||
->will($this->returnValueMap([ | |||
['session_lifetime', $defaultSessionLifetime, 150], | |||
['remember_login_cookie_lifetime', $defaultRememberMeLifetime, 300], | |||
])); | |||
$this->mapper->expects($this->at(0)) | |||
->method('invalidateOld') | |||
->with($this->time - 150); | |||
$this->mapper->expects($this->at(1)) | |||
->method('invalidateOld') | |||
->with($this->time - 300); | |||
$this->tokenProvider->invalidateOldTokens(); | |||
} | |||
public function testRenewSessionTokenWithoutPassword() { | |||
$token = $this->getMockBuilder(DefaultToken::class) | |||
->disableOriginalConstructor() | |||
->setMethods(['getUID', 'getLoginName', 'getPassword', 'getName']) | |||
->getMock(); | |||
$token | |||
->expects($this->at(0)) | |||
->method('getUID') | |||
->willReturn('UserUid'); | |||
$token | |||
->expects($this->at(1)) | |||
->method('getLoginName') | |||
->willReturn('UserLoginName'); | |||
$token | |||
->expects($this->at(2)) | |||
->method('getPassword') | |||
->willReturn(null); | |||
$token | |||
->expects($this->at(3)) | |||
->method('getName') | |||
->willReturn('MyTokenName'); | |||
$this->config | |||
->expects($this->exactly(2)) | |||
->method('getSystemValue') | |||
->with('secret') | |||
->willReturn('MyInstanceSecret'); | |||
$this->mapper | |||
->expects($this->at(0)) | |||
->method('getToken') | |||
->with(hash('sha512', 'oldId' . 'MyInstanceSecret')) | |||
->willReturn($token); | |||
$newToken = new DefaultToken(); | |||
$newToken->setUid('UserUid'); | |||
$newToken->setLoginName('UserLoginName'); | |||
$newToken->setName('MyTokenName'); | |||
$newToken->setToken(hash('sha512', 'newId' . 'MyInstanceSecret')); | |||
$newToken->setType(IToken::TEMPORARY_TOKEN); | |||
$newToken->setLastActivity(1313131); | |||
$this->mapper | |||
->expects($this->at(1)) | |||
->method('insert') | |||
->with($newToken); | |||
$this->tokenProvider->renewSessionToken('oldId', 'newId'); | |||
} | |||
public function testRenewSessionTokenWithPassword() { | |||
$token = $this->getMockBuilder(DefaultToken::class) | |||
->disableOriginalConstructor() | |||
->setMethods(['getUID', 'getLoginName', 'getPassword', 'getName']) | |||
->getMock(); | |||
$token | |||
->expects($this->at(0)) | |||
->method('getUID') | |||
->willReturn('UserUid'); | |||
$token | |||
->expects($this->at(1)) | |||
->method('getLoginName') | |||
->willReturn('UserLoginName'); | |||
$token | |||
->expects($this->at(2)) | |||
->method('getPassword') | |||
->willReturn('EncryptedPassword'); | |||
$token | |||
->expects($this->at(3)) | |||
->method('getPassword') | |||
->willReturn('EncryptedPassword'); | |||
$token | |||
->expects($this->at(4)) | |||
->method('getName') | |||
->willReturn('MyTokenName'); | |||
$this->crypto | |||
->expects($this->any(0)) | |||
->method('decrypt') | |||
->with('EncryptedPassword', 'oldIdMyInstanceSecret') | |||
->willReturn('ClearTextPassword'); | |||
$this->crypto | |||
->expects($this->any(1)) | |||
->method('encrypt') | |||
->with('ClearTextPassword', 'newIdMyInstanceSecret') | |||
->willReturn('EncryptedPassword'); | |||
$this->config | |||
->expects($this->exactly(4)) | |||
->method('getSystemValue') | |||
->with('secret') | |||
->willReturn('MyInstanceSecret'); | |||
$this->mapper | |||
->expects($this->at(0)) | |||
->method('getToken') | |||
->with(hash('sha512', 'oldId' . 'MyInstanceSecret')) | |||
->willReturn($token); | |||
$newToken = new DefaultToken(); | |||
$newToken->setUid('UserUid'); | |||
$newToken->setLoginName('UserLoginName'); | |||
$newToken->setName('MyTokenName'); | |||
$newToken->setToken(hash('sha512', 'newId' . 'MyInstanceSecret')); | |||
$newToken->setType(IToken::TEMPORARY_TOKEN); | |||
$newToken->setLastActivity(1313131); | |||
$newToken->setPassword('EncryptedPassword'); | |||
$this->mapper | |||
->expects($this->at(1)) | |||
->method('insert') | |||
->with($newToken); | |||
$this->tokenProvider->renewSessionToken('oldId', 'newId'); | |||
} | |||
} |
@@ -233,8 +233,15 @@ class ManagerTest extends TestCase { | |||
->with($this->user, $challenge) | |||
->will($this->returnValue(true)); | |||
$this->session->expects($this->once()) | |||
->method('get') | |||
->with('two_factor_remember_login') | |||
->will($this->returnValue(false)); | |||
$this->session->expects($this->at(1)) | |||
->method('remove') | |||
->with('two_factor_auth_uid'); | |||
$this->session->expects($this->at(2)) | |||
->method('remove') | |||
->with('two_factor_remember_login'); | |||
$this->assertTrue($this->manager->verifyChallenge('email', $this->user, $challenge)); | |||
} | |||
@@ -304,11 +311,29 @@ class ManagerTest extends TestCase { | |||
->method('getUID') | |||
->will($this->returnValue('ferdinand')); | |||
$this->session->expects($this->once()) | |||
$this->session->expects($this->at(0)) | |||
->method('set') | |||
->with('two_factor_auth_uid', 'ferdinand'); | |||
$this->session->expects($this->at(1)) | |||
->method('set') | |||
->with('two_factor_remember_login', true); | |||
$this->manager->prepareTwoFactorLogin($this->user, true); | |||
} | |||
public function testPrepareTwoFactorLoginDontRemember() { | |||
$this->user->expects($this->once()) | |||
->method('getUID') | |||
->will($this->returnValue('ferdinand')); | |||
$this->session->expects($this->at(0)) | |||
->method('set') | |||
->with('two_factor_auth_uid', 'ferdinand'); | |||
$this->session->expects($this->at(1)) | |||
->method('set') | |||
->with('two_factor_remember_login', false); | |||
$this->manager->prepareTwoFactorLogin($this->user); | |||
$this->manager->prepareTwoFactorLogin($this->user, false); | |||
} | |||
} |
@@ -1,5 +1,4 @@ | |||
<?php | |||
/** | |||
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> | |||
* This file is licensed under the Affero General Public License version 3 or | |||
@@ -39,8 +38,16 @@ class SessionTest extends \Test\TestCase { | |||
protected $tokenProvider; | |||
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $config; | |||
/** @var Throttler */ | |||
/** @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; | |||
protected function setUp() { | |||
parent::setUp(); | |||
@@ -52,6 +59,24 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
} | |||
public function testGetUser() { | |||
@@ -100,12 +125,12 @@ class SessionTest extends \Test\TestCase { | |||
->method('updateTokenActivity') | |||
->with($token); | |||
$manager->expects($this->any()) | |||
$manager->expects($this->once()) | |||
->method('get') | |||
->with($expectedUser->getUID()) | |||
->will($this->returnValue($expectedUser)); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); | |||
$user = $userSession->getUser(); | |||
$this->assertSame($expectedUser, $user); | |||
$this->assertSame(10000, $token->getLastCheck()); | |||
@@ -127,7 +152,7 @@ class SessionTest extends \Test\TestCase { | |||
$manager = $this->createMock(Manager::class); | |||
$userSession = $this->getMockBuilder(Session::class) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->setMethods([ | |||
'getUser' | |||
]) | |||
@@ -154,7 +179,7 @@ class SessionTest extends \Test\TestCase { | |||
->method('getUID') | |||
->will($this->returnValue('foo')); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); | |||
$userSession->setUser($user); | |||
} | |||
@@ -181,17 +206,10 @@ class SessionTest extends \Test\TestCase { | |||
}, 'foo')); | |||
$managerMethods = get_class_methods(Manager::class); | |||
//keep following methods intact in order to ensure hooks are | |||
//working | |||
$doNotMock = array('__construct', 'emit', 'listen'); | |||
foreach ($doNotMock as $methodName) { | |||
$i = array_search($methodName, $managerMethods, true); | |||
if ($i !== false) { | |||
unset($managerMethods[$i]); | |||
} | |||
} | |||
//keep following methods intact in order to ensure hooks are working | |||
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']); | |||
$manager = $this->getMockBuilder(Manager::class) | |||
->setMethods($managerMethods) | |||
->setMethods($mockedManagerMethods) | |||
->setConstructorArgs([$this->config]) | |||
->getMock(); | |||
@@ -213,7 +231,7 @@ class SessionTest extends \Test\TestCase { | |||
->will($this->returnValue($user)); | |||
$userSession = $this->getMockBuilder(Session::class) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->setMethods([ | |||
'prepareUserLogin' | |||
]) | |||
@@ -238,18 +256,11 @@ class SessionTest extends \Test\TestCase { | |||
->with('bar') | |||
->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException())); | |||
$managerMethods = get_class_methods('\OC\User\Manager'); | |||
//keep following methods intact in order to ensure hooks are | |||
//working | |||
$doNotMock = array('__construct', 'emit', 'listen'); | |||
foreach ($doNotMock as $methodName) { | |||
$i = array_search($methodName, $managerMethods, true); | |||
if ($i !== false) { | |||
unset($managerMethods[$i]); | |||
} | |||
} | |||
$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($managerMethods) | |||
->setMethods($mockedManagerMethods) | |||
->setConstructorArgs([$this->config]) | |||
->getMock(); | |||
@@ -267,28 +278,21 @@ class SessionTest extends \Test\TestCase { | |||
->with('foo', 'bar') | |||
->will($this->returnValue($user)); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); | |||
$userSession->login('foo', 'bar'); | |||
} | |||
public function testLoginInvalidPassword() { | |||
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); | |||
$managerMethods = get_class_methods('\OC\User\Manager'); | |||
//keep following methods intact in order to ensure hooks are | |||
//working | |||
$doNotMock = array('__construct', 'emit', 'listen'); | |||
foreach ($doNotMock as $methodName) { | |||
$i = array_search($methodName, $managerMethods, true); | |||
if ($i !== false) { | |||
unset($managerMethods[$i]); | |||
} | |||
} | |||
$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($managerMethods) | |||
->setMethods($mockedManagerMethods) | |||
->setConstructorArgs([$this->config]) | |||
->getMock(); | |||
$backend = $this->createMock(\Test\Util\User\Dummy::class); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); | |||
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock(); | |||
@@ -317,7 +321,7 @@ class SessionTest extends \Test\TestCase { | |||
public function testLoginNonExisting() { | |||
$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); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); | |||
$session->expects($this->never()) | |||
->method('set'); | |||
@@ -343,7 +347,7 @@ class SessionTest extends \Test\TestCase { | |||
public function testLoginWithDifferentTokenLoginName() { | |||
$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); | |||
$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); | |||
@@ -375,7 +379,7 @@ class SessionTest extends \Test\TestCase { | |||
/** @var \OC\User\Session $userSession */ | |||
$userSession = $this->getMockBuilder(Session::class) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser']) | |||
->getMock(); | |||
@@ -411,7 +415,7 @@ class SessionTest extends \Test\TestCase { | |||
/** @var Session $userSession */ | |||
$userSession = $this->getMockBuilder(Session::class) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser']) | |||
->getMock(); | |||
@@ -434,7 +438,7 @@ class SessionTest extends \Test\TestCase { | |||
/** @var \OC\User\Session $userSession */ | |||
$userSession = $this->getMockBuilder(Session::class) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser']) | |||
->getMock(); | |||
@@ -476,7 +480,7 @@ class SessionTest extends \Test\TestCase { | |||
/** @var \OC\User\Session $userSession */ | |||
$userSession = $this->getMockBuilder(Session::class) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->setMethods(['login', 'isTwoFactorEnforced']) | |||
->getMock(); | |||
@@ -513,156 +517,216 @@ class SessionTest extends \Test\TestCase { | |||
public function testRememberLoginValidToken() { | |||
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); | |||
$session->expects($this->exactly(1)) | |||
->method('set') | |||
->with($this->callback(function ($key) { | |||
switch ($key) { | |||
case 'user_id': | |||
return true; | |||
default: | |||
return false; | |||
} | |||
}, 'foo')); | |||
$session->expects($this->once()) | |||
->method('regenerateId'); | |||
$managerMethods = get_class_methods(Manager::class); | |||
//keep following methods intact in order to ensure hooks are | |||
//working | |||
$doNotMock = array('__construct', 'emit', 'listen'); | |||
foreach ($doNotMock as $methodName) { | |||
$i = array_search($methodName, $managerMethods, true); | |||
if ($i !== false) { | |||
unset($managerMethods[$i]); | |||
} | |||
} | |||
$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($managerMethods) | |||
->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(); | |||
$backend = $this->createMock(\Test\Util\User\Dummy::class); | |||
$user = $this->createMock(IUser::class); | |||
$token = 'goodToken'; | |||
$oldSessionId = 'sess321'; | |||
$sessionId = 'sess123'; | |||
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock(); | |||
$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); | |||
$session->expects($this->once()) | |||
->method('getId') | |||
->will($this->returnValue($sessionId)); | |||
$this->tokenProvider->expects($this->once()) | |||
->method('renewSessionToken') | |||
->with($oldSessionId, $sessionId) | |||
->will($this->returnValue(true)); | |||
$user->expects($this->any()) | |||
->method('getUID') | |||
->will($this->returnValue('foo')); | |||
$userSession->expects($this->once()) | |||
->method('setMagicInCookie'); | |||
$user->expects($this->once()) | |||
->method('updateLastLoginTimestamp'); | |||
$session->expects($this->once()) | |||
->method('set') | |||
->with('user_id', 'foo'); | |||
$manager->expects($this->once()) | |||
->method('get') | |||
->with('foo') | |||
->will($this->returnValue($user)); | |||
$granted = $userSession->loginWithCookie('foo', $token, $oldSessionId); | |||
//prepare login token | |||
$token = 'goodToken'; | |||
\OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time()); | |||
$this->assertTrue($granted); | |||
} | |||
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(); | |||
$userSession = $this->getMockBuilder(Session::class) | |||
//override, otherwise tests will fail because of setcookie() | |||
->setMethods(['setMagicInCookie']) | |||
//there are passed as parameters to the constructor | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->getMock(); | |||
$granted = $userSession->loginWithCookie('foo', $token); | |||
$this->assertSame($granted, true); | |||
} | |||
$user = $this->createMock(IUser::class); | |||
$token = 'goodToken'; | |||
$oldSessionId = 'sess321'; | |||
$sessionId = 'sess123'; | |||
public function testRememberLoginInvalidToken() { | |||
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); | |||
$session->expects($this->never()) | |||
->method('set'); | |||
$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->config->expects($this->once()) | |||
->method('setUserValue'); // TODO: mock new random value | |||
$managerMethods = get_class_methods('\OC\User\Manager'); | |||
//keep following methods intact in order to ensure hooks are | |||
//working | |||
$doNotMock = array('__construct', 'emit', 'listen'); | |||
foreach ($doNotMock as $methodName) { | |||
$i = array_search($methodName, $managerMethods, true); | |||
if ($i !== false) { | |||
unset($managerMethods[$i]); | |||
} | |||
} | |||
$manager = $this->getMockBuilder(Manager::class) | |||
->setMethods($managerMethods) | |||
->setConstructorArgs([$this->config]) | |||
->getMock(); | |||
$backend = $this->createMock(\Test\Util\User\Dummy::class); | |||
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock(); | |||
$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())); | |||
$user->expects($this->any()) | |||
$user->expects($this->never()) | |||
->method('getUID') | |||
->will($this->returnValue('foo')); | |||
$userSession->expects($this->never()) | |||
->method('setMagicInCookie'); | |||
$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); | |||
} | |||
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'); | |||
$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'); | |||
//prepare login token | |||
$token = 'goodToken'; | |||
\OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time()); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); | |||
$granted = $userSession->loginWithCookie('foo', 'badToken'); | |||
$granted = $userSession->loginWithCookie('foo', $token, $oldSessionId); | |||
$this->assertSame($granted, false); | |||
$this->assertFalse($granted); | |||
} | |||
public function testRememberLoginInvalidUser() { | |||
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); | |||
$session->expects($this->never()) | |||
->method('set'); | |||
$session->expects($this->once()) | |||
->method('regenerateId'); | |||
$managerMethods = get_class_methods('\OC\User\Manager'); | |||
//keep following methods intact in order to ensure hooks are | |||
//working | |||
$doNotMock = array('__construct', 'emit', 'listen'); | |||
foreach ($doNotMock as $methodName) { | |||
$i = array_search($methodName, $managerMethods, true); | |||
if ($i !== false) { | |||
unset($managerMethods[$i]); | |||
} | |||
} | |||
$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($managerMethods) | |||
->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'; | |||
$backend = $this->createMock(\Test\Util\User\Dummy::class); | |||
$user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock(); | |||
$user->expects($this->never()) | |||
->method('getUID'); | |||
$user->expects($this->never()) | |||
->method('updateLastLoginTimestamp'); | |||
$session->expects($this->once()) | |||
->method('regenerateId'); | |||
$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'); | |||
//prepare login token | |||
$token = 'goodToken'; | |||
\OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time()); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); | |||
$granted = $userSession->loginWithCookie('foo', $token); | |||
$granted = $userSession->loginWithCookie('foo', $token, $oldSessionId); | |||
$this->assertSame($granted, false); | |||
$this->assertFalse($granted); | |||
} | |||
public function testActiveUserAfterSetSession() { | |||
@@ -684,7 +748,7 @@ class SessionTest extends \Test\TestCase { | |||
$session = new Memory(''); | |||
$session->set('user_id', 'foo'); | |||
$userSession = $this->getMockBuilder('\OC\User\Session') | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->setMethods([ | |||
'validateSession' | |||
]) | |||
@@ -705,7 +769,7 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
$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); | |||
@@ -749,7 +813,7 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
$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); | |||
@@ -796,7 +860,7 @@ class SessionTest extends \Test\TestCase { | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$session = $this->createMock(ISession::class); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); | |||
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); | |||
$request = $this->createMock(IRequest::class); | |||
$uid = 'user123'; | |||
@@ -826,7 +890,7 @@ class SessionTest extends \Test\TestCase { | |||
$user = $this->createMock(IUser::class); | |||
$userSession = $this->getMockBuilder('\OC\User\Session') | |||
->setMethods(['logout']) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) | |||
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) | |||
->getMock(); | |||
$request = $this->createMock(IRequest::class); | |||
@@ -855,7 +919,7 @@ class SessionTest extends \Test\TestCase { | |||
$timeFactory = $this->createMock(ITimeFactory::class); | |||
$tokenProvider = $this->createMock(IProvider::class); | |||
$userSession = $this->getMockBuilder('\OC\User\Session') | |||
->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config]) | |||
->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random]) | |||
->setMethods(['logout']) | |||
->getMock(); | |||
@@ -902,7 +966,7 @@ class SessionTest extends \Test\TestCase { | |||
$timeFactory = $this->createMock(ITimeFactory::class); | |||
$tokenProvider = $this->createMock(IProvider::class); | |||
$userSession = $this->getMockBuilder('\OC\User\Session') | |||
->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config]) | |||
->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random]) | |||
->setMethods(['logout']) | |||
->getMock(); | |||
@@ -936,7 +1000,7 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
$userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random); | |||
$password = '123456'; | |||
$sessionId = 'session1234'; | |||
@@ -961,7 +1025,7 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
$userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random); | |||
$session->expects($this->once()) | |||
->method('getId') | |||
@@ -975,7 +1039,7 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
$userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random); | |||
$password = '123456'; | |||
$sessionId = 'session1234'; | |||
@@ -1015,7 +1079,7 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
$userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random); | |||
$mapper->expects($this->any()) | |||
->method('getToken') | |||
@@ -1065,7 +1129,7 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
$userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random); | |||
$mapper->expects($this->any()) | |||
->method('getToken') | |||
@@ -1092,4 +1156,27 @@ class SessionTest extends \Test\TestCase { | |||
$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); | |||
} | |||
} |
@@ -25,7 +25,7 @@ | |||
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades | |||
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel | |||
// when updating major/minor version number. | |||
$OC_Version = array(9, 2, 0, 4); | |||
$OC_Version = array(9, 2, 0, 5); | |||
// The human readable string | |||
$OC_VersionString = '11.0 alpha'; |