From 7aa16e1559e8ef1121ac2529090a6881b4d919d5 Mon Sep 17 00:00:00 2001
From: Christoph Wurst <christoph@owncloud.com>
Date: Wed, 27 Apr 2016 12:01:13 +0200
Subject: [PATCH] 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(-)

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()
-- 
GitLab