diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index 7afed6b274..ba9fc55d45 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 8af2f02479..b17c1a384d 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 94197f7f27..67d714188a 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 bb35b65b27..262174ab17 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 ca408d347b..499e916994 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()