diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/l10n/da.js | 1 | ||||
-rw-r--r-- | lib/l10n/da.json | 1 | ||||
-rw-r--r-- | lib/l10n/fa.js | 1 | ||||
-rw-r--r-- | lib/l10n/fa.json | 1 | ||||
-rw-r--r-- | lib/private/AppFramework/Bootstrap/Coordinator.php | 2 | ||||
-rw-r--r-- | lib/private/AppFramework/Bootstrap/RegistrationContext.php | 4 | ||||
-rw-r--r-- | lib/private/Command/ClosureJob.php | 5 | ||||
-rw-r--r-- | lib/private/Command/CommandJob.php | 2 | ||||
-rw-r--r-- | lib/private/Command/CronBus.php | 5 | ||||
-rw-r--r-- | lib/private/Dashboard/Manager.php | 35 | ||||
-rw-r--r-- | lib/private/Files/Storage/Common.php | 1 | ||||
-rw-r--r-- | lib/private/Http/Client/LocalAddressChecker.php | 6 | ||||
-rw-r--r-- | lib/private/L10N/L10N.php | 2 | ||||
-rw-r--r-- | lib/private/Log.php | 34 | ||||
-rw-r--r-- | lib/private/Log/ExceptionSerializer.php | 12 | ||||
-rw-r--r-- | lib/private/Log/LogDetails.php | 4 | ||||
-rw-r--r-- | lib/private/Mail/EMailTemplate.php | 2 | ||||
-rw-r--r-- | lib/private/Memcache/Memcached.php | 30 | ||||
-rw-r--r-- | lib/private/Setup/MySQL.php | 2 | ||||
-rw-r--r-- | lib/public/Dashboard/IManager.php | 2 |
20 files changed, 84 insertions, 68 deletions
diff --git a/lib/l10n/da.js b/lib/l10n/da.js index cbcf6cd32c7..683b6da5338 100644 --- a/lib/l10n/da.js +++ b/lib/l10n/da.js @@ -18,6 +18,7 @@ OC.L10N.register( "Authentication" : "Godkendelse", "Unknown filetype" : "Ukendt filtype", "Invalid image" : "Ugyldigt billede", + "View profile" : "Vis profil", "today" : "i dag", "tomorrow" : "i morgen", "yesterday" : "i går", diff --git a/lib/l10n/da.json b/lib/l10n/da.json index 8e18ffdb314..cadfde89f09 100644 --- a/lib/l10n/da.json +++ b/lib/l10n/da.json @@ -16,6 +16,7 @@ "Authentication" : "Godkendelse", "Unknown filetype" : "Ukendt filtype", "Invalid image" : "Ugyldigt billede", + "View profile" : "Vis profil", "today" : "i dag", "tomorrow" : "i morgen", "yesterday" : "i går", diff --git a/lib/l10n/fa.js b/lib/l10n/fa.js index d4bb5db0142..95a78ce1015 100644 --- a/lib/l10n/fa.js +++ b/lib/l10n/fa.js @@ -42,6 +42,7 @@ OC.L10N.register( "Unknown filetype" : "نوع فایل ناشناخته", "Invalid image" : "عکس نامعتبر", "Avatar image is not square" : "تصویر آواتار مربع نیست", + "View profile" : "مشاهده پروفایل", "today" : "امروز", "tomorrow" : "فردا", "yesterday" : "دیروز", diff --git a/lib/l10n/fa.json b/lib/l10n/fa.json index d8dabdaed32..3fbaf99cfa9 100644 --- a/lib/l10n/fa.json +++ b/lib/l10n/fa.json @@ -40,6 +40,7 @@ "Unknown filetype" : "نوع فایل ناشناخته", "Invalid image" : "عکس نامعتبر", "Avatar image is not square" : "تصویر آواتار مربع نیست", + "View profile" : "مشاهده پروفایل", "today" : "امروز", "tomorrow" : "فردا", "yesterday" : "دیروز", diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php index b6378830732..3ab6ac4c8b0 100644 --- a/lib/private/AppFramework/Bootstrap/Coordinator.php +++ b/lib/private/AppFramework/Bootstrap/Coordinator.php @@ -151,7 +151,7 @@ class Coordinator { */ $this->registrationContext->delegateCapabilityRegistrations($apps); $this->registrationContext->delegateCrashReporterRegistrations($apps, $this->registry); - $this->registrationContext->delegateDashboardPanelRegistrations($apps, $this->dashboardManager); + $this->registrationContext->delegateDashboardPanelRegistrations($this->dashboardManager); $this->registrationContext->delegateEventListenerRegistrations($this->eventDispatcher); $this->registrationContext->delegateContainerRegistrations($apps); $this->registrationContext->delegateMiddlewareRegistrations($apps); diff --git a/lib/private/AppFramework/Bootstrap/RegistrationContext.php b/lib/private/AppFramework/Bootstrap/RegistrationContext.php index 7b4d24036e8..8f6aff228e1 100644 --- a/lib/private/AppFramework/Bootstrap/RegistrationContext.php +++ b/lib/private/AppFramework/Bootstrap/RegistrationContext.php @@ -475,10 +475,10 @@ class RegistrationContext { /** * @param App[] $apps */ - public function delegateDashboardPanelRegistrations(array $apps, IManager $dashboardManager): void { + public function delegateDashboardPanelRegistrations(IManager $dashboardManager): void { while (($panel = array_shift($this->dashboardPanels)) !== null) { try { - $dashboardManager->lazyRegisterWidget($panel->getService()); + $dashboardManager->lazyRegisterWidget($panel->getService(), $panel->getAppId()); } catch (Throwable $e) { $appId = $panel->getAppId(); $this->logger->error("Error during dashboard registration of $appId: " . $e->getMessage(), [ diff --git a/lib/private/Command/ClosureJob.php b/lib/private/Command/ClosureJob.php index 498fe6d1d96..5639852e4db 100644 --- a/lib/private/Command/ClosureJob.php +++ b/lib/private/Command/ClosureJob.php @@ -23,10 +23,13 @@ namespace OC\Command; use OC\BackgroundJob\QueuedJob; +use Laravel\SerializableClosure\SerializableClosure as LaravelClosure; +use Opis\Closure\SerializableClosure as OpisClosure; class ClosureJob extends QueuedJob { protected function run($serializedCallable) { - $callable = \Opis\Closure\unserialize($serializedCallable); + $callable = unserialize($serializedCallable, [LaravelClosure::class, OpisClosure::class]); + $callable = $callable->getClosure(); if (is_callable($callable)) { $callable(); } else { diff --git a/lib/private/Command/CommandJob.php b/lib/private/Command/CommandJob.php index 6fa0c6d7ceb..5b267162c81 100644 --- a/lib/private/Command/CommandJob.php +++ b/lib/private/Command/CommandJob.php @@ -30,7 +30,7 @@ use OCP\Command\ICommand; */ class CommandJob extends QueuedJob { protected function run($serializedCommand) { - $command = \Opis\Closure\unserialize($serializedCommand); + $command = unserialize($serializedCommand); if ($command instanceof ICommand) { $command->handle(); } else { diff --git a/lib/private/Command/CronBus.php b/lib/private/Command/CronBus.php index 89a739617d0..8749ad0bff5 100644 --- a/lib/private/Command/CronBus.php +++ b/lib/private/Command/CronBus.php @@ -26,6 +26,7 @@ namespace OC\Command; use OCP\Command\ICommand; +use Laravel\SerializableClosure\SerializableClosure; class CronBus extends AsyncBus { /** @@ -67,9 +68,9 @@ class CronBus extends AsyncBus { */ private function serializeCommand($command) { if ($command instanceof \Closure) { - return \Opis\Closure\serialize($command); + return serialize(new SerializableClosure($command)); } elseif (is_callable($command) or $command instanceof ICommand) { - return \Opis\Closure\serialize($command); + return serialize($command); } else { throw new \InvalidArgumentException('Invalid command'); } diff --git a/lib/private/Dashboard/Manager.php b/lib/private/Dashboard/Manager.php index 09525693b4f..2aeedf3174e 100644 --- a/lib/private/Dashboard/Manager.php +++ b/lib/private/Dashboard/Manager.php @@ -27,10 +27,11 @@ declare(strict_types=1); namespace OC\Dashboard; use InvalidArgumentException; -use OCP\AppFramework\QueryException; +use OCP\App\IAppManager; use OCP\Dashboard\IManager; use OCP\Dashboard\IWidget; -use OCP\IServerContainer; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\ContainerInterface; use Throwable; use Psr\Log\LoggerInterface; @@ -42,10 +43,10 @@ class Manager implements IManager { /** @var IWidget[] */ private $widgets = []; - /** @var IServerContainer */ - private $serverContainer; + private ContainerInterface $serverContainer; + private ?IAppManager $appManager = null; - public function __construct(IServerContainer $serverContainer) { + public function __construct(ContainerInterface $serverContainer) { $this->serverContainer = $serverContainer; } @@ -57,17 +58,25 @@ class Manager implements IManager { $this->widgets[$widget->getId()] = $widget; } - public function lazyRegisterWidget(string $widgetClass): void { - $this->lazyWidgets[] = $widgetClass; + public function lazyRegisterWidget(string $widgetClass, string $appId): void { + $this->lazyWidgets[] = ['class' => $widgetClass, 'appId' => $appId]; } public function loadLazyPanels(): void { - $classes = $this->lazyWidgets; - foreach ($classes as $class) { + if ($this->appManager === null) { + $this->appManager = $this->serverContainer->get(IAppManager::class); + } + $services = $this->lazyWidgets; + foreach ($services as $service) { + /** @psalm-suppress InvalidCatch */ try { + if (!$this->appManager->isEnabledForUser($service['appId'])) { + // all apps are registered, but some may not be enabled for the user + continue; + } /** @var IWidget $widget */ - $widget = $this->serverContainer->query($class); - } catch (QueryException $e) { + $widget = $this->serverContainer->get($service['class']); + } catch (ContainerExceptionInterface $e) { /* * There is a circular dependency between the logger and the registry, so * we can not inject it. Thus the static call. @@ -90,7 +99,7 @@ class Manager implements IManager { */ \OC::$server->get(LoggerInterface::class)->critical( 'Could not register lazy dashboard widget: ' . $e->getMessage(), - ['excepiton' => $e] + ['exception' => $e] ); } @@ -111,7 +120,7 @@ class Manager implements IManager { } catch (Throwable $e) { \OC::$server->get(LoggerInterface::class)->critical( 'Error during dashboard widget loading: ' . $e->getMessage(), - ['excepiton' => $e] + ['exception' => $e] ); } } diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php index 3c970ee75f5..a7bc44e10e2 100644 --- a/lib/private/Files/Storage/Common.php +++ b/lib/private/Files/Storage/Common.php @@ -228,6 +228,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage { while ($file = readdir($dir)) { if (!Filesystem::isIgnoredDir($file)) { if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { + closedir($dir); return false; } } diff --git a/lib/private/Http/Client/LocalAddressChecker.php b/lib/private/Http/Client/LocalAddressChecker.php index 2789b1b5935..c69d1007a16 100644 --- a/lib/private/Http/Client/LocalAddressChecker.php +++ b/lib/private/Http/Client/LocalAddressChecker.php @@ -66,8 +66,10 @@ class LocalAddressChecker { $host = substr($host, 1, -1); } - // Disallow localhost and local network - if ($host === 'localhost' || substr($host, -6) === '.local' || substr($host, -10) === '.localhost') { + // Disallow local network top-level domains from RFC 6762 + $localTopLevelDomains = ['local','localhost','intranet','internal','private','corp','home','lan']; + $topLevelDomain = substr((strrchr($host, '.') ?: ''), 1); + if (in_array($topLevelDomain, $localTopLevelDomains)) { $this->logger->warning("Host $host was not connected to because it violates local access rules"); throw new LocalServerException('Host violates local access rules'); } diff --git a/lib/private/L10N/L10N.php b/lib/private/L10N/L10N.php index 09c0f1cdb35..82ef3350b1f 100644 --- a/lib/private/L10N/L10N.php +++ b/lib/private/L10N/L10N.php @@ -122,7 +122,7 @@ class L10N implements IL10N { * */ public function n(string $text_singular, string $text_plural, int $count, array $parameters = []): string { - $identifier = "_${text_singular}_::_${text_plural}_"; + $identifier = "_{$text_singular}_::_{$text_plural}_"; if (isset($this->translations[$identifier])) { return (string) new L10NString($this, $identifier, $parameters, $count); } diff --git a/lib/private/Log.php b/lib/private/Log.php index 0415967f0f0..95e0a833b66 100644 --- a/lib/private/Log.php +++ b/lib/private/Log.php @@ -15,6 +15,7 @@ declare(strict_types=1); * @author Olivier Paroz <github@oparoz.com> * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Thomas Citharel <nextcloud@tcit.fr> * @author Thomas Müller <thomas.mueller@tmit.eu> * @author Victor Dubiniuk <dubiniuk@owncloud.com> * @@ -207,11 +208,11 @@ class Log implements ILogger, IDataLogger { array_walk($context, [$this->normalizer, 'format']); $app = $context['app'] ?? 'no app in context'; - $message = $this->interpolateMessage($context, $message); + $entry = $this->interpolateMessage($context, $message); try { if ($level >= $minLevel) { - $this->writeLog($app, $message, $level); + $this->writeLog($app, $entry, $level); if ($this->crashReporters !== null) { $messageContext = array_merge( @@ -220,11 +221,11 @@ class Log implements ILogger, IDataLogger { 'level' => $level ] ); - $this->crashReporters->delegateMessage($message, $messageContext); + $this->crashReporters->delegateMessage($entry['message'], $messageContext); } } else { if ($this->crashReporters !== null) { - $this->crashReporters->delegateBreadcrumb($message, 'log', $context); + $this->crashReporters->delegateBreadcrumb($entry['message'], 'log', $context); } } } catch (\Throwable $e) { @@ -315,8 +316,11 @@ class Log implements ILogger, IDataLogger { $this->error("Failed to load ExceptionSerializer serializer while trying to log " . $exception->getMessage()); return; } - $data = $serializer->serializeException($exception); - $data['CustomMessage'] = $this->interpolateMessage($context, $context['message'] ?? '--'); + $data = $context; + unset($data['app']); + unset($data['level']); + $data = array_merge($serializer->serializeException($exception), $data); + $data = $this->interpolateMessage($data, $context['message'] ?? '--', 'CustomMessage'); $minLevel = $this->getLogLevel($context); @@ -381,16 +385,20 @@ class Log implements ILogger, IDataLogger { /** * Interpolate $message as defined in PSR-3 * - * @param array $context - * @param string $message - * - * @return string + * Returns an array containing the context without the interpolated + * parameters placeholders and the message as the 'message' - or + * user-defined - key. */ - private function interpolateMessage(array $context, string $message): string { + private function interpolateMessage(array $context, string $message, string $messageKey = 'message'): array { $replace = []; + $usedContextKeys = []; foreach ($context as $key => $val) { - $replace['{' . $key . '}'] = $val; + $fullKey = '{' . $key . '}'; + $replace[$fullKey] = $val; + if (strpos($message, $fullKey) !== false) { + $usedContextKeys[$key] = true; + } } - return strtr($message, $replace); + return array_merge(array_diff_key($context, $usedContextKeys), [$messageKey => strtr($message, $replace)]); } } diff --git a/lib/private/Log/ExceptionSerializer.php b/lib/private/Log/ExceptionSerializer.php index dab134b26a4..3c3ff95f8e1 100644 --- a/lib/private/Log/ExceptionSerializer.php +++ b/lib/private/Log/ExceptionSerializer.php @@ -42,6 +42,8 @@ use OCA\Encryption\Session; use OCP\HintException; class ExceptionSerializer { + public const SENSITIVE_VALUE_PLACEHOLDER = '*** sensitive parameters replaced ***'; + public const methodsWithSensitiveParameters = [ // Session/User 'completeLogin', @@ -180,7 +182,7 @@ class ExceptionSerializer { if (isset($traceLine['args'])) { $sensitiveValues = array_merge($sensitiveValues, $traceLine['args']); } - $traceLine['args'] = ['*** sensitive parameters replaced ***']; + $traceLine['args'] = [self::SENSITIVE_VALUE_PLACEHOLDER]; return $traceLine; } @@ -208,14 +210,16 @@ class ExceptionSerializer { } private function removeValuesFromArgs($args, $values) { - foreach ($args as &$arg) { + $workArgs = []; + foreach ($args as $arg) { if (in_array($arg, $values, true)) { - $arg = '*** sensitive parameter replaced ***'; + $arg = self::SENSITIVE_VALUE_PLACEHOLDER; } elseif (is_array($arg)) { $arg = $this->removeValuesFromArgs($arg, $values); } + $workArgs[] = $arg; } - return $args; + return $workArgs; } private function encodeTrace($trace) { diff --git a/lib/private/Log/LogDetails.php b/lib/private/Log/LogDetails.php index 3353ea3f4cc..b3544572708 100644 --- a/lib/private/Log/LogDetails.php +++ b/lib/private/Log/LogDetails.php @@ -5,6 +5,7 @@ * @author Arthur Schiwon <blizzz@arthur-schiwon.de> * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Julius Härtl <jus@bitgrid.net> + * @author Thomas Citharel <nextcloud@tcit.fr> * * @license GNU AGPL version 3 or any later version * @@ -90,8 +91,9 @@ abstract class LogDetails { $entry['exception'] = $message; $entry['message'] = $message['CustomMessage'] !== '--' ? $message['CustomMessage'] : $message['Message']; } else { - $entry['data'] = $message; $entry['message'] = $message['message'] ?? '(no message provided)'; + unset($message['message']); + $entry['data'] = $message; } } diff --git a/lib/private/Mail/EMailTemplate.php b/lib/private/Mail/EMailTemplate.php index 2c091deb2a1..7ec2b46bad3 100644 --- a/lib/private/Mail/EMailTemplate.php +++ b/lib/private/Mail/EMailTemplate.php @@ -497,7 +497,7 @@ EOF; */ /** @var string $label */ $label = ($plainMetaInfo !== false)? $plainMetaInfo : ''; - $this->plainBody .= sprintf("%${plainIndent}s %s\n", + $this->plainBody .= sprintf("%{$plainIndent}s %s\n", $label, str_replace("\n", "\n" . str_repeat(' ', $plainIndent + 1), $plainText)); } diff --git a/lib/private/Memcache/Memcached.php b/lib/private/Memcache/Memcached.php index db4aa7ba9cc..7d512d4d1ae 100644 --- a/lib/private/Memcache/Memcached.php +++ b/lib/private/Memcache/Memcached.php @@ -63,7 +63,7 @@ class Memcached extends Cache implements IMemcache { \Memcached::OPT_LIBKETAMA_COMPATIBLE => true, // Enable Binary Protocol - //\Memcached::OPT_BINARY_PROTOCOL => true, + \Memcached::OPT_BINARY_PROTOCOL => true, ]; /** * By default enable igbinary serializer if available @@ -119,10 +119,7 @@ class Memcached extends Cache implements IMemcache { } else { $result = self::$cache->set($this->getNameSpace() . $key, $value); } - if ($result !== true) { - $this->verifyReturnCode(); - } - return $result; + return $result || $this->isSuccess(); } public function hasKey($key) { @@ -132,10 +129,7 @@ class Memcached extends Cache implements IMemcache { public function remove($key) { $result = self::$cache->delete($this->getNameSpace() . $key); - if (self::$cache->getResultCode() !== \Memcached::RES_NOTFOUND) { - $this->verifyReturnCode(); - } - return $result; + return $result || $this->isSuccess() || self::$cache->getResultCode() === \Memcached::RES_NOTFOUND; } public function clear($prefix = '') { @@ -151,14 +145,10 @@ class Memcached extends Cache implements IMemcache { * @param mixed $value * @param int $ttl Time To Live in seconds. Defaults to 60*60*24 * @return bool - * @throws \Exception */ public function add($key, $value, $ttl = 0) { $result = self::$cache->add($this->getPrefix() . $key, $value, $ttl); - if (self::$cache->getResultCode() !== \Memcached::RES_NOTSTORED) { - $this->verifyReturnCode(); - } - return $result; + return $result || $this->isSuccess(); } /** @@ -200,15 +190,7 @@ class Memcached extends Cache implements IMemcache { return extension_loaded('memcached'); } - /** - * @throws \Exception - */ - private function verifyReturnCode() { - $code = self::$cache->getResultCode(); - if ($code === \Memcached::RES_SUCCESS) { - return; - } - $message = self::$cache->getResultMessage(); - throw new \Exception("Error $code interacting with memcached : $message"); + private function isSuccess(): bool { + return self::$cache->getResultCode() === \Memcached::RES_SUCCESS; } } diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php index 7bd8fa7b1ec..e878ed4d9aa 100644 --- a/lib/private/Setup/MySQL.php +++ b/lib/private/Setup/MySQL.php @@ -80,7 +80,7 @@ class MySQL extends AbstractDatabase { $user = $this->dbUser; //we can't use OC_DB functions here because we need to connect as the administrative user. $characterSet = $this->config->getValue('mysql.utf8mb4', false) ? 'utf8mb4' : 'utf8'; - $query = "CREATE DATABASE IF NOT EXISTS `$name` CHARACTER SET $characterSet COLLATE ${characterSet}_bin;"; + $query = "CREATE DATABASE IF NOT EXISTS `$name` CHARACTER SET $characterSet COLLATE {$characterSet}_bin;"; $connection->executeUpdate($query); } catch (\Exception $ex) { $this->logger->error('Database creation failed.', [ diff --git a/lib/public/Dashboard/IManager.php b/lib/public/Dashboard/IManager.php index 396624876ef..d9e73c89eb9 100644 --- a/lib/public/Dashboard/IManager.php +++ b/lib/public/Dashboard/IManager.php @@ -36,7 +36,7 @@ interface IManager { * @param string $widgetClass * @since 20.0.0 */ - public function lazyRegisterWidget(string $widgetClass): void; + public function lazyRegisterWidget(string $widgetClass, string $appId): void; /** * @since 20.0.0 |