diff options
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/AppFramework/DependencyInjection/DIContainer.php | 5 | ||||
-rw-r--r-- | lib/private/Files/Storage/Wrapper/Quota.php | 22 | ||||
-rw-r--r-- | lib/private/Files/Stream/Encryption.php | 6 | ||||
-rw-r--r-- | lib/private/Files/View.php | 7 | ||||
-rw-r--r-- | lib/private/Log.php | 46 | ||||
-rw-r--r-- | lib/private/Log/Errorlog.php | 11 | ||||
-rw-r--r-- | lib/private/Log/File.php | 71 | ||||
-rw-r--r-- | lib/private/Log/LogFactory.php | 78 | ||||
-rw-r--r-- | lib/private/Log/Rotate.php | 26 | ||||
-rw-r--r-- | lib/private/Log/Syslog.php | 25 | ||||
-rw-r--r-- | lib/private/Server.php | 21 | ||||
-rw-r--r-- | lib/private/Settings/Admin/Mail.php (renamed from lib/private/Settings/Admin/Additional.php) | 6 | ||||
-rw-r--r-- | lib/private/Settings/Admin/Overview.php | 154 | ||||
-rw-r--r-- | lib/private/Settings/Admin/Server.php | 56 | ||||
-rw-r--r-- | lib/private/Settings/Manager.php | 17 | ||||
-rw-r--r-- | lib/private/Template/SCSSCacher.php | 6 | ||||
-rw-r--r-- | lib/private/legacy/app.php | 2 | ||||
-rw-r--r-- | lib/private/legacy/util.php | 17 |
18 files changed, 382 insertions, 194 deletions
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index 37a34106dbe..c82ac5255dd 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -46,6 +46,7 @@ use OC\AppFramework\Middleware\Security\RateLimitingMiddleware; use OC\AppFramework\Middleware\Security\SecurityMiddleware; use OC\AppFramework\Middleware\SessionMiddleware; use OC\AppFramework\Utility\SimpleContainer; +use OC\Collaboration\Collaborators\SearchResult; use OC\Core\Middleware\TwoFactorMiddleware; use OC\RichObjectStrings\Validator; use OC\ServerContainer; @@ -53,6 +54,7 @@ use OCP\AppFramework\Http\IOutput; use OCP\AppFramework\IAppContainer; use OCP\AppFramework\QueryException; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\Collaboration\Collaborators\ISearchResult; use OCP\Files\Folder; use OCP\Files\IAppData; use OCP\GlobalScale\IConfig; @@ -62,7 +64,6 @@ use OCP\IRequest; use OCP\IServerContainer; use OCP\IUserSession; use OCP\RichObjectStrings\IValidator; -use OCP\Util; use OCP\Encryption\IManager; use OCA\WorkflowEngine\Manager; @@ -144,6 +145,8 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $c; }); + $this->registerAlias(ISearchResult::class, SearchResult::class); + // commonly used attributes $this->registerService('UserId', function ($c) { return $c->query(IUserSession::class)->getSession()->get('user_id'); diff --git a/lib/private/Files/Storage/Wrapper/Quota.php b/lib/private/Files/Storage/Wrapper/Quota.php index 22338f9c3cc..a7d5f3101fe 100644 --- a/lib/private/Files/Storage/Wrapper/Quota.php +++ b/lib/private/Files/Storage/Wrapper/Quota.php @@ -46,7 +46,7 @@ class Quota extends Wrapper { * @param array $parameters */ public function __construct($parameters) { - $this->storage = $parameters['storage']; + parent::__construct($parameters); $this->quota = $parameters['quota']; $this->sizeRoot = isset($parameters['root']) ? $parameters['root'] : ''; } @@ -83,7 +83,7 @@ class Quota extends Wrapper { * @return int */ public function free_space($path) { - if ($this->quota < 0) { + if ($this->quota < 0 || strpos($path, 'cache') === 0) { return $this->storage->free_space($path); } else { $used = $this->getSize($this->sizeRoot); @@ -111,7 +111,7 @@ class Quota extends Wrapper { * @return bool */ public function file_put_contents($path, $data) { - $free = $this->free_space(''); + $free = $this->free_space($path); if ($free < 0 or strlen($data) < $free) { return $this->storage->file_put_contents($path, $data); } else { @@ -127,7 +127,7 @@ class Quota extends Wrapper { * @return bool */ public function copy($source, $target) { - $free = $this->free_space(''); + $free = $this->free_space($target); if ($free < 0 or $this->getSize($source) < $free) { return $this->storage->copy($source, $target); } else { @@ -147,7 +147,7 @@ class Quota extends Wrapper { // don't apply quota for part files if (!$this->isPartFile($path)) { - $free = $this->free_space(''); + $free = $this->free_space($path); if ($source && $free >= 0 && $mode !== 'r' && $mode !== 'rb') { // only apply quota for files, not metadata, trash or others if (strpos(ltrim($path, '/'), 'files/') === 0) { @@ -178,7 +178,7 @@ class Quota extends Wrapper { * @return bool */ public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) { - $free = $this->free_space(''); + $free = $this->free_space($targetInternalPath); if ($free < 0 or $this->getSize($sourceInternalPath, $sourceStorage) < $free) { return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } else { @@ -193,11 +193,19 @@ class Quota extends Wrapper { * @return bool */ public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) { - $free = $this->free_space(''); + $free = $this->free_space($targetInternalPath); if ($free < 0 or $this->getSize($sourceInternalPath, $sourceStorage) < $free) { return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } else { return false; } } + + public function mkdir($path) { + if ($this->quota === 0.0) { + return false; + } + + return parent::mkdir($path); + } } diff --git a/lib/private/Files/Stream/Encryption.php b/lib/private/Files/Stream/Encryption.php index 05be5a5b286..65d379c0289 100644 --- a/lib/private/Files/Stream/Encryption.php +++ b/lib/private/Files/Stream/Encryption.php @@ -195,10 +195,10 @@ class Encryption extends Wrapper { protected static function wrapSource($source, $context, $protocol, $class, $mode = 'r+') { try { stream_wrapper_register($protocol, $class); - if (@rewinddir($source) === false) { - $wrapped = fopen($protocol . '://', $mode, false, $context); - } else { + if (self::isDirectoryHandle($source)) { $wrapped = opendir($protocol . '://', $context); + } else { + $wrapped = fopen($protocol . '://', $mode, false, $context); } } catch (\BadMethodCallException $e) { stream_wrapper_unregister($protocol); diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index a149cdf0af5..527ca728229 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -1316,15 +1316,13 @@ class View { try { // if the file is not in the cache or needs to be updated, trigger the scanner and reload the data if (!$data || $data['size'] === -1) { - $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED); if (!$storage->file_exists($internalPath)) { - $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED); return false; } + // don't need to get a lock here since the scanner does it's own locking $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); $data = $cache->get($internalPath); - $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED); } else if (!Cache\Scanner::isPartialFile($internalPath) && $watcher->needsUpdate($internalPath, $data)) { $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED); $watcher->update($internalPath, $data); @@ -1361,6 +1359,7 @@ class View { $mount = Filesystem::getMountManager()->find($path); if (!$mount) { + \OC::$server->getLogger()->warning('Mountpoint not found for path: ' . $path); return false; } $storage = $mount->getStorage(); @@ -1392,6 +1391,8 @@ class View { } return $info; + } else { + \OC::$server->getLogger()->warning('Storage not valid for mountpoint: ' . $mount->getMountPoint()); } return false; diff --git a/lib/private/Log.php b/lib/private/Log.php index ffe8c665c6f..69705c49e87 100644 --- a/lib/private/Log.php +++ b/lib/private/Log.php @@ -38,7 +38,8 @@ namespace OC; use InterfaSys\LogNormalizer\Normalizer; use OC\Log\ExceptionSerializer; -use OC\Log\File; +use OCP\Log\IFileBased; +use OCP\Log\IWriter; use OCP\ILogger; use OCP\Support\CrashReport\IRegistry; use OCP\Util; @@ -54,7 +55,7 @@ use OCP\Util; */ class Log implements ILogger { - /** @var string */ + /** @var IWriter */ private $logger; /** @var SystemConfig */ @@ -70,27 +71,19 @@ class Log implements ILogger { private $crashReporters; /** - * @param string $logger The logger that should be used + * @param IWriter $logger The logger that should be used * @param SystemConfig $config the system config object * @param Normalizer|null $normalizer * @param IRegistry|null $registry */ - public function __construct($logger = null, SystemConfig $config = null, $normalizer = null, IRegistry $registry = null) { + public function __construct(IWriter $logger, SystemConfig $config = null, $normalizer = null, IRegistry $registry = null) { // FIXME: Add this for backwards compatibility, should be fixed at some point probably if ($config === null) { $config = \OC::$server->getSystemConfig(); } $this->config = $config; - - // FIXME: Add this for backwards compatibility, should be fixed at some point probably - if ($logger === null) { - $logType = $this->config->getValue('log_type', 'file'); - $this->logger = static::getLogClass($logType); - call_user_func([$this->logger, 'init']); - } else { - $this->logger = $logger; - } + $this->logger = $logger; if ($normalizer === null) { $this->normalizer = new Normalizer(); } else { @@ -302,7 +295,7 @@ class Log implements ILogger { array_walk($context, [$this->normalizer, 'format']); if ($level >= $minLevel) { - if ($this->logger !== File::class) { + if (!$this->logger instanceof IFileBased) { $data = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR); } $this->writeLog($app, $data, $level); @@ -320,28 +313,13 @@ class Log implements ILogger { * @param int $level */ protected function writeLog(string $app, $entry, int $level) { - call_user_func([$this->logger, 'write'], $app, $entry, $level); + $this->logger->write($app, $entry, $level); } - /** - * @param string $logType - * @return string - * @internal - */ - public static function getLogClass(string $logType): string { - switch (strtolower($logType)) { - case 'errorlog': - return \OC\Log\Errorlog::class; - case 'syslog': - return \OC\Log\Syslog::class; - case 'file': - return \OC\Log\File::class; - - // Backwards compatibility for old and fallback for unknown log types - case 'owncloud': - case 'nextcloud': - default: - return \OC\Log\File::class; + public function getLogPath():string { + if($this->logger instanceof IFileBased) { + return $this->logger->getLogFilePath(); } + throw new \RuntimeException('Log implementation has no path'); } } diff --git a/lib/private/Log/Errorlog.php b/lib/private/Log/Errorlog.php index 37498c36aba..9dc8b2cc49c 100644 --- a/lib/private/Log/Errorlog.php +++ b/lib/private/Log/Errorlog.php @@ -25,14 +25,9 @@ namespace OC\Log; -class Errorlog { +use OCP\Log\IWriter; - - /** - * Init class data - */ - public static function init() { - } +class Errorlog implements IWriter { /** * write a message in the log @@ -40,7 +35,7 @@ class Errorlog { * @param string $message * @param int $level */ - public static function write($app, $message, $level) { + public function write(string $app, $message, int $level) { error_log('[owncloud]['.$app.']['.$level.'] '.$message); } } diff --git a/lib/private/Log/File.php b/lib/private/Log/File.php index 755c4729c7a..597cb54e402 100644 --- a/lib/private/Log/File.php +++ b/lib/private/Log/File.php @@ -36,7 +36,9 @@ */ namespace OC\Log; - +use OC\SystemConfig; +use OCP\Log\IFileBased; +use OCP\Log\IWriter; use OCP\ILogger; /** @@ -45,30 +47,26 @@ use OCP\ILogger; * Log is saved at data/nextcloud.log (on default) */ -class File { - static protected $logFile; - - /** - * Init class data - */ - public static function init() { - $systemConfig = \OC::$server->getSystemConfig(); - $defaultLogFile = $systemConfig->getValue("datadirectory", \OC::$SERVERROOT.'/data').'/nextcloud.log'; - self::$logFile = $systemConfig->getValue("logfile", $defaultLogFile); +class File implements IWriter, IFileBased { + /** @var string */ + protected $logFile; + /** @var SystemConfig */ + private $config; - /** - * Fall back to default log file if specified logfile does not exist - * and can not be created. - */ - if (!file_exists(self::$logFile)) { - if(!is_writable(dirname(self::$logFile))) { - self::$logFile = $defaultLogFile; - } else { - if(!touch(self::$logFile)) { - self::$logFile = $defaultLogFile; - } + public function __construct(string $path, string $fallbackPath = '', SystemConfig $config) { + $this->logFile = $path; + if (!file_exists($this->logFile)) { + if( + ( + !is_writable(dirname($this->logFile)) + || !touch($this->logFile) + ) + && $fallbackPath !== '' + ) { + $this->logFile = $fallbackPath; } } + $this->config = $config; } /** @@ -77,12 +75,10 @@ class File { * @param string|array $message * @param int $level */ - public static function write($app, $message, $level) { - $config = \OC::$server->getSystemConfig(); - + public function write(string $app, $message, int $level) { // default to ISO8601 - $format = $config->getValue('logdateformat', \DateTime::ATOM); - $logTimeZone = $config->getValue('logtimezone', 'UTC'); + $format = $this->config->getValue('logdateformat', \DateTime::ATOM); + $logTimeZone = $this->config->getValue('logtimezone', 'UTC'); try { $timezone = new \DateTimeZone($logTimeZone); } catch (\Exception $e) { @@ -102,7 +98,7 @@ class File { $time = $time->format($format); $url = ($request->getRequestUri() !== '') ? $request->getRequestUri() : '--'; $method = is_string($request->getMethod()) ? $request->getMethod() : '--'; - if($config->getValue('installed', false)) { + if($this->config->getValue('installed', false)) { $user = \OC_User::getUser() ? \OC_User::getUser() : '--'; } else { $user = '--'; @@ -111,7 +107,7 @@ class File { if ($userAgent === '') { $userAgent = '--'; } - $version = $config->getValue('version', ''); + $version = $this->config->getValue('version', ''); $entry = compact( 'reqId', 'level', @@ -137,9 +133,9 @@ class File { } } $entry = json_encode($entry, JSON_PARTIAL_OUTPUT_ON_ERROR); - $handle = @fopen(self::$logFile, 'a'); - if ((fileperms(self::$logFile) & 0777) != 0640) { - @chmod(self::$logFile, 0640); + $handle = @fopen($this->logFile, 'a'); + if ((fileperms($this->logFile) & 0777) != 0640) { + @chmod($this->logFile, 0640); } if ($handle) { fwrite($handle, $entry."\n"); @@ -159,11 +155,10 @@ class File { * @param int $offset * @return array */ - public static function getEntries($limit=50, $offset=0) { - self::init(); - $minLevel = \OC::$server->getSystemConfig()->getValue("loglevel", ILogger::WARN); + public function getEntries(int $limit=50, int $offset=0):array { + $minLevel = $this->config->getValue("loglevel", ILogger::WARN); $entries = array(); - $handle = @fopen(self::$logFile, 'rb'); + $handle = @fopen($this->logFile, 'rb'); if ($handle) { fseek($handle, 0, SEEK_END); $pos = ftell($handle); @@ -205,7 +200,7 @@ class File { /** * @return string */ - public static function getLogFilePath() { - return self::$logFile; + public function getLogFilePath():string { + return $this->logFile; } } diff --git a/lib/private/Log/LogFactory.php b/lib/private/Log/LogFactory.php new file mode 100644 index 00000000000..9b9d12abfa8 --- /dev/null +++ b/lib/private/Log/LogFactory.php @@ -0,0 +1,78 @@ +<?php +/** + * @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Log; + +use OC\Log; +use OC\SystemConfig; +use OCP\ILogger; +use OCP\IServerContainer; +use OCP\Log\ILogFactory; +use OCP\Log\IWriter; + +class LogFactory implements ILogFactory { + /** @var IServerContainer */ + private $c; + /** @var SystemConfig */ + private $systemConfig; + + public function __construct(IServerContainer $c, SystemConfig $systemConfig) { + $this->c = $c; + $this->systemConfig = $systemConfig; + } + + /** + * @throws \OCP\AppFramework\QueryException + */ + public function get(string $type):IWriter { + switch (strtolower($type)) { + case 'errorlog': + return new Errorlog(); + case 'syslog': + return $this->c->resolve(Syslog::class); + case 'file': + return $this->buildLogFile(); + + // Backwards compatibility for old and fallback for unknown log types + case 'owncloud': + case 'nextcloud': + default: + return $this->buildLogFile(); + } + } + + public function getCustomLogger(string $path):ILogger { + $log = $this->buildLogFile($path); + return new Log($log, $this->systemConfig); + } + + protected function buildLogFile(string $logFile = ''):File { + $defaultLogFile = $this->systemConfig->getValue('datadirectory', \OC::$SERVERROOT.'/data').'/nextcloud.log'; + if($logFile === '') { + $logFile = $this->systemConfig->getValue('logfile', $defaultLogFile); + } + $fallback = $defaultLogFile !== $logFile ? $defaultLogFile : ''; + + return new File($logFile, $fallback, $this->systemConfig); + } +} diff --git a/lib/private/Log/Rotate.php b/lib/private/Log/Rotate.php index 48b96c98a8d..cc41c804ad3 100644 --- a/lib/private/Log/Rotate.php +++ b/lib/private/Log/Rotate.php @@ -24,7 +24,7 @@ */ namespace OC\Log; -use OCP\ILogger; +use OCP\Log\RotationTrait; /** * This rotates the current logfile to a new name, this way the total log usage @@ -33,23 +33,17 @@ use OCP\ILogger; * location and manage that with your own tools. */ class Rotate extends \OC\BackgroundJob\Job { - private $max_log_size; + use RotationTrait; + public function run($dummy) { $systemConfig = \OC::$server->getSystemConfig(); - $logFile = $systemConfig->getValue('logfile', $systemConfig->getValue('datadirectory', \OC::$SERVERROOT . '/data') . '/nextcloud.log'); - $this->max_log_size = \OC::$server->getConfig()->getSystemValue('log_rotate_size', 100 * 1024 * 1024); - if ($this->max_log_size) { - $filesize = @filesize($logFile); - if ($filesize >= $this->max_log_size) { - $this->rotate($logFile); - } - } - } + $this->filePath = $systemConfig->getValue('logfile', $systemConfig->getValue('datadirectory', \OC::$SERVERROOT . '/data') . '/nextcloud.log'); - protected function rotate($logfile) { - $rotatedLogfile = $logfile.'.1'; - rename($logfile, $rotatedLogfile); - $msg = 'Log file "'.$logfile.'" was over '.$this->max_log_size.' bytes, moved to "'.$rotatedLogfile.'"'; - \OCP\Util::writeLog(Rotate::class, $msg, ILogger::WARN); + $this->maxSize = \OC::$server->getConfig()->getSystemValue('log_rotate_size', 100 * 1024 * 1024); + if($this->shouldRotateBySize()) { + $rotatedFile = $this->rotate(); + $msg = 'Log file "'.$this->filePath.'" was over '.$this->maxSize.' bytes, moved to "'.$rotatedFile.'"'; + \OC::$server->getLogger()->warning($msg, ['app' => Rotate::class]); + } } } diff --git a/lib/private/Log/Syslog.php b/lib/private/Log/Syslog.php index 7b3d931ef31..90a20026f0e 100644 --- a/lib/private/Log/Syslog.php +++ b/lib/private/Log/Syslog.php @@ -26,23 +26,24 @@ namespace OC\Log; use OCP\ILogger; +use OCP\IConfig; +use OCP\Log\IWriter; -class Syslog { - static protected $levels = array( +class Syslog implements IWriter { + protected $levels = [ ILogger::DEBUG => LOG_DEBUG, ILogger::INFO => LOG_INFO, ILogger::WARN => LOG_WARNING, ILogger::ERROR => LOG_ERR, ILogger::FATAL => LOG_CRIT, - ); + ]; - /** - * Init class data - */ - public static function init() { - openlog(\OC::$server->getSystemConfig()->getValue("syslog_tag", "ownCloud"), LOG_PID | LOG_CONS, LOG_USER); - // Close at shutdown - register_shutdown_function('closelog'); + public function __construct(IConfig $config) { + openlog($config->getSystemValue('syslog_tag', 'ownCloud'), LOG_PID | LOG_CONS, LOG_USER); + } + + public function __destruct() { + closelog(); } /** @@ -51,8 +52,8 @@ class Syslog { * @param string $message * @param int $level */ - public static function write($app, $message, $level) { - $syslog_level = self::$levels[$level]; + public function write(string $app, $message, int $level) { + $syslog_level = $this->levels[$level]; syslog($syslog_level, '{'.$app.'} '.$message); } } diff --git a/lib/private/Server.php b/lib/private/Server.php index 3786486c2b2..a879c65bb9b 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -87,6 +87,7 @@ use OC\Lock\DBLockingProvider; use OC\Lock\MemcacheLockingProvider; use OC\Lock\NoopLockingProvider; use OC\Lockdown\LockdownManager; +use OC\Log\LogFactory; use OC\Mail\Mailer; use OC\Memcache\ArrayCache; use OC\Memcache\Factory; @@ -134,6 +135,7 @@ use OCP\ITempManager; use OCP\Contacts\ContactsMenu\IActionFactory; use OCP\IUser; use OCP\Lock\ILockingProvider; +use OCP\Log\ILogFactory; use OCP\Remote\Api\IApiFactory; use OCP\Remote\IInstanceFactory; use OCP\RichObjectStrings\IValidator; @@ -546,15 +548,18 @@ class Server extends ServerContainer implements IServerContainer { $this->registerService(\OCP\ILogger::class, function (Server $c) { $logType = $c->query('AllConfig')->getSystemValue('log_type', 'file'); - $logger = Log::getLogClass($logType); - call_user_func(array($logger, 'init')); - $config = $this->getSystemConfig(); + $factory = new LogFactory($c, $this->getSystemConfig()); + $logger = $factory->get($logType); $registry = $c->query(\OCP\Support\CrashReport\IRegistry::class); - return new Log($logger, $config, null, $registry); + return new Log($logger, $this->getSystemConfig(), null, $registry); }); $this->registerAlias('Logger', \OCP\ILogger::class); + $this->registerService(ILogFactory::class, function (Server $c) { + return new LogFactory($c, $this->getSystemConfig()); + }); + $this->registerService(\OCP\BackgroundJob\IJobList::class, function (Server $c) { $config = $c->getConfig(); return new \OC\BackgroundJob\JobList( @@ -1529,6 +1534,14 @@ class Server extends ServerContainer implements IServerContainer { } /** + * @return ILogFactory + * @throws \OCP\AppFramework\QueryException + */ + public function getLogFactory() { + return $this->query(ILogFactory::class); + } + + /** * Returns a router for generating and matching urls * * @return \OCP\Route\IRouter diff --git a/lib/private/Settings/Admin/Additional.php b/lib/private/Settings/Admin/Mail.php index 36258573047..74a94a4c7a0 100644 --- a/lib/private/Settings/Admin/Additional.php +++ b/lib/private/Settings/Admin/Mail.php @@ -29,7 +29,7 @@ use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; use OCP\Settings\ISettings; -class Additional implements ISettings { +class Mail implements ISettings { /** @var IConfig */ private $config; @@ -70,7 +70,7 @@ class Additional implements ISettings { * @return string the section ID, e.g. 'sharing' */ public function getSection() { - return 'additional'; + return 'server'; } /** @@ -81,6 +81,6 @@ class Additional implements ISettings { * E.g.: 70 */ public function getPriority() { - return 0; + return 10; } } diff --git a/lib/private/Settings/Admin/Overview.php b/lib/private/Settings/Admin/Overview.php new file mode 100644 index 00000000000..6e186dc6f98 --- /dev/null +++ b/lib/private/Settings/Admin/Overview.php @@ -0,0 +1,154 @@ +<?php +/** + * @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings\Admin; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Platforms\SqlitePlatform; +use OC\Lock\DBLockingProvider; +use OC\Lock\NoopLockingProvider; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IL10N; +use OCP\IRequest; +use OCP\Lock\ILockingProvider; +use OCP\Settings\ISettings; + +class Overview implements ISettings { + /** @var IDBConnection|Connection */ + private $db; + /** @var IRequest */ + private $request; + /** @var IConfig */ + private $config; + /** @var ILockingProvider */ + private $lockingProvider; + /** @var IL10N */ + private $l; + + /** + * @param IDBConnection $db + * @param IRequest $request + * @param IConfig $config + * @param ILockingProvider $lockingProvider + * @param IL10N $l + */ + public function __construct(IDBConnection $db, + IRequest $request, + IConfig $config, + ILockingProvider $lockingProvider, + IL10N $l) { + $this->db = $db; + $this->request = $request; + $this->config = $config; + $this->lockingProvider = $lockingProvider; + $this->l = $l; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + try { + if ($this->db->getDatabasePlatform() instanceof SqlitePlatform) { + $invalidTransactionIsolationLevel = false; + } else { + $invalidTransactionIsolationLevel = $this->db->getTransactionIsolation() !== Connection::TRANSACTION_READ_COMMITTED; + } + } catch (DBALException $e) { + // ignore + $invalidTransactionIsolationLevel = false; + } + + $envPath = getenv('PATH'); + + // warn if outdated version of a memcache module is used + $caches = [ + 'apcu' => ['name' => $this->l->t('APCu'), 'version' => '4.0.6'], + 'redis' => ['name' => $this->l->t('Redis'), 'version' => '2.2.5'], + ]; + $outdatedCaches = []; + foreach ($caches as $php_module => $data) { + $isOutdated = extension_loaded($php_module) && version_compare(phpversion($php_module), $data['version'], '<'); + if ($isOutdated) { + $outdatedCaches[$php_module] = $data; + } + } + + if ($this->lockingProvider instanceof NoopLockingProvider) { + $fileLockingType = 'none'; + } else if ($this->lockingProvider instanceof DBLockingProvider) { + $fileLockingType = 'db'; + } else { + $fileLockingType = 'cache'; + } + + $suggestedOverwriteCliUrl = ''; + if ($this->config->getSystemValue('overwrite.cli.url', '') === '') { + $suggestedOverwriteCliUrl = $this->request->getServerProtocol() . '://' . $this->request->getInsecureServerHost() . \OC::$WEBROOT; + if (!$this->config->getSystemValue('config_is_read_only', false)) { + // Set the overwrite URL when it was not set yet. + $this->config->setSystemValue('overwrite.cli.url', $suggestedOverwriteCliUrl); + $suggestedOverwriteCliUrl = ''; + } + } + + $parameters = [ + // Diagnosis + 'readOnlyConfigEnabled' => \OC_Helper::isReadOnlyConfigEnabled(), + 'isLocaleWorking' => \OC_Util::isSetLocaleWorking(), + 'isAnnotationsWorking' => \OC_Util::isAnnotationsWorking(), + 'checkForWorkingWellKnownSetup' => $this->config->getSystemValue('check_for_working_wellknown_setup', true), + 'has_fileinfo' => \OC_Util::fileInfoLoaded(), + 'invalidTransactionIsolationLevel' => $invalidTransactionIsolationLevel, + 'getenvServerNotWorking' => empty($envPath), + 'OutdatedCacheWarning' => $outdatedCaches, + 'fileLockingType' => $fileLockingType, + 'suggestedOverwriteCliUrl' => $suggestedOverwriteCliUrl, + 'lastcron' => $this->config->getAppValue('core', 'lastcron', false), + 'cronErrors' => $this->config->getAppValue('core', 'cronErrors'), + ]; + + return new TemplateResponse('settings', 'settings/admin/overview', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'overview'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 10; + } +} diff --git a/lib/private/Settings/Admin/Server.php b/lib/private/Settings/Admin/Server.php index 0b9c042e4f2..1ebea8a4dcd 100644 --- a/lib/private/Settings/Admin/Server.php +++ b/lib/private/Settings/Admin/Server.php @@ -74,63 +74,7 @@ class Server implements ISettings { * @return TemplateResponse */ public function getForm() { - try { - if ($this->db->getDatabasePlatform() instanceof SqlitePlatform) { - $invalidTransactionIsolationLevel = false; - } else { - $invalidTransactionIsolationLevel = $this->db->getTransactionIsolation() !== Connection::TRANSACTION_READ_COMMITTED; - } - } catch (DBALException $e) { - // ignore - $invalidTransactionIsolationLevel = false; - } - - $envPath = getenv('PATH'); - - // warn if outdated version of a memcache module is used - $caches = [ - 'apcu' => ['name' => $this->l->t('APCu'), 'version' => '4.0.6'], - 'redis' => ['name' => $this->l->t('Redis'), 'version' => '2.2.5'], - ]; - $outdatedCaches = []; - foreach ($caches as $php_module => $data) { - $isOutdated = extension_loaded($php_module) && version_compare(phpversion($php_module), $data['version'], '<'); - if ($isOutdated) { - $outdatedCaches[$php_module] = $data; - } - } - - if ($this->lockingProvider instanceof NoopLockingProvider) { - $fileLockingType = 'none'; - } else if ($this->lockingProvider instanceof DBLockingProvider) { - $fileLockingType = 'db'; - } else { - $fileLockingType = 'cache'; - } - - $suggestedOverwriteCliUrl = ''; - if ($this->config->getSystemValue('overwrite.cli.url', '') === '') { - $suggestedOverwriteCliUrl = $this->request->getServerProtocol() . '://' . $this->request->getInsecureServerHost() . \OC::$WEBROOT; - if (!$this->config->getSystemValue('config_is_read_only', false)) { - // Set the overwrite URL when it was not set yet. - $this->config->setSystemValue('overwrite.cli.url', $suggestedOverwriteCliUrl); - $suggestedOverwriteCliUrl = ''; - } - } - $parameters = [ - // Diagnosis - 'readOnlyConfigEnabled' => \OC_Helper::isReadOnlyConfigEnabled(), - 'isLocaleWorking' => \OC_Util::isSetLocaleWorking(), - 'isAnnotationsWorking' => \OC_Util::isAnnotationsWorking(), - 'checkForWorkingWellKnownSetup' => $this->config->getSystemValue('check_for_working_wellknown_setup', true), - 'has_fileinfo' => \OC_Util::fileInfoLoaded(), - 'invalidTransactionIsolationLevel' => $invalidTransactionIsolationLevel, - 'getenvServerNotWorking' => empty($envPath), - 'OutdatedCacheWarning' => $outdatedCaches, - 'fileLockingType' => $fileLockingType, - 'suggestedOverwriteCliUrl' => $suggestedOverwriteCliUrl, - // Background jobs 'backgroundjobs_mode' => $this->config->getAppValue('core', 'backgroundjobs_mode', 'ajax'), 'lastcron' => $this->config->getAppValue('core', 'lastcron', false), diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 49f699223f6..becc670c6f9 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -226,7 +226,8 @@ class Manager implements IManager { public function getAdminSections(): array { // built-in sections $sections = [ - 0 => [new Section('server', $this->l->t('Basic settings'), 0, $this->url->imagePath('settings', 'admin.svg'))], + 0 => [new Section('overview', $this->l->t('Overview'), 0, $this->url->imagePath('settings', 'admin.svg'))], + 1 => [new Section('server', $this->l->t('Basic settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))], 5 => [new Section('sharing', $this->l->t('Sharing'), 0, $this->url->imagePath('core', 'actions/share.svg'))], 10 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('core', 'actions/password.svg'))], 45 => [new Section('encryption', $this->l->t('Encryption'), 0, $this->url->imagePath('core', 'actions/password.svg'))], @@ -257,11 +258,18 @@ class Manager implements IManager { private function getBuiltInAdminSettings($section): array { $forms = []; + if ($section === 'overview') { + /** @var ISettings $form */ + $form = new Admin\Overview($this->dbc, $this->request, $this->config, $this->lockingProvider, $this->l); + $forms[$form->getPriority()] = [$form]; + $form = new Admin\ServerDevNotice(); + $forms[$form->getPriority()] = [$form]; + } if ($section === 'server') { /** @var ISettings $form */ $form = new Admin\Server($this->dbc, $this->request, $this->config, $this->lockingProvider, $this->l); $forms[$form->getPriority()] = [$form]; - $form = new Admin\ServerDevNotice(); + $form = new Admin\Mail($this->config); $forms[$form->getPriority()] = [$form]; } if ($section === 'encryption') { @@ -274,11 +282,6 @@ class Manager implements IManager { $form = new Admin\Sharing($this->config, $this->l); $forms[$form->getPriority()] = [$form]; } - if ($section === 'additional') { - /** @var ISettings $form */ - $form = new Admin\Additional($this->config); - $forms[$form->getPriority()] = [$form]; - } if ($section === 'tips-tricks') { /** @var ISettings $form */ $form = new Admin\TipsTricks($this->config); diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php index 6fb9d11953b..6e25e1fa5de 100644 --- a/lib/private/Template/SCSSCacher.php +++ b/lib/private/Template/SCSSCacher.php @@ -273,7 +273,11 @@ class SCSSCacher { $appDirectory = $this->appData->getDirectoryListing(); foreach ($appDirectory as $folder) { foreach ($folder->getDirectoryListing() as $file) { - $file->delete(); + try { + $file->delete(); + } catch(NotPermittedException $e) { + $this->logger->logException($e, ['message' => 'SCSSCacher: unable to delete file: ' . $file->getName()]); + } } } } diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php index 7931eecc502..70f1b16e3c6 100644 --- a/lib/private/legacy/app.php +++ b/lib/private/legacy/app.php @@ -464,7 +464,7 @@ class OC_App { } else { $versionToLoad = []; foreach ($possibleApps as $possibleApp) { - $version = self::getAppVersionByPath($possibleApp['path']); + $version = self::getAppVersionByPath($possibleApp['path'] . '/' . $appId); if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) { $versionToLoad = array( 'dir' => $possibleApp, diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php index d3599d14e7a..356d336f687 100644 --- a/lib/private/legacy/util.php +++ b/lib/private/legacy/util.php @@ -259,6 +259,23 @@ class OC_Util { return $storage; }); + \OC\Files\Filesystem::addStorageWrapper('readonly', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) { + /* + * Do not allow any operations that modify the storage + */ + if ($mount->getOption('readonly', false)) { + return new \OC\Files\Storage\Wrapper\PermissionsMask([ + 'storage' => $storage, + 'mask' => \OCP\Constants::PERMISSION_ALL & ~( + \OCP\Constants::PERMISSION_UPDATE | + \OCP\Constants::PERMISSION_CREATE | + \OCP\Constants::PERMISSION_DELETE + ), + ]); + } + return $storage; + }); + OC_Hook::emit('OC_Filesystem', 'preSetup', array('user' => $user)); \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(true); |