clean up tryRememberLogin and save the timestamp of users last login
This commit is contained in:
parent
40fc1d5b4b
commit
2c89962919
5 changed files with 85 additions and 15 deletions
24
lib/base.php
24
lib/base.php
|
@ -883,30 +883,24 @@ class OC {
|
|||
if (defined("DEBUG") && DEBUG) {
|
||||
OC_Log::write('core', 'Trying to login from cookie', OC_Log::DEBUG);
|
||||
}
|
||||
// confirm credentials in cookie
|
||||
if (isset($_COOKIE['oc_token']) && OC_User::userExists($_COOKIE['oc_username'])) {
|
||||
// delete outdated cookies
|
||||
|
||||
if(OC_User::userExists($_COOKIE['oc_username'])) {
|
||||
self::cleanupLoginTokens($_COOKIE['oc_username']);
|
||||
// get stored tokens
|
||||
$tokens = OC_Preferences::getKeys($_COOKIE['oc_username'], 'login_token');
|
||||
// test cookies token against stored tokens
|
||||
if (in_array($_COOKIE['oc_token'], $tokens, true)) {
|
||||
// replace successfully used token with a new one
|
||||
OC_Preferences::deleteKey($_COOKIE['oc_username'], 'login_token', $_COOKIE['oc_token']);
|
||||
$token = OC_Util::generateRandomBytes(32);
|
||||
OC_Preferences::setValue($_COOKIE['oc_username'], 'login_token', $token, time());
|
||||
OC_User::setMagicInCookie($_COOKIE['oc_username'], $token);
|
||||
// login
|
||||
OC_User::setUserId($_COOKIE['oc_username']);
|
||||
// confirm credentials in cookie
|
||||
$granted = OC_User::loginWithCookie(
|
||||
$_COOKIE['oc_username'], $_COOKIE['oc_token']);
|
||||
if($granted === true) {
|
||||
OC_Util::redirectToDefaultPage();
|
||||
// doesn't return
|
||||
}
|
||||
OC_Log::write('core', 'Authentication cookie rejected for user ' .
|
||||
$_COOKIE['oc_username'], OC_Log::WARN);
|
||||
// if you reach this point you have changed your password
|
||||
// or you are an attacker
|
||||
// we can not delete tokens here because users may reach
|
||||
// this point multiple times after a password change
|
||||
OC_Log::write('core', 'Authentication cookie rejected for user ' . $_COOKIE['oc_username'], OC_Log::WARN);
|
||||
}
|
||||
|
||||
OC_User::unsetMagicInCookie();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -235,6 +235,17 @@ class OC_User {
|
|||
return self::getUserSession()->login($uid, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to login a user using the magic cookie (remember login)
|
||||
*
|
||||
* @param string $uid The username of the user to log in
|
||||
* @param string $token
|
||||
* @return bool
|
||||
*/
|
||||
public static function loginWithCookie($uid, $token) {
|
||||
return self::getUserSession()->loginWithCookie($uid, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to login a user, assuming authentication
|
||||
* has already happened (e.g. via Single Sign On).
|
||||
|
|
|
@ -52,6 +52,12 @@ class Manager extends PublicEmitter {
|
|||
unset($cachedUsers[$i]);
|
||||
}
|
||||
});
|
||||
$this->listen('\OC\User', 'postLogin', function ($user, $pw) {
|
||||
$user->updateLastLoginTimestamp();
|
||||
});
|
||||
$this->listen('\OC\User', 'postRememberedLogin', function ($user) {
|
||||
$user->updateLastLoginTimestamp();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -170,6 +170,38 @@ class Session implements Emitter, \OCP\IUserSession {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* perform login using the magic cookie (remember login)
|
||||
*
|
||||
* @param string $uid the username
|
||||
* @param string $currentToken
|
||||
* @return bool
|
||||
*/
|
||||
public function loginWithCookie($uid, $currentToken) {
|
||||
$user = $this->manager->get($uid);
|
||||
if(is_null($user)) {
|
||||
// user does not exist
|
||||
return false;
|
||||
}
|
||||
|
||||
// get stored tokens
|
||||
$tokens = \OC_Preferences::getKeys($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_Preferences::deleteKey($uid, 'login_token', $currentToken);
|
||||
$newToken = \OC_Util::generateRandomBytes(32);
|
||||
\OC_Preferences::setValue($uid, 'login_token', $newToken, time());
|
||||
$this->setMagicInCookie($user->getUID(), $newToken);
|
||||
|
||||
//login
|
||||
$this->setUser($user);
|
||||
$this->manager->emit('\OC\User', 'postRememberedLogin', array($user));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* logout the user from the session
|
||||
*/
|
||||
|
|
|
@ -42,6 +42,11 @@ class User {
|
|||
*/
|
||||
private $home;
|
||||
|
||||
/**
|
||||
* @var int $lastLogin
|
||||
*/
|
||||
private $lastLogin;
|
||||
|
||||
/**
|
||||
* @var \OC\AllConfig $config
|
||||
*/
|
||||
|
@ -64,6 +69,7 @@ class User {
|
|||
} else {
|
||||
$this->enabled = true;
|
||||
}
|
||||
$this->lastLogin = \OC_Preferences::getValue($uid, 'login', 'lastLogin', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +113,27 @@ class User {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the timestamp of the user's last login or 0 if the user did never
|
||||
* login
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastLogin() {
|
||||
return $this->lastLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* updates the timestamp of the most recent login of this user
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function updateLastLoginTimestamp() {
|
||||
$this->lastLogin = time();
|
||||
\OC_Preferences::setValue(
|
||||
$this->uid, 'login', 'lastLogin', $this->lastLogin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the user
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue