diff options
Diffstat (limited to 'lib/private')
24 files changed, 407 insertions, 93 deletions
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index 0879b3e9330..ec36aab75d9 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -49,6 +49,7 @@ use OC\RichObjectStrings\Validator; use OC\Security\Bruteforce\Throttler; use OCP\AppFramework\IApi; use OCP\AppFramework\IAppContainer; +use OCP\Federation\ICloudIdManager; use OCP\Files\IAppData; use OCP\Files\Mount\IMountManager; use OCP\RichObjectStrings\IValidator; @@ -152,6 +153,10 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $this->getServer()->getQueryLogger(); }); + $this->registerService(ICloudIdManager::class, function($c) { + return $this->getServer()->getCloudIdManager(); + }); + $this->registerService('OCP\\Files\\IMimeTypeDetector', function($c) { return $this->getServer()->getMimeTypeDetector(); }); @@ -342,6 +347,13 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $c->query(Validator::class); }); + $this->registerService(\OC\Security\IdentityProof\Manager::class, function ($c) { + return new \OC\Security\IdentityProof\Manager( + $this->getServer()->getAppDataDir('identityproof'), + $this->getServer()->getCrypto() + ); + }); + /** * App Framework APIs diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php index 62d7fc7ed30..be35f4d172f 100644 --- a/lib/private/AppFramework/Http/Request.php +++ b/lib/private/AppFramework/Http/Request.php @@ -72,7 +72,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { /** * @deprecated use \OCP\IRequest::USER_AGENT_CLIENT_IOS instead */ - const USER_AGENT_OWNCLOUD_IOS = '/^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/'; + const USER_AGENT_OWNCLOUD_IOS = '/^Mozilla\/5\.0 \(iOS\) (ownCloud|Nextcloud)\-iOS.*$/'; /** * @deprecated use \OCP\IRequest::USER_AGENT_CLIENT_ANDROID instead */ @@ -490,7 +490,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @return bool */ private function cookieCheckRequired() { - if($this->getCookie(session_name()) === null && $this->getCookie('oc_token') === null) { + if($this->getCookie(session_name()) === null && $this->getCookie('nc_token') === null) { return false; } diff --git a/lib/private/Federation/CloudId.php b/lib/private/Federation/CloudId.php new file mode 100644 index 00000000000..6ba4ff9166b --- /dev/null +++ b/lib/private/Federation/CloudId.php @@ -0,0 +1,76 @@ +<?php +/** + * @copyright Copyright (c) 2017, Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * 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 <http://www.gnu.org/licenses/> + * + */ + +namespace OC\Federation; + +use OCP\Federation\ICloudId; + +class CloudId implements ICloudId { + /** @var string */ + private $id; + /** @var string */ + private $user; + /** @var string */ + private $remote; + + /** + * CloudId constructor. + * + * @param string $id + * @param string $user + * @param string $remote + */ + public function __construct($id, $user, $remote) { + $this->id = $id; + $this->user = $user; + $this->remote = $remote; + } + + /** + * The full remote cloud id + * + * @return string + */ + public function getId() { + return $this->id; + } + + public function getDisplayId() { + return str_replace('https://', '', str_replace('http://', '', $this->getId())); + } + + /** + * The username on the remote server + * + * @return string + */ + public function getUser() { + return $this->user; + } + + /** + * The base address of the remote server + * + * @return string + */ + public function getRemote() { + return $this->remote; + } +} diff --git a/lib/private/Federation/CloudIdManager.php b/lib/private/Federation/CloudIdManager.php new file mode 100644 index 00000000000..46d90f7ab92 --- /dev/null +++ b/lib/private/Federation/CloudIdManager.php @@ -0,0 +1,110 @@ +<?php +/** + * @copyright Copyright (c) 2017, Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * 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 <http://www.gnu.org/licenses/> + * + */ + +namespace OC\Federation; + +use OCP\Federation\ICloudId; +use OCP\Federation\ICloudIdManager; + +class CloudIdManager implements ICloudIdManager { + /** + * @param string $cloudId + * @return ICloudId + * @throws \InvalidArgumentException + */ + public function resolveCloudId($cloudId) { + // TODO magic here to get the url and user instead of just splitting on @ + + if (!$this->isValidCloudId($cloudId)) { + throw new \InvalidArgumentException('Invalid cloud id'); + } + + // Find the first character that is not allowed in user names + $id = $this->fixRemoteURL($cloudId); + $posSlash = strpos($id, '/'); + $posColon = strpos($id, ':'); + + if ($posSlash === false && $posColon === false) { + $invalidPos = strlen($id); + } else if ($posSlash === false) { + $invalidPos = $posColon; + } else if ($posColon === false) { + $invalidPos = $posSlash; + } else { + $invalidPos = min($posSlash, $posColon); + } + + // Find the last @ before $invalidPos + $pos = $lastAtPos = 0; + while ($lastAtPos !== false && $lastAtPos <= $invalidPos) { + $pos = $lastAtPos; + $lastAtPos = strpos($id, '@', $pos + 1); + } + + if ($pos !== false) { + $user = substr($id, 0, $pos); + $remote = substr($id, $pos + 1); + if (!empty($user) && !empty($remote)) { + return new CloudId($id, $user, $remote); + } + } + throw new \InvalidArgumentException('Invalid cloud id'); + } + + /** + * @param string $user + * @param string $remote + * @return CloudId + */ + public function getCloudId($user, $remote) { + // TODO check what the correct url is for remote (asking the remote) + return new CloudId($user. '@' . $remote, $user, $remote); + } + + /** + * Strips away a potential file names and trailing slashes: + * - http://localhost + * - http://localhost/ + * - http://localhost/index.php + * - http://localhost/index.php/s/{shareToken} + * + * all return: http://localhost + * + * @param string $remote + * @return string + */ + protected function fixRemoteURL($remote) { + $remote = str_replace('\\', '/', $remote); + if ($fileNamePosition = strpos($remote, '/index.php')) { + $remote = substr($remote, 0, $fileNamePosition); + } + $remote = rtrim($remote, '/'); + + return $remote; + } + + /** + * @param string $cloudId + * @return bool + */ + public function isValidCloudId($cloudId) { + return strpos($cloudId, '@') !== false; + } +} diff --git a/lib/private/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php index 8625e4904ca..e65c01559f0 100644 --- a/lib/private/Files/Cache/Scanner.php +++ b/lib/private/Files/Cache/Scanner.php @@ -168,7 +168,7 @@ class Scanner extends BasicEmitter implements IScanner { $parent = ''; } if ($parentId === -1) { - $parentId = $this->cache->getId($parent); + $parentId = $this->cache->getParentId($file); } // scan the parent if it's not in the cache (id -1) and the current file is not the root folder @@ -491,7 +491,7 @@ class Scanner extends BasicEmitter implements IScanner { } else { $lastPath = null; while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { - $this->runBackgroundScanJob(function() use ($path) { + $this->runBackgroundScanJob(function () use ($path) { $this->scan($path, self::SCAN_RECURSIVE_INCOMPLETE, self::REUSE_ETAG | self::REUSE_SIZE); }, $path); // FIXME: this won't proceed with the next item, needs revamping of getIncomplete() diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php index d8bdca6a3c4..894fbcc803d 100644 --- a/lib/private/Files/Cache/Wrapper/CacheJail.php +++ b/lib/private/Files/Cache/Wrapper/CacheJail.php @@ -142,11 +142,7 @@ class CacheJail extends CacheWrapper { * @return int */ public function getParentId($file) { - if ($file === '') { - return -1; - } else { - return $this->getCache()->getParentId($this->getSourcePath($file)); - } + return $this->getCache()->getParentId($this->getSourcePath($file)); } /** diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php index f3e3cb9e58c..6e5799be34c 100644 --- a/lib/private/Files/Storage/Common.php +++ b/lib/private/Files/Storage/Common.php @@ -53,6 +53,7 @@ use OCP\Files\InvalidPathException; use OCP\Files\ReservedWordException; use OCP\Files\Storage\ILockingStorage; use OCP\Lock\ILockingProvider; +use OCP\Lock\LockedException; /** * Storage backend class for providing common filesystem operation methods @@ -79,6 +80,9 @@ abstract class Common implements Storage, ILockingStorage { protected $mountOptions = []; protected $owner = null; + private $shouldLogLocks = null; + private $logger; + public function __construct($parameters) { } @@ -681,25 +685,101 @@ abstract class Common implements Storage, ILockingStorage { * @throws \OCP\Lock\LockedException */ public function acquireLock($path, $type, ILockingProvider $provider) { - $provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type); + $logger = $this->getLockLogger(); + if ($logger) { + $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive'; + $logger->info( + sprintf( + 'acquire %s lock on "%s" on storage "%s"', + $typeString, + $path, + $this->getId() + ), + [ + 'app' => 'locking', + ] + ); + } + try { + $provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type); + } catch (LockedException $e) { + if ($logger) { + $logger->logException($e); + } + throw $e; + } } /** * @param string $path * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE * @param \OCP\Lock\ILockingProvider $provider + * @throws \OCP\Lock\LockedException */ public function releaseLock($path, $type, ILockingProvider $provider) { - $provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type); + $logger = $this->getLockLogger(); + if ($logger) { + $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive'; + $logger->info( + sprintf( + 'release %s lock on "%s" on storage "%s"', + $typeString, + $path, + $this->getId() + ), + [ + 'app' => 'locking', + ] + ); + } + try { + $provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type); + } catch (LockedException $e) { + if ($logger) { + $logger->logException($e); + } + throw $e; + } } /** * @param string $path * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE * @param \OCP\Lock\ILockingProvider $provider + * @throws \OCP\Lock\LockedException */ public function changeLock($path, $type, ILockingProvider $provider) { - $provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type); + $logger = $this->getLockLogger(); + if ($logger) { + $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive'; + $logger->info( + sprintf( + 'change lock on "%s" to %s on storage "%s"', + $path, + $typeString, + $this->getId() + ), + [ + 'app' => 'locking', + ] + ); + } + try { + $provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type); + } catch (LockedException $e) { + if ($logger) { + $logger->logException($e); + } + throw $e; + } + } + + private function getLockLogger() { + if (is_null($this->shouldLogLocks)) { + $this->shouldLogLocks = \OC::$server->getConfig()->getSystemValue('filelocking.debug', false); + $this->logger = $this->shouldLogLocks ? \OC::$server->getLogger() : null; + } + return $this->logger; } /** diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php index 3b89a66d6a2..76a6155df24 100644 --- a/lib/private/Files/Storage/DAV.php +++ b/lib/private/Files/Storage/DAV.php @@ -74,11 +74,11 @@ class DAV extends Common { /** @var bool */ protected $ready; /** @var Client */ - private $client; + protected $client; /** @var ArrayCache */ - private $statCache; + protected $statCache; /** @var \OCP\Http\Client\IClientService */ - private $httpClientService; + protected $httpClientService; /** * @param array $params @@ -127,7 +127,7 @@ class DAV extends Common { } } - private function init() { + protected function init() { if ($this->ready) { return; } @@ -203,7 +203,7 @@ class DAV extends Common { try { $response = $this->client->propFind( $this->encodePath($path), - [], + ['{DAV:}href'], 1 ); if ($response === false) { @@ -627,7 +627,7 @@ class DAV extends Common { * @param string $path to encode * @return string encoded path */ - private function encodePath($path) { + protected function encodePath($path) { // slashes need to stay return str_replace('%2F', '/', rawurlencode($path)); } @@ -641,7 +641,7 @@ class DAV extends Common { * @throws StorageInvalidException * @throws StorageNotAvailableException */ - private function simpleResponse($method, $path, $body, $expected) { + protected function simpleResponse($method, $path, $body, $expected) { $path = $this->cleanPath($path); try { $response = $this->client->request($method, $this->encodePath($path), $body); @@ -815,7 +815,7 @@ class DAV extends Common { * @throws StorageNotAvailableException if the storage is not available, * which might be temporary */ - private function convertException(Exception $e, $path = '') { + protected function convertException(Exception $e, $path = '') { \OC::$server->getLogger()->logException($e); Util::writeLog('files_external', $e->getMessage(), Util::ERROR); if ($e instanceof ClientHttpException) { diff --git a/lib/private/Files/Storage/Storage.php b/lib/private/Files/Storage/Storage.php index 49a714587a7..281a8284107 100644 --- a/lib/private/Files/Storage/Storage.php +++ b/lib/private/Files/Storage/Storage.php @@ -107,6 +107,7 @@ interface Storage extends \OCP\Files\Storage { * @param string $path The path of the file to release the lock for * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE * @param \OCP\Lock\ILockingProvider $provider + * @throws \OCP\Lock\LockedException */ public function releaseLock($path, $type, ILockingProvider $provider); diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php index 8615d73f346..013f5ab2344 100644 --- a/lib/private/Files/Storage/Wrapper/Jail.php +++ b/lib/private/Files/Storage/Wrapper/Jail.php @@ -58,7 +58,7 @@ class Jail extends Wrapper { } public function getId() { - return 'link:' . parent::getId() . ':' . $this->rootPath; + return parent::getId(); } /** diff --git a/lib/private/Files/Storage/Wrapper/PermissionsMask.php b/lib/private/Files/Storage/Wrapper/PermissionsMask.php index 239824b67e2..ab0c30a4736 100644 --- a/lib/private/Files/Storage/Wrapper/PermissionsMask.php +++ b/lib/private/Files/Storage/Wrapper/PermissionsMask.php @@ -138,4 +138,13 @@ class PermissionsMask extends Wrapper { $sourceCache = parent::getCache($path, $storage); return new CachePermissionsMask($sourceCache, $this->mask); } + + public function getMetaData($path) { + $data = parent::getMetaData($path); + + if ($data && isset($data['permissions'])) { + $data['permissions'] = $data['permissions'] & $this->mask; + } + return $data; + } } diff --git a/lib/private/Lockdown/Filesystem/NullStorage.php b/lib/private/Lockdown/Filesystem/NullStorage.php index 967b6d2c6e7..ea911b90064 100644 --- a/lib/private/Lockdown/Filesystem/NullStorage.php +++ b/lib/private/Lockdown/Filesystem/NullStorage.php @@ -20,6 +20,7 @@ namespace OC\Lockdown\Filesystem; use Icewind\Streams\IteratorDirectory; +use OC\Files\FileInfo; use OC\Files\Storage\Common; class NullStorage extends Common { @@ -128,7 +129,7 @@ class NullStorage extends Common { } public function free_space($path) { - return 0; + return FileInfo::SPACE_UNKNOWN; } public function touch($path, $mtime = null) { diff --git a/lib/private/Log.php b/lib/private/Log.php index fddd3593127..bcaa788603a 100644 --- a/lib/private/Log.php +++ b/lib/private/Log.php @@ -88,7 +88,8 @@ class Log implements ILogger { 'decrypt', //LoginController - 'tryLogin' + 'tryLogin', + 'confirmPassword', ]; /** diff --git a/lib/private/Repair/RepairMimeTypes.php b/lib/private/Repair/RepairMimeTypes.php index 86427af4c47..fbf446a681c 100644 --- a/lib/private/Repair/RepairMimeTypes.php +++ b/lib/private/Repair/RepairMimeTypes.php @@ -308,6 +308,16 @@ class RepairMimeTypes implements IRepairStep { self::updateMimetypes($updatedMimetypes); } + private function introduceWindowsProgramTypes() { + $updatedMimetypes = array( + 'htaccess' => 'text/plain', + 'bat' => 'application/x-msdos-program', + 'cmd' => 'application/cmd', + ); + + $this->updateMimetypes($updatedMimetypes); + } + /** * Fix mime types */ @@ -377,5 +387,9 @@ class RepairMimeTypes implements IRepairStep { $out->info('Fixed richdocuments additional office mime types'); } } + + if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.13', '<') && $this->introduceWindowsProgramTypes()) { + $out->info('Fixed windows program mime types'); + } } } diff --git a/lib/private/Server.php b/lib/private/Server.php index 3c716ae6ce6..bcbe23b0181 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -52,6 +52,7 @@ use OC\Diagnostics\EventLogger; use OC\Diagnostics\NullEventLogger; use OC\Diagnostics\NullQueryLogger; use OC\Diagnostics\QueryLogger; +use OC\Federation\CloudIdManager; use OC\Files\Config\UserMountCache; use OC\Files\Config\UserMountCacheListener; use OC\Files\Mount\CacheMountProvider; @@ -90,6 +91,7 @@ use OC\Security\TrustedDomainHelper; use OC\Session\CryptoWrapper; use OC\Tagging\TagMapper; use OCA\Theming\ThemingDefaults; +use OCP\Federation\ICloudIdManager; use OCP\Authentication\LoginCredentials\IStore; use OCP\IL10N; use OCP\IServerContainer; @@ -825,6 +827,10 @@ class Server extends ServerContainer implements IServerContainer { return new LockdownManager(); }); + $this->registerService(ICloudIdManager::class, function (Server $c) { + return new CloudIdManager(); + }); + /* To trick DI since we don't extend the DIContainer here */ $this->registerService(CleanPreviewsBackgroundJob::class, function (Server $c) { return new CleanPreviewsBackgroundJob( @@ -1570,4 +1576,11 @@ class Server extends ServerContainer implements IServerContainer { public function getLockdownManager() { return $this->query('LockdownManager'); } + + /** + * @return \OCP\Federation\ICloudIdManager + */ + public function getCloudIdManager() { + return $this->query(ICloudIdManager::class); + } } diff --git a/lib/private/Setup.php b/lib/private/Setup.php index d9997767684..321e8ea4c66 100644 --- a/lib/private/Setup.php +++ b/lib/private/Setup.php @@ -357,6 +357,7 @@ class Setup { $config = \OC::$server->getConfig(); $config->setAppValue('core', 'installedat', microtime(true)); $config->setAppValue('core', 'lastupdatedat', microtime(true)); + $config->setAppValue('core', 'vendor', $this->getVendor()); $group =\OC::$server->getGroupManager()->createGroup('admin'); $group->addUser($user); @@ -497,4 +498,18 @@ class Setup { file_put_contents($baseDir . '/.htaccess', $content); file_put_contents($baseDir . '/index.html', ''); } + + /** + * Return vendor from which this version was published + * + * @return string Get the vendor + * + * Copy of \OC\Updater::getVendor() + */ + private function getVendor() { + // this should really be a JSON file + require \OC::$SERVERROOT . '/version.php'; + /** @var string $vendor */ + return (string) $vendor; + } } diff --git a/lib/private/Share/Helper.php b/lib/private/Share/Helper.php index 20aaa793728..a1a56077d40 100644 --- a/lib/private/Share/Helper.php +++ b/lib/private/Share/Helper.php @@ -249,46 +249,14 @@ class Helper extends \OC\Share\Constants { * @throws HintException */ public static function splitUserRemote($id) { - if (strpos($id, '@') === false) { + try { + $cloudId = \OC::$server->getCloudIdManager()->resolveCloudId($id); + return [$cloudId->getUser(), $cloudId->getRemote()]; + } catch (\InvalidArgumentException $e) { $l = \OC::$server->getL10N('core'); $hint = $l->t('Invalid Federated Cloud ID'); - throw new HintException('Invalid Federated Cloud ID', $hint); + throw new HintException('Invalid Federated Cloud ID', $hint, 0, $e); } - - // Find the first character that is not allowed in user names - $id = str_replace('\\', '/', $id); - $posSlash = strpos($id, '/'); - $posColon = strpos($id, ':'); - - if ($posSlash === false && $posColon === false) { - $invalidPos = strlen($id); - } else if ($posSlash === false) { - $invalidPos = $posColon; - } else if ($posColon === false) { - $invalidPos = $posSlash; - } else { - $invalidPos = min($posSlash, $posColon); - } - - // Find the last @ before $invalidPos - $pos = $lastAtPos = 0; - while ($lastAtPos !== false && $lastAtPos <= $invalidPos) { - $pos = $lastAtPos; - $lastAtPos = strpos($id, '@', $pos + 1); - } - - if ($pos !== false) { - $user = substr($id, 0, $pos); - $remote = substr($id, $pos + 1); - $remote = self::fixRemoteURL($remote); - if (!empty($user) && !empty($remote)) { - return array($user, $remote); - } - } - - $l = \OC::$server->getL10N('core'); - $hint = $l->t('Invalid Federated Cloud ID'); - throw new HintException('Invalid Fededrated Cloud ID', $hint); } /** diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php index 3f277a852b3..87d9d221810 100644 --- a/lib/private/Share20/ProviderFactory.php +++ b/lib/private/Share20/ProviderFactory.php @@ -96,7 +96,8 @@ class ProviderFactory implements IProviderFactory { $l = $this->serverContainer->getL10N('federatedfilessharing'); $addressHandler = new AddressHandler( $this->serverContainer->getURLGenerator(), - $l + $l, + $this->serverContainer->getCloudIdManager() ); $discoveryManager = new DiscoveryManager( $this->serverContainer->getMemCacheFactory(), @@ -121,7 +122,8 @@ class ProviderFactory implements IProviderFactory { $this->serverContainer->getLogger(), $this->serverContainer->getLazyRootFolder(), $this->serverContainer->getConfig(), - $this->serverContainer->getUserManager() + $this->serverContainer->getUserManager(), + $this->serverContainer->getCloudIdManager() ); } diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php index f17c6a16194..1c241989fd2 100644 --- a/lib/private/Template/JSConfigHelper.php +++ b/lib/private/Template/JSConfigHelper.php @@ -204,7 +204,7 @@ class JSConfigHelper { 'session_keepalive' => $this->config->getSystemValue('session_keepalive', true), 'version' => implode('.', \OCP\Util::getVersion()), 'versionstring' => \OC_Util::getVersionString(), - 'enable_avatars' => $this->config->getSystemValue('enable_avatars', true) === true, + 'enable_avatars' => true, // here for legacy reasons - to not crash existing code that relies on this value 'lost_password_link'=> $this->config->getSystemValue('lost_password_link', null), 'modRewriteWorking' => (\OC::$server->getConfig()->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true'), ]), diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index 7ded109f76b..f1621363237 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -100,7 +100,6 @@ class TemplateLayout extends \OC_Template { $this->assign('user_displayname', $userDisplayName); $this->assign('user_uid', \OC_User::getUser()); $this->assign('appsmanagement_active', $appsMgmtActive); - $this->assign('enableAvatars', $this->config->getSystemValue('enable_avatars', true) === true); if (\OC_User::getUser() === false) { $this->assign('userAvatarSet', false); @@ -164,11 +163,15 @@ class TemplateLayout extends \OC_Template { // Do not load scss for update, errors, installation or login page if(\OC::$server->getSystemConfig()->getValue('installed', false) && !\OCP\Util::needUpgrade() - && strpos(\OC::$server->getRequest()->getRequestUri(), \OC::$server->getURLGenerator()->linkToRoute('core.login.tryLogin')) !== 0) { + && !preg_match('/^\/login/', \OC::$server->getRequest()->getPathInfo())) { $cssFiles = self::findStylesheetFiles(\OC_Util::$styles); } else { + // If we ignore the scss compiler, + // we need to load the guest css fallback + \OC_Util::addStyle('guest'); $cssFiles = self::findStylesheetFiles(\OC_Util::$styles, false); } + $this->assign('cssfiles', array()); $this->assign('printcssfiles', []); $this->assign('versionHash', self::$versionHash); diff --git a/lib/private/Updater.php b/lib/private/Updater.php index a66d49941cd..30a9a80cef4 100644 --- a/lib/private/Updater.php +++ b/lib/private/Updater.php @@ -157,13 +157,13 @@ class Updater extends BasicEmitter { /** * Return version from which this version is allowed to upgrade from * - * @return string allowed previous version + * @return array allowed previous versions per vendor */ - private function getAllowedPreviousVersion() { + private function getAllowedPreviousVersions() { // this should really be a JSON file require \OC::$SERVERROOT . '/version.php'; /** @var array $OC_VersionCanBeUpgradedFrom */ - return implode('.', $OC_VersionCanBeUpgradedFrom); + return $OC_VersionCanBeUpgradedFrom; } /** @@ -182,26 +182,22 @@ class Updater extends BasicEmitter { * Whether an upgrade to a specified version is possible * @param string $oldVersion * @param string $newVersion - * @param string $allowedPreviousVersion + * @param array $allowedPreviousVersions * @return bool */ - public function isUpgradePossible($oldVersion, $newVersion, $allowedPreviousVersion) { - $allowedUpgrade = (version_compare($allowedPreviousVersion, $oldVersion, '<=') - && (version_compare($oldVersion, $newVersion, '<=') || $this->config->getSystemValue('debug', false))); - - if ($allowedUpgrade) { - return $allowedUpgrade; + public function isUpgradePossible($oldVersion, $newVersion, array $allowedPreviousVersions) { + $version = explode('.', $oldVersion); + $majorMinor = $version[0] . '.' . $version[1]; + + $currentVendor = $this->config->getAppValue('core', 'vendor', ''); + if ($currentVendor === 'nextcloud') { + return isset($allowedPreviousVersions[$currentVendor][$majorMinor]) + && (version_compare($oldVersion, $newVersion, '<=') || + $this->config->getSystemValue('debug', false)); } - // Upgrade not allowed, someone switching vendor? - if ($this->getVendor() !== $this->config->getAppValue('core', 'vendor', '')) { - $oldVersion = explode('.', $oldVersion); - $newVersion = explode('.', $newVersion); - - return $oldVersion[0] === $newVersion[0] && $oldVersion[1] === $newVersion[1]; - } - - return false; + // Check if the instance can be migrated + return isset($allowedPreviousVersions[$currentVendor][$majorMinor]); } /** @@ -215,8 +211,8 @@ class Updater extends BasicEmitter { */ private function doUpgrade($currentVersion, $installedVersion) { // Stop update if the update is over several major versions - $allowedPreviousVersion = $this->getAllowedPreviousVersion(); - if (!self::isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersion)) { + $allowedPreviousVersions = $this->getAllowedPreviousVersions(); + if (!$this->isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersions)) { throw new \Exception('Updates between multiple major versions and downgrades are unsupported.'); } diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 1486a5b7fea..c03cbd5891b 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -286,6 +286,19 @@ class Session implements IUserSession, Emitter { } /** + * set the token id + * + * @param int|null $token that was used to log in + */ + protected function setToken($token) { + if ($token === null) { + $this->session->remove('token-id'); + } else { + $this->session->set('token-id', $token); + } + } + + /** * try to log in with the provided credentials * * @param string $uid @@ -478,6 +491,7 @@ class Session implements IUserSession, Emitter { if ($user->isEnabled()) { $this->setUser($user); $this->setLoginName($uid); + $this->setToken(null); $firstTimeLogin = $user->updateLastLoginTimestamp(); $this->manager->emit('\OC\User', 'postLogin', [$user, $password]); if ($this->isLoggedIn()) { @@ -500,7 +514,7 @@ class Session implements IUserSession, Emitter { * * @param string $token * @return boolean - * @throws LoginException if an app canceld the login process or the user is not enabled + * @throws LoginException if an app canceled the login process or the user is not enabled */ private function loginWithToken($token) { try { @@ -533,6 +547,7 @@ class Session implements IUserSession, Emitter { //login $this->setUser($user); $this->setLoginName($dbToken->getLoginName()); + $this->setToken($dbToken->getId()); \OC::$server->getLockdownManager()->setToken($dbToken); $this->manager->emit('\OC\User', 'postLogin', array($user, $password)); @@ -743,10 +758,12 @@ class Session implements IUserSession, Emitter { } $this->setMagicInCookie($user->getUID(), $newToken); + $token = $this->tokenProvider->getToken($sessionId); //login $this->setUser($user); - $this->setLoginName($this->tokenProvider->getToken($sessionId)->getLoginName()); + $this->setLoginName($token->getLoginName()); + $this->setToken($token->getId()); $user->updateLastLoginTimestamp(); $this->manager->emit('\OC\User', 'postRememberedLogin', [$user]); return true; @@ -776,6 +793,7 @@ class Session implements IUserSession, Emitter { } $this->setUser(null); $this->setLoginName(null); + $this->setToken(null); $this->unsetMagicInCookie(); $this->session->clear(); } diff --git a/lib/private/User/User.php b/lib/private/User/User.php index c37bb59028e..961f70f8a8e 100644 --- a/lib/private/User/User.php +++ b/lib/private/User/User.php @@ -411,7 +411,8 @@ class User implements IUser { public function getCloudId() { $uid = $this->getUID(); $server = $this->urlGenerator->getAbsoluteURL('/'); - return $uid . '@' . rtrim( $this->removeProtocolFromUrl($server), '/'); + $server = rtrim( $this->removeProtocolFromUrl($server), '/'); + return \OC::$server->getCloudIdManager()->getCloudId($uid, $server)->getId(); } /** diff --git a/lib/private/legacy/template.php b/lib/private/legacy/template.php index a07bf214f34..09e3d130f49 100644 --- a/lib/private/legacy/template.php +++ b/lib/private/legacy/template.php @@ -121,10 +121,8 @@ class OC_Template extends \OC\Template\Base { OC_Util::addStyle("styles",null,true); // avatars - if (\OC::$server->getSystemConfig()->getValue('enable_avatars', true) === true) { - \OC_Util::addScript('jquery.avatar', null, true); - \OC_Util::addScript('placeholder', null, true); - } + \OC_Util::addScript('jquery.avatar', null, true); + \OC_Util::addScript('placeholder', null, true); OC_Util::addVendorScript('select2/select2'); OC_Util::addVendorStyle('select2/select2', null, true); |