From d8cde414bd13c327ec2edaf1ae38380073c93e3e Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Mon, 25 Apr 2016 14:10:55 +0200 Subject: token based auth * Add InvalidTokenException * add DefaultTokenMapper and use it to check if a auth token exists * create new token for the browser session if none exists hash stored token; save user agent * encrypt login password when creating the token --- lib/private/legacy/user.php | 25 +++---------------------- lib/private/legacy/util.php | 3 +-- 2 files changed, 4 insertions(+), 24 deletions(-) (limited to 'lib/private/legacy') diff --git a/lib/private/legacy/user.php b/lib/private/legacy/user.php index 7855b5e7059..575011d3985 100644 --- a/lib/private/legacy/user.php +++ b/lib/private/legacy/user.php @@ -6,6 +6,7 @@ * @author Bart Visscher * @author Bartek Przybylski * @author Björn Schießle + * @author Christoph Wurst * @author Florian Preinstorfer * @author Georg Ehrke * @author Jakob Sack @@ -155,6 +156,8 @@ class OC_User { * @return boolean|null * * Log in a user and regenerate a new session - if the password is ok + * + * @deprecated Use \OCP\IUserSession::login */ public static function login($loginName, $password) { @@ -283,28 +286,6 @@ class OC_User { } } - /** - * Tries to login the user with HTTP Basic Authentication - */ - public static function tryBasicAuthLogin() { - if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { - $result = \OC_User::login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); - if($result === true) { - /** - * Add DAV authenticated. This should in an ideal world not be - * necessary but the iOS App reads cookies from anywhere instead - * only the DAV endpoint. - * This makes sure that the cookies will be valid for the whole scope - * @see https://github.com/owncloud/core/issues/22893 - */ - \OC::$server->getSession()->set( - \OCA\DAV\Connector\Sabre\Auth::DAV_AUTHENTICATED, - \OC::$server->getUserSession()->getUser()->getUID() - ); - } - } - } - /** * Check if the user is logged in, considers also the HTTP basic credentials * diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php index b3432470f03..4f7a8668dfc 100644 --- a/lib/private/legacy/util.php +++ b/lib/private/legacy/util.php @@ -957,8 +957,7 @@ class OC_Util { public static function checkLoggedIn() { // Check if we are a user if (!OC_User::isLoggedIn()) { - header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute( - 'core.login.showLoginForm', + header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php', [ 'redirect_url' => \OC::$server->getRequest()->getRequestUri() ] -- cgit v1.2.3 From 3ab922601a2e6b9b170007461b9e0718c70bddcd Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Tue, 26 Apr 2016 11:32:35 +0200 Subject: Check if session token is valid and log user out if the check fails * Update last_activity timestamp of the session token * Check user backend credentials once in 5 minutes --- core/Controller/LoginController.php | 1 - db_structure.xml | 4 +- lib/private/Authentication/Token/DefaultToken.php | 7 +-- .../Authentication/Token/DefaultTokenMapper.php | 6 +- .../Authentication/Token/DefaultTokenProvider.php | 67 ++++++++++++++++++++-- lib/private/User/Session.php | 45 ++++++++++++--- lib/private/legacy/user.php | 2 +- 7 files changed, 107 insertions(+), 25 deletions(-) (limited to 'lib/private/legacy') diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index fe1ad41aedb..e13d8ae10d2 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -26,7 +26,6 @@ namespace OC\Core\Controller; use OC; use OC\User\Session; use OC_App; -use OC_User; use OC_Util; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\RedirectResponse; diff --git a/db_structure.xml b/db_structure.xml index 68a812a6b8f..dcbf426e5b8 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -1057,10 +1057,10 @@ password - text + clob true - 100 + 4000 diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php index 9bdae789afd..6b859d7d063 100644 --- a/lib/private/Authentication/Token/DefaultToken.php +++ b/lib/private/Authentication/Token/DefaultToken.php @@ -51,13 +51,8 @@ class DefaultToken extends Entity implements IToken { */ protected $lastActivity; - /** - * Get the token ID - * - * @return string - */ public function getId() { - return $this->token; + return $this->id; } } diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php index 9a73192c0d8..d54d2489399 100644 --- a/lib/private/Authentication/Token/DefaultTokenMapper.php +++ b/lib/private/Authentication/Token/DefaultTokenMapper.php @@ -61,10 +61,10 @@ class DefaultTokenMapper extends Mapper { * * @param string $token * @throws DoesNotExistException - * @return string + * @return DefaultToken */ - public function getTokenUser($token) { - $sql = 'SELECT `uid` ' + public function getToken($token) { + $sql = 'SELECT `id`, `uid`, `password`, `name`, `token`, `last_activity` ' . 'FROM `' . $this->getTableName() . '` ' . 'WHERE `token` = ?'; return $this->findEntity($sql, [ diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index 71f798da370..b3564e0e81b 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -48,8 +48,7 @@ class DefaultTokenProvider implements IProvider { * @param IConfig $config * @param ILogger $logger */ - public function __construct(DefaultTokenMapper $mapper, ICrypto $crypto, - IConfig $config, ILogger $logger) { + public function __construct(DefaultTokenMapper $mapper, ICrypto $crypto, IConfig $config, ILogger $logger) { $this->mapper = $mapper; $this->crypto = $crypto; $this->config = $config; @@ -67,8 +66,7 @@ class DefaultTokenProvider implements IProvider { public function generateToken($token, $uid, $password, $name) { $dbToken = new DefaultToken(); $dbToken->setUid($uid); - $secret = $this->config->getSystemValue('secret'); - $dbToken->setPassword($this->crypto->encrypt($password . $secret)); + $dbToken->setPassword($this->encryptPassword($password, $token)); $dbToken->setName($name); $dbToken->setToken($this->hashToken($token)); $dbToken->setLastActivity(time()); @@ -78,6 +76,37 @@ class DefaultTokenProvider implements IProvider { return $dbToken; } + /** + * Update token activity timestamp + * + * @param DefaultToken $token + */ + public function updateToken(DefaultToken $token) { + $token->setLastActivity(time()); + + $this->mapper->update($token); + } + + /** + * @param string $token + * @throws InvalidTokenException + */ + public function getToken($token) { + try { + return $this->mapper->getToken($this->hashToken($token)); + } catch (DoesNotExistException $ex) { + throw new InvalidTokenException(); + } + } + + /** + * @param DefaultToken $savedToken + * @param string $token session token + */ + public function getPassword(DefaultToken $savedToken, $token) { + return $this->decryptPassword($savedToken->getPassword(), $token); + } + /** * Invalidate (delete) the given session token * @@ -104,7 +133,7 @@ class DefaultTokenProvider implements IProvider { public function validateToken($token) { $this->logger->debug('validating default token <' . $token . '>'); try { - $dbToken = $this->mapper->getTokenUser($this->hashToken($token)); + $dbToken = $this->mapper->getToken($this->hashToken($token)); $this->logger->debug('valid token for ' . $dbToken->getUid()); return $dbToken->getUid(); } catch (DoesNotExistException $ex) { @@ -121,4 +150,32 @@ class DefaultTokenProvider implements IProvider { return hash('sha512', $token); } + /** + * Encrypt the given password + * + * The token is used as key + * + * @param string $password + * @param string $token + * @return string encrypted password + */ + private function encryptPassword($password, $token) { + $secret = $this->config->getSystemValue('secret'); + return $this->crypto->encrypt($password, $token . $secret); + } + + /** + * Decrypt the given password + * + * The token is used as key + * + * @param string $password + * @param string $token + * @return string the decrypted key + */ + private function decryptPassword($password, $token) { + $secret = $this->config->getSystemValue('secret'); + return $this->crypto->decrypt($password, $token . $secret); + } + } diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 9db503e6add..7d4594e7205 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -96,8 +96,7 @@ class Session implements IUserSession, Emitter { * @param ISession $session * @param IProvider[] $tokenProviders */ - public function __construct(IUserManager $manager, ISession $session, - DefaultTokenProvider $tokenProvider, array $tokenProviders = []) { + public function __construct(IUserManager $manager, ISession $session, DefaultTokenProvider $tokenProvider, array $tokenProviders = []) { $this->manager = $manager; $this->session = $session; $this->tokenProvider = $tokenProvider; @@ -118,8 +117,7 @@ class Session implements IUserSession, Emitter { * @param string $method optional * @param callable $callback optional */ - public function removeListener($scope = null, $method = null, - callable $callback = null) { + public function removeListener($scope = null, $method = null, callable $callback = null) { $this->manager->removeListener($scope, $method, $callback); } @@ -183,8 +181,7 @@ class Session implements IUserSession, Emitter { return $this->activeUser; } else { $uid = $this->session->get('user_id'); - if ($uid !== null) { - $this->activeUser = $this->manager->get($uid); + if ($uid !== null && $this->isValidSession($uid)) { return $this->activeUser; } else { return null; @@ -192,6 +189,41 @@ class Session implements IUserSession, Emitter { } } + private function isValidSession($uid) { + $this->activeUser = $this->manager->get($uid); + if (is_null($this->activeUser)) { + // User does not exist + return false; + } + // TODO: use ISession::getId(), https://github.com/owncloud/core/pull/24229 + $sessionId = session_id(); + try { + $token = $this->tokenProvider->getToken($sessionId); + } catch (InvalidTokenException $ex) { + // Session was inalidated + $this->logout(); + return false; + } + + // Check whether login credentials are still valid + // This check is performed each 5 minutes + $lastCheck = $this->session->get('last_login_check') ? : 0; + if ($lastCheck < (time() - 60 * 5)) { + $pwd = $this->tokenProvider->getPassword($token, $sessionId); + if ($this->manager->checkPassword($uid, $pwd) === false) { + // Password has changed -> log user out + $this->logout(); + return false; + } + $this->session->set('last_login_check', time()); + } + + // Session is valid, so the token can be refreshed + $this->tokenProvider->updateToken($token); + + return true; + } + /** * Checks whether the user is logged in * @@ -334,7 +366,6 @@ class Session implements IUserSession, Emitter { * @return boolean */ private function validateToken(IRequest $request, $token) { - // TODO: hash token foreach ($this->tokenProviders as $provider) { try { $user = $provider->validateToken($token); diff --git a/lib/private/legacy/user.php b/lib/private/legacy/user.php index 575011d3985..ca408d347bd 100644 --- a/lib/private/legacy/user.php +++ b/lib/private/legacy/user.php @@ -68,7 +68,7 @@ class OC_User { private static $_setupedBackends = array(); - // bool, stores if a user want to access a resource anonymously, e.g if he opens a public link + // bool, stores if a user want to access a resource anonymously, e.g if they open a public link private static $incognitoMode = false; /** -- cgit v1.2.3 From fdc2cd755477220c027e026aa70594af87427bed Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Wed, 27 Apr 2016 09:38:30 +0200 Subject: Add token auth for OCS APIs --- core/Controller/LoginController.php | 2 +- core/Controller/TokenController.php | 8 +++- lib/private/Authentication/Token/DefaultToken.php | 4 ++ .../Authentication/Token/DefaultTokenProvider.php | 10 +++-- lib/private/Authentication/Token/IProvider.php | 9 ++++- lib/private/Authentication/Token/IToken.php | 7 ++++ lib/private/User/Session.php | 34 ++++++++++++----- lib/private/legacy/api.php | 43 ++++++++-------------- 8 files changed, 73 insertions(+), 44 deletions(-) (limited to 'lib/private/legacy') diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index e13d8ae10d2..7afed6b274a 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -172,7 +172,7 @@ class LoginController extends Controller { if ($this->userManager->checkPassword($user, $password) === false) { return new RedirectResponse($this->urlGenerator->linkToRoute('login#showLoginForm')); } - $this->userSession->createSessionToken($user, $password); + $this->userSession->createSessionToken($this->request, $user, $password); if (!is_null($redirect_url) && $this->userSession->isLoggedIn()) { $location = OC::$server->getURLGenerator()->getAbsoluteURL(urldecode($redirect_url)); // Deny the redirect if the URL contains a @ diff --git a/core/Controller/TokenController.php b/core/Controller/TokenController.php index 8a25ad9bb98..d1d7b50d084 100644 --- a/core/Controller/TokenController.php +++ b/core/Controller/TokenController.php @@ -68,10 +68,14 @@ class TokenController extends Controller { */ public function generateToken($user, $password, $name = 'unknown client') { if (is_null($user) || is_null($password)) { - return new Response([], Http::STATUS_UNPROCESSABLE_ENTITY); + $response = new Response([]); + $response->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); + return $response; } if ($this->userManager->checkPassword($user, $password) === false) { - return new Response([], Http::STATUS_UNAUTHORIZED); + $response = new Response([]); + $response->setStatus(Http::STATUS_UNAUTHORIZED); + return $response; } $token = $this->secureRandom->generate(128); $this->tokenProvider->generateToken($token, $user, $password, $name, IToken::PERMANENT_TOKEN); diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php index 78b5c2d6116..70562502b76 100644 --- a/lib/private/Authentication/Token/DefaultToken.php +++ b/lib/private/Authentication/Token/DefaultToken.php @@ -60,4 +60,8 @@ class DefaultToken extends Entity implements IToken { return $this->id; } + public function getUid() { + return $this->uid; + } + } diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index a4e44f3c5d2..97567e53cd0 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -83,7 +83,11 @@ class DefaultTokenProvider implements IProvider { * * @param DefaultToken $token */ - public function updateToken(DefaultToken $token) { + public function updateToken(IToken $token) { + if (!($token instanceof DefaultToken)) { + throw new InvalidTokenException(); + } + /** @var DefaultToken $token */ $token->setLastActivity(time()); $this->mapper->update($token); @@ -130,14 +134,14 @@ class DefaultTokenProvider implements IProvider { /** * @param string $token * @throws InvalidTokenException - * @return string user UID + * @return IToken user UID */ public function validateToken($token) { $this->logger->debug('validating default token <' . $token . '>'); try { $dbToken = $this->mapper->getToken($this->hashToken($token)); $this->logger->debug('valid token for ' . $dbToken->getUid()); - return $dbToken->getUid(); + return $dbToken; } catch (DoesNotExistException $ex) { $this->logger->warning('invalid token'); throw new InvalidTokenException(); diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index 4fceef19a1c..5c0b0d140ae 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -29,7 +29,14 @@ interface IProvider { /** * @param string $token * @throws InvalidTokenException - * @return string user UID + * @return IToken */ public function validateToken($token); + + /** + * Update token activity timestamp + * + * @param DefaultToken $token + */ + public function updateToken(IToken $token); } diff --git a/lib/private/Authentication/Token/IToken.php b/lib/private/Authentication/Token/IToken.php index 549a1f98268..90feefb4589 100644 --- a/lib/private/Authentication/Token/IToken.php +++ b/lib/private/Authentication/Token/IToken.php @@ -36,4 +36,11 @@ interface IToken { * @return string */ public function getId(); + + /** + * Get the user UID + * + * @return string + */ + public function getUid(); } diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 976a2627735..7fac36626e2 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -37,6 +37,7 @@ use OC; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Token\DefaultTokenProvider; use OC\Authentication\Token\IProvider; +use OC\Authentication\Token\IToken; use OC\Hooks\Emitter; use OC_User; use OCA\DAV\Connector\Sabre\Auth; @@ -218,12 +219,7 @@ class Session implements IUserSession, Emitter { } // Session is valid, so the token can be refreshed - // To save unnecessary DB queries, this is only done once a minute - $lastTokenUpdate = $this->session->get('last_token_update') ? : 0; - if ($lastTokenUpdate < (time () - 60)) { - $this->tokenProvider->updateToken($token); - $this->session->set('last_token_update', time()); - } + $this->updateToken($this->tokenProvider, $token); return true; } @@ -311,6 +307,7 @@ class Session implements IUserSession, Emitter { /** * Tries to login the user with HTTP Basic Authentication + * @return boolean if the login was successful */ public function tryBasicAuthLogin() { if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { @@ -327,7 +324,9 @@ class Session implements IUserSession, Emitter { Auth::DAV_AUTHENTICATED, $this->getUser()->getUID() ); } + return $result; } + return false; } private function loginWithToken($uid) { @@ -347,11 +346,12 @@ class Session implements IUserSession, Emitter { /** * Create a new session token for the given user credentials * + * @param IRequest $request * @param string $uid user UID * @param string $password * @return boolean */ - public function createSessionToken($uid, $password) { + public function createSessionToken(IRequest $request, $uid, $password) { $this->session->regenerateId(); if (is_null($this->manager->get($uid))) { // User does not exist @@ -372,11 +372,12 @@ class Session implements IUserSession, Emitter { private function validateToken(IRequest $request, $token) { foreach ($this->tokenProviders as $provider) { try { - $user = $provider->validateToken($token); - if (!is_null($user)) { - $result = $this->loginWithToken($user); + $token = $provider->validateToken($token); + if (!is_null($token)) { + $result = $this->loginWithToken($token->getUid()); if ($result) { // Login success + $this->updateToken($provider, $token); return true; } } @@ -387,6 +388,19 @@ class Session implements IUserSession, Emitter { return false; } + /** + * @param IProvider $provider + * @param IToken $token + */ + private function updateToken(IProvider $provider, IToken $token) { + // To save unnecessary DB queries, this is only done once a minute + $lastTokenUpdate = $this->session->get('last_token_update') ? : 0; + if ($lastTokenUpdate < (time () - 60)) { + $provider->updateToken($token); + $this->session->set('last_token_update', time()); + } + } + /** * Tries to login the user with auth token header * diff --git a/lib/private/legacy/api.php b/lib/private/legacy/api.php index 702b9df1927..3fcd9a93ec1 100644 --- a/lib/private/legacy/api.php +++ b/lib/private/legacy/api.php @@ -337,7 +337,7 @@ class OC_API { } // reuse existing login - $loggedIn = OC_User::isLoggedIn(); + $loggedIn = \OC::$server->getUserSession()->isLoggedIn(); if ($loggedIn === true) { $ocsApiRequest = isset($_SERVER['HTTP_OCS_APIREQUEST']) ? $_SERVER['HTTP_OCS_APIREQUEST'] === 'true' : false; if ($ocsApiRequest) { @@ -353,35 +353,24 @@ class OC_API { // basic auth - because OC_User::login will create a new session we shall only try to login // if user and pass are set - if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) ) { - $authUser = $_SERVER['PHP_AUTH_USER']; - $authPw = $_SERVER['PHP_AUTH_PW']; - try { - $return = OC_User::login($authUser, $authPw); - } catch (\OC\User\LoginException $e) { - return false; + $userSession = \OC::$server->getUserSession(); + try { + $loginSuccess = $userSession->tryTokenLogin(); + if (!$loginSuccess) { + $loginSuccess = $userSession->tryBasicAuthLogin(); } - if ($return === true) { - self::$logoutRequired = true; - - // initialize the user's filesystem - \OC_Util::setUpFS(\OC_User::getUser()); - self::$isLoggedIn = true; + } catch (\OC\User\LoginException $e) { + return false; + } + + if ($loginSuccess === true) { + self::$logoutRequired = true; - /** - * Add DAV authenticated. This should in an ideal world not be - * necessary but the iOS App reads cookies from anywhere instead - * only the DAV endpoint. - * This makes sure that the cookies will be valid for the whole scope - * @see https://github.com/owncloud/core/issues/22893 - */ - \OC::$server->getSession()->set( - \OCA\DAV\Connector\Sabre\Auth::DAV_AUTHENTICATED, - \OC::$server->getUserSession()->getUser()->getUID() - ); + // initialize the user's filesystem + \OC_Util::setUpFS(\OC_User::getUser()); + self::$isLoggedIn = true; - return \OC_User::getUser(); - } + return \OC_User::getUser(); } return false; -- cgit v1.2.3 From 7aa16e1559e8ef1121ac2529090a6881b4d919d5 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Wed, 27 Apr 2016 12:01:13 +0200 Subject: fix setup --- core/Controller/LoginController.php | 15 +++++++++++---- lib/private/Server.php | 17 ++++++++++++----- lib/private/Setup.php | 9 ++++++++- lib/private/User/Session.php | 28 ++++++++++++++++++++++------ lib/private/legacy/user.php | 32 -------------------------------- 5 files changed, 53 insertions(+), 48 deletions(-) (limited to 'lib/private/legacy') diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index 7afed6b274a..ba9fc55d451 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -63,9 +63,8 @@ class LoginController extends Controller { * @param Session $userSession * @param IURLGenerator $urlGenerator */ - function __construct($appName, IRequest $request, IUserManager $userManager, - IConfig $config, ISession $session, Session $userSession, - IURLGenerator $urlGenerator) { + function __construct($appName, IRequest $request, IUserManager $userManager, IConfig $config, ISession $session, + Session $userSession, IURLGenerator $urlGenerator) { parent::__construct($appName, $request); $this->userManager = $userManager; $this->config = $config; @@ -169,7 +168,15 @@ class LoginController extends Controller { */ public function tryLogin($user, $password, $redirect_url) { // TODO: Add all the insane error handling - if ($this->userManager->checkPassword($user, $password) === false) { + $loginResult = $this->userManager->checkPassword($user, $password) === false; + if ($loginResult) { + $users = $this->userManager->getByEmail($user); + // we only allow login by email if unique + if (count($users) === 1) { + $loginResult = $this->userManager->checkPassword($users[0]->getUID(), $password); + } + } + if ($loginResult) { return new RedirectResponse($this->urlGenerator->linkToRoute('login#showLoginForm')); } $this->userSession->createSessionToken($this->request, $user, $password); diff --git a/lib/private/Server.php b/lib/private/Server.php index 8af2f02479c..b17c1a384dc 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -223,11 +223,18 @@ class Server extends ServerContainer implements IServerContainer { $this->registerService('UserSession', function (Server $c) { $manager = $c->getUserManager(); $session = new \OC\Session\Memory(''); - $defaultTokenProvider = $c->query('OC\Authentication\Token\DefaultTokenProvider'); - $tokenProviders = [ - $defaultTokenProvider, - ]; - + // Token providers might require a working database. This code + // might however be called when ownCloud is not yet setup. + if (\OC::$server->getSystemConfig()->getValue('installed', false)) { + $defaultTokenProvider = $c->query('OC\Authentication\Token\DefaultTokenProvider'); + $tokenProviders = [ + $defaultTokenProvider, + ]; + } else { + $defaultTokenProvider = null; + $tokenProviders = []; + } + $userSession = new \OC\User\Session($manager, $session, $defaultTokenProvider, $tokenProviders); $userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) { \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password)); diff --git a/lib/private/Setup.php b/lib/private/Setup.php index 94197f7f27f..67d714188ac 100644 --- a/lib/private/Setup.php +++ b/lib/private/Setup.php @@ -364,7 +364,14 @@ class Setup { $group =\OC::$server->getGroupManager()->createGroup('admin'); $group->addUser($user); - \OC_User::login($username, $password); + + // Create a session token for the newly created user + // The token provider requires a working db, so it's not injected on setup + /* @var $userSession User\Session */ + $userSession = \OC::$server->getUserSession(); + $defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider'); + $userSession->setTokenProvider($defaultTokenProvider); + $userSession->createSessionToken($request, $username, $password); //guess what this does Installer::installShippedApps(); diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index bb35b65b272..262174ab172 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -96,13 +96,20 @@ class Session implements IUserSession, Emitter { * @param ISession $session * @param IProvider[] $tokenProviders */ - public function __construct(IUserManager $manager, ISession $session, DefaultTokenProvider $tokenProvider, array $tokenProviders = []) { + public function __construct(IUserManager $manager, ISession $session, $tokenProvider, array $tokenProviders = []) { $this->manager = $manager; $this->session = $session; $this->tokenProvider = $tokenProvider; $this->tokenProviders = $tokenProviders; } + /** + * @param DefaultTokenProvider $provider + */ + public function setTokenProvider(DefaultTokenProvider $provider) { + $this->tokenProvider = $provider; + } + /** * @param string $scope * @param string $method @@ -296,6 +303,13 @@ class Session implements IUserSession, Emitter { $this->setLoginName($uid); $this->manager->emit('\OC\User', 'postLogin', array($user, $password)); if ($this->isLoggedIn()) { + // Refresh the token + \OC::$server->getCsrfTokenManager()->refreshToken(); + //we need to pass the user name, which may differ from login name + $user = $this->getUser()->getUID(); + \OC_Util::setupFS($user); + //trigger creation of user home and /files folder + \OC::$server->getUserFolder($user); return true; } else { // injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory @@ -359,16 +373,18 @@ class Session implements IUserSession, Emitter { * @return boolean */ public function createSessionToken(IRequest $request, $uid, $password) { - $this->session->regenerateId(); if (is_null($this->manager->get($uid))) { // User does not exist return false; } $name = isset($request->server['HTTP_USER_AGENT']) ? $request->server['HTTP_USER_AGENT'] : 'unknown browser'; // TODO: use ISession::getId(), https://github.com/owncloud/core/pull/24229 - $sessionId = session_id(); - $token = $this->tokenProvider->generateToken($sessionId, $uid, $password, $name); - return $this->loginWithToken($uid); + $loggedIn = $this->login($uid, $password); + if ($loggedIn) { + $sessionId = session_id(); + $this->tokenProvider->generateToken($sessionId, $uid, $password, $name); + } + return $loggedIn; } /** @@ -402,7 +418,7 @@ class Session implements IUserSession, Emitter { private function updateToken(IProvider $provider, IToken $token) { // To save unnecessary DB queries, this is only done once a minute $lastTokenUpdate = $this->session->get('last_token_update') ? : 0; - if ($lastTokenUpdate < (time () - 60)) { + if ($lastTokenUpdate < (time() - 60)) { $provider->updateToken($token); $this->session->set('last_token_update', time()); } diff --git a/lib/private/legacy/user.php b/lib/private/legacy/user.php index ca408d347bd..499e916994a 100644 --- a/lib/private/legacy/user.php +++ b/lib/private/legacy/user.php @@ -149,39 +149,7 @@ class OC_User { } /** - * Try to login a user - * - * @param string $loginName The login name of the user to log in - * @param string $password The password of the user - * @return boolean|null - * - * Log in a user and regenerate a new session - if the password is ok - * - * @deprecated Use \OCP\IUserSession::login - */ - public static function login($loginName, $password) { - $result = self::getUserSession()->login($loginName, $password); - if (!$result) { - $users = \OC::$server->getUserManager()->getByEmail($loginName); - // we only allow login by email if unique - if (count($users) === 1) { - $result = self::getUserSession()->login($users[0]->getUID(), $password); - } - } - if ($result) { - // Refresh the token - \OC::$server->getCsrfTokenManager()->refreshToken(); - //we need to pass the user name, which may differ from login name - $user = self::getUserSession()->getUser()->getUID(); - OC_Util::setupFS($user); - //trigger creation of user home and /files folder - \OC::$server->getUserFolder($user); - } - return $result; - } - - /** * Try to login a user using the magic cookie (remember login) * * @deprecated use \OCP\IUserSession::loginWithCookie() -- cgit v1.2.3 From 699289cd26d3101c18b72e287de77282c782c9cc Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Fri, 29 Apr 2016 14:00:07 +0200 Subject: pass in $request on OCS api --- lib/private/User/Session.php | 2 ++ lib/private/legacy/api.php | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/private/legacy') diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index b72e4e1a1ed..72fb8bc41d0 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -330,6 +330,8 @@ class Session implements IUserSession, Emitter { /** * Tries to login the user with HTTP Basic Authentication + * + * @param IRequest $request * @return boolean if the login was successful */ public function tryBasicAuthLogin(IRequest $request) { diff --git a/lib/private/legacy/api.php b/lib/private/legacy/api.php index 3fcd9a93ec1..e3d597fc64e 100644 --- a/lib/private/legacy/api.php +++ b/lib/private/legacy/api.php @@ -354,8 +354,9 @@ class OC_API { // basic auth - because OC_User::login will create a new session we shall only try to login // if user and pass are set $userSession = \OC::$server->getUserSession(); + $request = \OC::$server->getRequest(); try { - $loginSuccess = $userSession->tryTokenLogin(); + $loginSuccess = $userSession->tryTokenLogin($request); if (!$loginSuccess) { $loginSuccess = $userSession->tryBasicAuthLogin(); } -- cgit v1.2.3 From 46bdf6ea2b1e10c2f4d2fae214ecc81b188fa981 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Fri, 6 May 2016 16:31:40 +0200 Subject: fix PHPDoc and other minor issues --- build/integration/features/bootstrap/Auth.php | 4 +- core/Controller/LoginController.php | 4 +- core/Controller/TokenController.php | 3 +- lib/private/Authentication/Token/DefaultToken.php | 2 +- .../Authentication/Token/DefaultTokenProvider.php | 11 ++++-- lib/private/Authentication/Token/IProvider.php | 2 +- lib/private/Authentication/Token/IToken.php | 2 +- lib/private/Files/Filesystem.php | 2 +- lib/private/Updater.php | 1 + lib/private/User/Session.php | 45 ++++++++++------------ lib/private/legacy/api.php | 2 +- .../token/defaulttokenmappertest.php | 4 +- .../token/defaulttokenprovidertest.php | 36 ++++++++--------- tests/lib/user/session.php | 27 ++++++++----- 14 files changed, 77 insertions(+), 68 deletions(-) (limited to 'lib/private/legacy') diff --git a/build/integration/features/bootstrap/Auth.php b/build/integration/features/bootstrap/Auth.php index 88edcd49a5b..5f36b199e06 100644 --- a/build/integration/features/bootstrap/Auth.php +++ b/build/integration/features/bootstrap/Auth.php @@ -61,14 +61,14 @@ trait Auth { * @When requesting :url with :method using basic auth */ public function requestingWithBasicAuth($url, $method) { - $this->sendRequest($url, $method, 'basic ' . base64_encode('user:user')); + $this->sendRequest($url, $method, 'basic ' . base64_encode('user0:123456')); } /** * @When requesting :url with :method using basic token auth */ public function requestingWithBasicTokenAuth($url, $method) { - $this->sendRequest($url, $method, 'basic ' . base64_encode('user:' . $this->clientToken)); + $this->sendRequest($url, $method, 'basic ' . base64_encode('user0:' . $this->clientToken)); } /** diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index 977f523afda..df5ece9671b 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -98,7 +98,7 @@ class LoginController extends Controller { * @param string $redirect_url * @param string $remember_login * - * @return TemplateResponse + * @return TemplateResponse|RedirectResponse */ public function showLoginForm($user, $redirect_url, $remember_login) { if ($this->userSession->isLoggedIn()) { @@ -106,7 +106,6 @@ class LoginController extends Controller { } $parameters = array(); - $id = $this->session->getId(); $loginMessages = $this->session->get('loginMessages'); $errors = []; $messages = []; @@ -177,7 +176,6 @@ class LoginController extends Controller { } } if (!$loginResult) { - $id = $this->session->getId(); $this->session->set('loginMessages', [ [], ['invalidpassword'] diff --git a/core/Controller/TokenController.php b/core/Controller/TokenController.php index 6f98face144..6606a3c8345 100644 --- a/core/Controller/TokenController.php +++ b/core/Controller/TokenController.php @@ -27,6 +27,7 @@ use OC\Authentication\Token\DefaultTokenProvider; use OC\Authentication\Token\IToken; use OC\User\Manager; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\Response; use OCP\IRequest; use OCP\Security\ISecureRandom; @@ -66,7 +67,7 @@ class TokenController extends Controller { * @param string $user * @param string $password * @param string $name the name of the client - * @return Response + * @return JSONResponse */ public function generateToken($user, $password, $name = 'unknown client') { if (is_null($user) || is_null($password)) { diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php index 5dd9dc5b039..25caf675a43 100644 --- a/lib/private/Authentication/Token/DefaultToken.php +++ b/lib/private/Authentication/Token/DefaultToken.php @@ -74,7 +74,7 @@ class DefaultToken extends Entity implements IToken { return $this->id; } - public function getUid() { + public function getUID() { return $this->uid; } diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index a0d07f9e2e2..53ecb562a8d 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -51,6 +51,7 @@ class DefaultTokenProvider implements IProvider { * @param ICrypto $crypto * @param IConfig $config * @param ILogger $logger + * @param ITimeFactory $time */ public function __construct(DefaultTokenMapper $mapper, ICrypto $crypto, IConfig $config, ILogger $logger, ITimeFactory $time) { $this->mapper = $mapper; @@ -66,6 +67,7 @@ class DefaultTokenProvider implements IProvider { * @param string $token * @param string $uid * @param string $password + * @param string $name * @param int $type token type * @return DefaultToken */ @@ -86,7 +88,8 @@ class DefaultTokenProvider implements IProvider { /** * Update token activity timestamp * - * @param DefaultToken $token + * @throws InvalidTokenException + * @param IToken $token */ public function updateToken(IToken $token) { if (!($token instanceof DefaultToken)) { @@ -101,6 +104,7 @@ class DefaultTokenProvider implements IProvider { /** * @param string $token * @throws InvalidTokenException + * @return DefaultToken */ public function getToken($token) { try { @@ -113,6 +117,7 @@ class DefaultTokenProvider implements IProvider { /** * @param DefaultToken $savedToken * @param string $token session token + * @return string */ public function getPassword(DefaultToken $savedToken, $token) { return $this->decryptPassword($savedToken->getPassword(), $token); @@ -139,13 +144,13 @@ class DefaultTokenProvider implements IProvider { /** * @param string $token * @throws InvalidTokenException - * @return IToken user UID + * @return DefaultToken user UID */ public function validateToken($token) { $this->logger->debug('validating default token <' . $token . '>'); try { $dbToken = $this->mapper->getToken($this->hashToken($token)); - $this->logger->debug('valid token for ' . $dbToken->getUid()); + $this->logger->debug('valid token for ' . $dbToken->getUID()); return $dbToken; } catch (DoesNotExistException $ex) { $this->logger->warning('invalid token'); diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index 5c0b0d140ae..f8a3262ca8b 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -36,7 +36,7 @@ interface IProvider { /** * Update token activity timestamp * - * @param DefaultToken $token + * @param IToken $token */ public function updateToken(IToken $token); } diff --git a/lib/private/Authentication/Token/IToken.php b/lib/private/Authentication/Token/IToken.php index 90feefb4589..9b2bd18f83b 100644 --- a/lib/private/Authentication/Token/IToken.php +++ b/lib/private/Authentication/Token/IToken.php @@ -42,5 +42,5 @@ interface IToken { * * @return string */ - public function getUid(); + public function getUID(); } diff --git a/lib/private/Files/Filesystem.php b/lib/private/Files/Filesystem.php index 89b8547aa52..99c123ad1a1 100644 --- a/lib/private/Files/Filesystem.php +++ b/lib/private/Files/Filesystem.php @@ -404,7 +404,7 @@ class Filesystem { if (is_null($userObject)) { \OCP\Util::writeLog('files', ' Backends provided no user object for ' . $user, \OCP\Util::ERROR); - throw new \OC\User\NoUserException('Backend provided no user object for ' . $user); + throw new \OC\User\NoUserException('Backends provided no user object for ' . $user); } self::$usersSetup[$user] = true; diff --git a/lib/private/Updater.php b/lib/private/Updater.php index fd082c837e0..dbcaccaad26 100644 --- a/lib/private/Updater.php +++ b/lib/private/Updater.php @@ -216,6 +216,7 @@ class Updater extends BasicEmitter { try { Setup::updateHtaccess(); Setup::protectDataDirectory(); + // TODO: replace with the new repair step mechanism https://github.com/owncloud/core/pull/24378 Setup::installBackgroundJobs(); } catch (\Exception $e) { throw new \Exception($e->getMessage()); diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 297ebb2aaf0..0351125b5d9 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -97,11 +97,14 @@ class Session implements IUserSession, Emitter { /** * @var User $activeUser + */ protected $activeUser; /** * @param IUserManager $manager * @param ISession $session + * @param ITimeFactory $timeFacory + * @param IProvider $tokenProvider * @param IProvider[] $tokenProviders */ public function __construct(IUserManager $manager, ISession $session, ITimeFactory $timeFacory, $tokenProvider, @@ -219,7 +222,7 @@ class Session implements IUserSession, Emitter { } catch (InvalidTokenException $ex) { // Session was invalidated $this->logout(); - return false; + return; } // Check whether login credentials are still valid @@ -231,15 +234,13 @@ class Session implements IUserSession, Emitter { if ($this->manager->checkPassword($user->getUID(), $pwd) === false) { // Password has changed -> log user out $this->logout(); - return false; + return; } $this->session->set('last_login_check', $now); } // Session is valid, so the token can be refreshed $this->updateToken($this->tokenProvider, $token); - - return true; } /** @@ -301,9 +302,7 @@ class Session implements IUserSession, Emitter { $this->manager->emit('\OC\User', 'preLogin', array($uid, $password)); $user = $this->manager->checkPassword($uid, $password); if ($user === false) { - // Password auth failed, maybe it's a token - $request = \OC::$server->getRequest(); - if ($this->validateToken($request, $password)) { + if ($this->validateToken($password)) { $user = $this->getUser(); } } @@ -349,9 +348,8 @@ class Session implements IUserSession, Emitter { * @return boolean if the login was successful */ public function tryBasicAuthLogin(IRequest $request) { - // TODO: use $request->server instead of super globals - if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { - $result = $this->login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + if (!empty($request->server['PHP_AUTH_USER']) && !empty($request->server['PHP_AUTH_PW'])) { + $result = $this->login($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW']); if ($result === true) { /** * Add DAV authenticated. This should in an ideal world not be @@ -363,14 +361,14 @@ class Session implements IUserSession, Emitter { $this->session->set( Auth::DAV_AUTHENTICATED, $this->getUser()->getUID() ); + return true; } - return $result; } return false; } private function loginWithToken($uid) { - //$this->manager->emit('\OC\User', 'preTokenLogin', array($uid)); + // TODO: $this->manager->emit('\OC\User', 'preTokenLogin', array($uid)); $user = $this->manager->get($uid); if (is_null($user)) { // user does not exist @@ -379,7 +377,7 @@ class Session implements IUserSession, Emitter { //login $this->setUser($user); - //$this->manager->emit('\OC\User', 'postTokenLogin', array($user)); + // TODO: $this->manager->emit('\OC\User', 'postTokenLogin', array($user)); return true; } @@ -410,16 +408,15 @@ class Session implements IUserSession, Emitter { } /** - * @param IRequest $request * @param string $token * @return boolean */ - private function validateToken(IRequest $request, $token) { + private function validateToken($token) { foreach ($this->tokenProviders as $provider) { try { $token = $provider->validateToken($token); if (!is_null($token)) { - $result = $this->loginWithToken($token->getUid()); + $result = $this->loginWithToken($token->getUID()); if ($result) { // Login success $this->updateToken($provider, $token); @@ -458,13 +455,13 @@ class Session implements IUserSession, Emitter { // No auth header, let's try session id try { $sessionId = $this->session->getId(); - return $this->validateToken($request, $sessionId); + return $this->validateToken($sessionId); } catch (SessionNotAvailableException $ex) { return false; } } else { $token = substr($authHeader, 6); - return $this->validateToken($request, $token); + return $this->validateToken($token); } } @@ -530,9 +527,9 @@ 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); + 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); } /** @@ -542,9 +539,9 @@ 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"]); + 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); diff --git a/lib/private/legacy/api.php b/lib/private/legacy/api.php index e3d597fc64e..60300c88b57 100644 --- a/lib/private/legacy/api.php +++ b/lib/private/legacy/api.php @@ -358,7 +358,7 @@ class OC_API { try { $loginSuccess = $userSession->tryTokenLogin($request); if (!$loginSuccess) { - $loginSuccess = $userSession->tryBasicAuthLogin(); + $loginSuccess = $userSession->tryBasicAuthLogin($request); } } catch (\OC\User\LoginException $e) { return false; diff --git a/tests/lib/authentication/token/defaulttokenmappertest.php b/tests/lib/authentication/token/defaulttokenmappertest.php index 1f0fdc160e9..b77bf31aa48 100644 --- a/tests/lib/authentication/token/defaulttokenmappertest.php +++ b/tests/lib/authentication/token/defaulttokenmappertest.php @@ -79,12 +79,12 @@ class DefaultTokenMapperTest extends TestCase { private function getNumberOfTokens() { $qb = $this->dbConnection->getQueryBuilder(); - $result = $qb->select($qb->createFunction('COUNT(*)')) + $result = $qb->select($qb->createFunction('count(*) as `count`')) ->from('authtoken') ->execute() ->fetch(); print_r($result); - return (int) $result['COUNT(*)']; + return (int) $result['count']; } public function testInvalidate() { diff --git a/tests/lib/authentication/token/defaulttokenprovidertest.php b/tests/lib/authentication/token/defaulttokenprovidertest.php index 54e29a7ef52..567068ef06a 100644 --- a/tests/lib/authentication/token/defaulttokenprovidertest.php +++ b/tests/lib/authentication/token/defaulttokenprovidertest.php @@ -36,18 +36,25 @@ class DefaultTokenProviderTest extends TestCase { private $crypto; private $config; private $logger; + private $timeFactory; + private $time; protected function setUp() { parent::setUp(); - $this->mapper = $this->getMock('\OC\Authentication\Token\DefaultTokenMapper') + $this->mapper = $this->getMockBuilder('\OC\Authentication\Token\DefaultTokenMapper') ->disableOriginalConstructor() ->getMock(); $this->crypto = $this->getMock('\OCP\Security\ICrypto'); $this->config = $this->getMock('\OCP\IConfig'); $this->logger = $this->getMock('\OCP\ILogger'); + $this->timeFactory = $this->getMock('\OCP\AppFramework\Utility\ITimeFactory'); + $this->time = 1313131; + $this->timeFactory->expects($this->any()) + ->method('getTime') + ->will($this->returnValue($this->time)); - $this->tokenProvider = new DefaultTokenProvider($this->mapper, $this->crypto, $this->config, $this->logger); + $this->tokenProvider = new DefaultTokenProvider($this->mapper, $this->crypto, $this->config, $this->logger, $this->timeFactory); } public function testGenerateToken() { @@ -61,11 +68,11 @@ class DefaultTokenProviderTest extends TestCase { $toInsert->setUid($uid); $toInsert->setPassword('encryptedpassword'); $toInsert->setName($name); - $toInsert->setToken(hash('sha512', $token)); + $toInsert->setToken(hash('sha512', $token . '1f4h9s')); $toInsert->setType($type); - $toInsert->setLastActivity(time()); + $toInsert->setLastActivity($this->time); - $this->config->expects($this->once()) + $this->config->expects($this->any()) ->method('getSystemValue') ->with('secret') ->will($this->returnValue('1f4h9s')); @@ -83,27 +90,20 @@ class DefaultTokenProviderTest extends TestCase { } public function testUpdateToken() { - $tk = $this->getMockBuilder('\OC\Authentication\Token\DefaultTokenProvider') - ->disableOriginalConstructor() - ->getMock(); - $tk->expects($this->once()) - ->method('setLastActivity') - ->with(time()); + $tk = new DefaultToken(); $this->mapper->expects($this->once()) ->method('update') ->with($tk); $this->tokenProvider->updateToken($tk); + + $this->assertEquals($this->time, $tk->getLastActivity()); } public function testGetPassword() { $token = 'token1234'; - $tk = $this->getMockBuilder('\OC\Authentication\Token\DefaultToken') - ->disableOriginalConstructor() - ->getMock(); - $tk->expects($this->once()) - ->method('getPassword') - ->will($this->returnValue('someencryptedvalue')); + $tk = new DefaultToken(); + $tk->setPassword('someencryptedvalue'); $this->config->expects($this->once()) ->method('getSystemValue') ->with('secret') @@ -134,7 +134,7 @@ class DefaultTokenProviderTest extends TestCase { ->will($this->returnValue(150)); $this->mapper->expects($this->once()) ->method('invalidateOld') - ->with(time() - 150); + ->with($this->time - 150); $this->tokenProvider->invalidateOldTokens(); } diff --git a/tests/lib/user/session.php b/tests/lib/user/session.php index bbbe5e0c796..c6ddeb416fb 100644 --- a/tests/lib/user/session.php +++ b/tests/lib/user/session.php @@ -45,39 +45,43 @@ class Session extends \Test\TestCase { ->method('get') ->with('user_id') ->will($this->returnValue($expectedUser->getUID())); + $sessionId = 'abcdef12345'; $manager = $this->getMockBuilder('\OC\User\Manager') ->disableOriginalConstructor() ->getMock(); + $session->expects($this->once()) + ->method('getId') + ->will($this->returnValue($sessionId)); $this->defaultProvider->expects($this->once()) ->method('getToken') ->will($this->returnValue($token)); - // TODO: check passed session id once it's mockable - $session->expects($this->at(1)) - ->method('last_login_check') + $session->expects($this->at(2)) + ->method('get') + ->with('last_login_check') ->will($this->returnValue(null)); // No check has been run yet $this->defaultProvider->expects($this->once()) ->method('getPassword') - // TODO: check passed UID and session id once it's mockable + ->with($token, $sessionId) ->will($this->returnValue('password123')); $manager->expects($this->once()) ->method('checkPassword') ->with($expectedUser->getUID(), 'password123') ->will($this->returnValue(true)); - $session->expects($this->at(2)) + $session->expects($this->at(3)) ->method('set') ->with('last_login_check', 10000); - $session->expects($this->at(3)) + $session->expects($this->at(4)) ->method('get') ->with('last_token_update') ->will($this->returnValue(null)); // No check run so far $this->defaultProvider->expects($this->once()) ->method('updateToken') ->with($token); - $session->expects($this->at(4)) + $session->expects($this->at(5)) ->method('set') - ->with('last_token_update', $this->equalTo(time(), 10)); + ->with('last_token_update', $this->equalTo(10000)); $manager->expects($this->any()) ->method('get') @@ -171,7 +175,7 @@ class Session extends \Test\TestCase { $backend = $this->getMock('\Test\Util\User\Dummy'); $user = $this->getMock('\OC\User\User', array(), array('foo', $backend)); - $user->expects($this->once()) + $user->expects($this->any()) ->method('isEnabled') ->will($this->returnValue(true)); $user->expects($this->any()) @@ -197,6 +201,9 @@ class Session extends \Test\TestCase { $this->assertEquals($user, $userSession->getUser()); } + /** + * @expectedException \OC\User\LoginException + */ public function testLoginValidPasswordDisabled() { $session = $this->getMock('\OC\Session\Memory', array(), array('')); $session->expects($this->never()) @@ -219,7 +226,7 @@ class Session extends \Test\TestCase { $backend = $this->getMock('\Test\Util\User\Dummy'); $user = $this->getMock('\OC\User\User', array(), array('foo', $backend)); - $user->expects($this->once()) + $user->expects($this->any()) ->method('isEnabled') ->will($this->returnValue(false)); $user->expects($this->never()) -- cgit v1.2.3