diff options
-rw-r--r-- | core/Controller/LoginController.php | 2 | ||||
-rw-r--r-- | core/Controller/TokenController.php | 8 | ||||
-rw-r--r-- | lib/private/Authentication/Token/DefaultToken.php | 4 | ||||
-rw-r--r-- | lib/private/Authentication/Token/DefaultTokenProvider.php | 10 | ||||
-rw-r--r-- | lib/private/Authentication/Token/IProvider.php | 9 | ||||
-rw-r--r-- | lib/private/Authentication/Token/IToken.php | 7 | ||||
-rw-r--r-- | lib/private/User/Session.php | 34 | ||||
-rw-r--r-- | lib/private/legacy/api.php | 43 |
8 files changed, 73 insertions, 44 deletions
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; } } @@ -388,6 +389,19 @@ class Session implements IUserSession, Emitter { } /** + * @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 * * @todo check remember me cookie 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; |