From a253b56daef0f2d5a2a07dbe29030540323ff185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 16 Feb 2017 16:19:13 +0100 Subject: [PATCH] During installation no UserSession is available and no database connection - behave accordingly --- lib/base.php | 17 +- lib/private/App/AppManager.php | 4 +- lib/private/Files/View.php | 27 +-- lib/private/Group/Group.php | 3 +- lib/private/L10N/Factory.php | 4 +- .../CSRF/TokenStorage/SessionStorage.php | 2 +- lib/private/Server.php | 30 ++- lib/private/User/RemoteUser.php | 200 ++++++++++++++++++ 8 files changed, 255 insertions(+), 32 deletions(-) create mode 100644 lib/private/User/RemoteUser.php diff --git a/lib/base.php b/lib/base.php index 7138745ba04d..9ae89824eb8b 100644 --- a/lib/base.php +++ b/lib/base.php @@ -329,7 +329,7 @@ public static function checkSingleUserMode($lockIfNoUserLoggedIn = false) { /** * Checks if the version requires an update and shows * @param bool $showTemplate Whether an update screen should get shown - * @return bool|void + * @return bool */ public static function checkUpgrade($showTemplate = true) { if (\OCP\Util::needUpgrade()) { @@ -391,6 +391,7 @@ private static function printUpgradePage() { \OCP\Util::addScript('update'); \OCP\Util::addStyle('update'); + /** @var \OC\App\AppManager $appManager */ $appManager = \OC::$server->getAppManager(); $tmpl = new OC_Template('', 'update.admin', 'guest'); @@ -627,13 +628,13 @@ public static function init() { $systemConfig = \OC::$server->getSystemConfig(); // User and Groups - if (!$systemConfig->getValue("installed", false)) { + if ($systemConfig->getValue("installed", false)) { + OC_User::useBackend(new \OC\User\Database()); + \OC::$server->getGroupManager()->addBackend(new \OC\Group\Database()); + } else { self::$server->getSession()->set('user_id', ''); } - OC_User::useBackend(new \OC\User\Database()); - \OC::$server->getGroupManager()->addBackend(new \OC\Group\Database()); - // Subscribe to the hook \OCP\Util::connectHook( '\OCA\Files_Sharing\API\Server2Server', @@ -657,8 +658,10 @@ public static function init() { } self::registerShareHooks(); self::registerLogRotate(); - self::registerEncryptionWrapper(); - self::registerEncryptionHooks(); + if ($systemConfig->getValue("installed", false)) { + self::registerEncryptionWrapper(); + self::registerEncryptionHooks(); + } //make sure temporary files are cleaned up $tmpManager = \OC::$server->getTempManager(); diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php index b9092d72e7f8..6c01b4accba4 100644 --- a/lib/private/App/AppManager.php +++ b/lib/private/App/AppManager.php @@ -86,7 +86,7 @@ class AppManager implements IAppManager { * @param ICacheFactory $memCacheFactory * @param EventDispatcherInterface $dispatcher */ - public function __construct(IUserSession $userSession, + public function __construct(IUserSession $userSession = null, IAppConfig $appConfig, IGroupManager $groupManager, ICacheFactory $memCacheFactory, @@ -152,7 +152,7 @@ public function isEnabledForUser($appId, $user = null) { if ($this->isAlwaysEnabled($appId)) { return true; } - if (is_null($user)) { + if (is_null($user) && !is_null($this->userSession)) { $user = $this->userSession->getUser(); } $installedApps = $this->getInstalledAppsValues(); diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index 34e45ec3d8b3..59590d1036a8 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -49,7 +49,7 @@ use Icewind\Streams\CallbackWrapper; use OC\Files\Mount\MoveableMount; use OC\Files\Storage\Storage; -use OC\User\User; +use OC\User\RemoteUser; use OCP\Constants; use OCP\Files\Cache\ICacheEntry; use OCP\Files\FileNameTooLongException; @@ -61,6 +61,7 @@ use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; use OCA\Files_Sharing\SharedMount; +use OCP\Util; /** * Class to provide access to ownCloud filesystem via a "view", and methods for @@ -959,7 +960,7 @@ public function fopen($path, $mode) { $hooks[] = 'write'; break; default: - \OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR); + Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, Util::ERROR); } return $this->basicOperation('fopen', $path, $hooks, $mode); @@ -1262,15 +1263,15 @@ public function hasUpdated($path, $time) { /** * @param string $ownerId - * @return \OC\User\User + * @return IUser */ private function getUserObjectForOwner($ownerId) { $owner = $this->userManager->get($ownerId); - if ($owner instanceof IUser) { - return $owner; - } else { - return new User($ownerId, null); + if (!$owner instanceof IUser) { + return new RemoteUser($ownerId); } + + return $owner; } /** @@ -1408,7 +1409,7 @@ public function getDirectoryContent($directory, $mimetype_filter = '') { $folderId = $data['fileid']; $contents = $cache->getFolderContentsById($folderId); //TODO: mimetype_filter - $sharingDisabled = \OCP\Util::isSharingDisabledForUser(); + $sharingDisabled = Util::isSharingDisabledForUser(); /** * @var \OC\Files\FileInfo[] $files */ @@ -1443,11 +1444,11 @@ public function getDirectoryContent($directory, $mimetype_filter = '') { continue; } catch (\Exception $e) { // sometimes when the storage is not available it can be any exception - \OCP\Util::writeLog( + Util::writeLog( 'core', 'Exception while scanning storage "' . $subStorage->getId() . '": ' . get_class($e) . ': ' . $e->getMessage(), - \OCP\Util::ERROR + Util::ERROR ); continue; } @@ -1486,7 +1487,7 @@ public function getDirectoryContent($directory, $mimetype_filter = '') { $rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/ // if sharing was disabled for the user we remove the share permissions - if (\OCP\Util::isSharingDisabledForUser()) { + if (Util::isSharingDisabledForUser()) { $rootEntry['permissions'] = $rootEntry['permissions'] & ~\OCP\Constants::PERMISSION_SHARE; } @@ -1740,9 +1741,9 @@ private function canMove(MoveableMount $mount1, $target) { list($targetStorage, $targetInternalPath) = \OC\Files\Filesystem::resolvePath($target); if (!$targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage')) { - \OCP\Util::writeLog('files', + Util::writeLog('files', 'It is not allowed to move one mount point into another one', - \OCP\Util::DEBUG); + Util::DEBUG); return false; } diff --git a/lib/private/Group/Group.php b/lib/private/Group/Group.php index 6b899282ef97..1911086b065c 100644 --- a/lib/private/Group/Group.php +++ b/lib/private/Group/Group.php @@ -30,6 +30,7 @@ namespace OC\Group; use OCP\IGroup; +use OCP\IUser; class Group implements IGroup { /** @@ -117,7 +118,7 @@ public function getUsers() { /** * check if a user is in the group * - * @param \OC\User\User $user + * @param IUser $user * @return bool */ public function inGroup($user) { diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php index a9c19d9c6ecb..0744a7711d66 100644 --- a/lib/private/L10N/Factory.php +++ b/lib/private/L10N/Factory.php @@ -76,7 +76,7 @@ class Factory implements IFactory { */ public function __construct(IConfig $config, IRequest $request, - IUserSession $userSession, + IUserSession $userSession = null, $serverRoot) { $this->config = $config; $this->request = $request; @@ -128,7 +128,7 @@ public function findLanguage($app = null) { * * @link https://github.com/owncloud/core/issues/21955 */ - if($this->config->getSystemValue('installed', false)) { + if(!is_null($this->userSession) && $this->config->getSystemValue('installed', false)) { $userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() : null; if(!is_null($userId)) { $userLang = $this->config->getUserValue($userId, 'core', 'lang', null); diff --git a/lib/private/Security/CSRF/TokenStorage/SessionStorage.php b/lib/private/Security/CSRF/TokenStorage/SessionStorage.php index fa5b08a238e3..1caf6b713fdf 100644 --- a/lib/private/Security/CSRF/TokenStorage/SessionStorage.php +++ b/lib/private/Security/CSRF/TokenStorage/SessionStorage.php @@ -35,7 +35,7 @@ class SessionStorage { /** * @param ISession $session */ - public function __construct(ISession $session) { + public function __construct(ISession $session = null) { $this->session = $session; } diff --git a/lib/private/Server.php b/lib/private/Server.php index 5e1a063d1a8e..ae264927d5bb 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -80,6 +80,7 @@ use OC\Security\SecureRandom; use OC\Security\TrustedDomainHelper; use OC\Session\CryptoWrapper; +use OC\Session\Memory; use OC\Settings\Panels\Helper; use OC\Settings\SettingsManager; use OC\Tagging\TagMapper; @@ -87,6 +88,7 @@ use OC\User\AccountMapper; use OCP\IL10N; use OCP\IServerContainer; +use OCP\ISession; use OCP\Security\IContentSecurityPolicyManager; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -115,7 +117,7 @@ public function __construct($webRoot, \OC\Config $config) { parent::__construct(); $this->webRoot = $webRoot; - $this->registerService('SettingsManager', function($c) { + $this->registerService('SettingsManager', function(Server $c) { return new SettingsManager( $c->getL10N('core'), $c->getAppManager(), @@ -444,6 +446,11 @@ public function __construct($webRoot, \OC\Config $config) { }); $this->registerService('DatabaseConnection', function (Server $c) { $systemConfig = $c->getSystemConfig(); + $keys = $systemConfig->getKeys(); + if (!isset($keys['dbname']) && !isset($keys['dbhost']) && isset($keys['dbtableprefix'])) { + throw new \OC\DatabaseException('No database configured'); + } + $factory = new \OC\DB\ConnectionFactory($systemConfig); $type = $systemConfig->getValue('dbtype', 'sqlite'); if (!$factory->isValidType($type)) { @@ -954,21 +961,32 @@ public function getGroupManager() { * @return \OC\User\Session */ public function getUserSession() { + if($this->getConfig()->getSystemValue('installed', false) === false) { + return null; + } return $this->query('UserSession'); } /** - * @return \OCP\ISession + * @return ISession */ public function getSession() { - return $this->query('UserSession')->getSession(); + $userSession = $this->getUserSession(); + if (is_null($userSession)) { + return new Memory(''); + } + return $userSession->getSession(); } /** - * @param \OCP\ISession $session + * @param ISession $session */ - public function setSession(\OCP\ISession $session) { - return $this->query('UserSession')->setSession($session); + public function setSession(ISession $session) { + $userSession = $this->getUserSession(); + if (is_null($userSession)) { + return; + } + $userSession->setSession($session); } /** diff --git a/lib/private/User/RemoteUser.php b/lib/private/User/RemoteUser.php new file mode 100644 index 000000000000..782f321cf60d --- /dev/null +++ b/lib/private/User/RemoteUser.php @@ -0,0 +1,200 @@ + + * + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + + +namespace OC\User; + + +use OCP\IImage; +use OCP\IUser; + +/** + * Class RemoteUser - an implementation of IUser for user on a remote/federated server + * + * @package OC\User + */ +class RemoteUser implements IUser { + + /** @var string */ + private $userId; + + /** + * RemoteUser constructor. + * + * @param string $userId + */ + public function __construct($userId) { + $this->userId = $userId; + } + + /** + * @inheritdoc + */ + public function getUID() { + return $this->userId; + } + + /** + * @inheritdoc + */ + public function getDisplayName() { + return $this->userId; + } + + /** + * @inheritdoc + */ + public function setDisplayName($displayName) { + return false; + } + + /** + * @inheritdoc + */ + public function getLastLogin() { + return 0; + } + + /** + * @inheritdoc + */ + public function updateLastLoginTimestamp() { + } + + /** + * @inheritdoc + */ + public function delete() { + return false; + } + + /** + * @inheritdoc + */ + public function setPassword($password, $recoveryPassword = null) { + return false; + } + + /** + * @inheritdoc + */ + public function getHome() { + } + + /** + * @inheritdoc + */ + public function getBackendClassName() { + return 'Remote'; + } + + /** + * @inheritdoc + */ + public function canChangeAvatar() { + return false; + } + + /** + * @inheritdoc + */ + public function canChangePassword() { + return false; + } + + /** + * @inheritdoc + */ + public function canChangeDisplayName() { + return false; + } + + /** + * @inheritdoc + */ + public function isEnabled() { + return true; + } + + /** + * @inheritdoc + */ + public function setEnabled($enabled) { + return false; + } + + /** + * @inheritdoc + */ + public function getEMailAddress() { + return false; + } + + /** + * @inheritdoc + */ + public function getAvatarImage($size) { + return null; + } + + /** + * @inheritdoc + */ + public function getCloudId() { + $uid = $this->getUID(); + $server = \OC::$server->getURLGenerator()->getAbsoluteURL('/'); + return $uid . '@' . rtrim( $this->removeProtocolFromUrl($server), '/'); + } + + /** + * @param string $url + * @return string + */ + private function removeProtocolFromUrl($url) { + if (strpos($url, 'https://') === 0) { + return substr($url, strlen('https://')); + } else if (strpos($url, 'http://') === 0) { + return substr($url, strlen('http://')); + } + + return $url; + } + + /** + * @inheritdoc + */ + public function setEMailAddress($mailAddress) { + } + + /** + * @inheritdoc + */ + public function getQuota() { + return 'none'; + } + + /** + * @inheritdoc + */ + public function setQuota($quota) { + } + +}