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;
}
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).
unset($cachedUsers[$i]);
}
});
+ $this->listen('\OC\User', 'postLogin', function ($user, $pw) {
+ $user->updateLastLoginTimestamp();
+ });
+ $this->listen('\OC\User', 'postRememberedLogin', function ($user) {
+ $user->updateLastLoginTimestamp();
+ });
}
/**
}
}
+ /**
+ * 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
*/
*/
private $home;
+ /**
+ * @var int $lastLogin
+ */
+ private $lastLogin;
+
/**
* @var \OC\AllConfig $config
*/
} else {
$this->enabled = true;
}
+ $this->lastLogin = \OC_Preferences::getValue($uid, 'login', 'lastLogin', 0);
}
/**
}
}
+ /**
+ * 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
*