@@ -35,59 +35,59 @@ |
||
| 35 | 35 | */ |
| 36 | 36 | interface IRegistry { |
| 37 | 37 | |
| 38 | - /** |
|
| 39 | - * Register a reporter instance |
|
| 40 | - * |
|
| 41 | - * @param IReporter $reporter |
|
| 42 | - * |
|
| 43 | - * @since 13.0.0 |
|
| 44 | - * @deprecated 20.0.0 use IRegistrationContext::registerCrashReporter |
|
| 45 | - * @see IRegistrationContext::registerCrashReporter() |
|
| 46 | - */ |
|
| 47 | - public function register(IReporter $reporter): void; |
|
| 38 | + /** |
|
| 39 | + * Register a reporter instance |
|
| 40 | + * |
|
| 41 | + * @param IReporter $reporter |
|
| 42 | + * |
|
| 43 | + * @since 13.0.0 |
|
| 44 | + * @deprecated 20.0.0 use IRegistrationContext::registerCrashReporter |
|
| 45 | + * @see IRegistrationContext::registerCrashReporter() |
|
| 46 | + */ |
|
| 47 | + public function register(IReporter $reporter): void; |
|
| 48 | 48 | |
| 49 | - /** |
|
| 50 | - * Delegate breadcrumb collection to all registered reporters |
|
| 51 | - * |
|
| 52 | - * @param string $message |
|
| 53 | - * @param string $category |
|
| 54 | - * @param array $context |
|
| 55 | - * |
|
| 56 | - * @deprecated used internally only |
|
| 57 | - * @since 15.0.0 |
|
| 58 | - */ |
|
| 59 | - public function delegateBreadcrumb(string $message, string $category, array $context = []): void; |
|
| 49 | + /** |
|
| 50 | + * Delegate breadcrumb collection to all registered reporters |
|
| 51 | + * |
|
| 52 | + * @param string $message |
|
| 53 | + * @param string $category |
|
| 54 | + * @param array $context |
|
| 55 | + * |
|
| 56 | + * @deprecated used internally only |
|
| 57 | + * @since 15.0.0 |
|
| 58 | + */ |
|
| 59 | + public function delegateBreadcrumb(string $message, string $category, array $context = []): void; |
|
| 60 | 60 | |
| 61 | - /** |
|
| 62 | - * Delegate crash reporting to all registered reporters |
|
| 63 | - * |
|
| 64 | - * @param Exception|Throwable $exception |
|
| 65 | - * @param array $context |
|
| 66 | - * |
|
| 67 | - * @deprecated used internally only |
|
| 68 | - * @since 13.0.0 |
|
| 69 | - */ |
|
| 70 | - public function delegateReport($exception, array $context = []); |
|
| 61 | + /** |
|
| 62 | + * Delegate crash reporting to all registered reporters |
|
| 63 | + * |
|
| 64 | + * @param Exception|Throwable $exception |
|
| 65 | + * @param array $context |
|
| 66 | + * |
|
| 67 | + * @deprecated used internally only |
|
| 68 | + * @since 13.0.0 |
|
| 69 | + */ |
|
| 70 | + public function delegateReport($exception, array $context = []); |
|
| 71 | 71 | |
| 72 | - /** |
|
| 73 | - * Delegate a message to all reporters that implement IMessageReporter |
|
| 74 | - * |
|
| 75 | - * @param string $message |
|
| 76 | - * @param array $context |
|
| 77 | - * |
|
| 78 | - * @return void |
|
| 79 | - * |
|
| 80 | - * @deprecated used internally only |
|
| 81 | - * @since 17.0.0 |
|
| 82 | - */ |
|
| 83 | - public function delegateMessage(string $message, array $context = []): void; |
|
| 72 | + /** |
|
| 73 | + * Delegate a message to all reporters that implement IMessageReporter |
|
| 74 | + * |
|
| 75 | + * @param string $message |
|
| 76 | + * @param array $context |
|
| 77 | + * |
|
| 78 | + * @return void |
|
| 79 | + * |
|
| 80 | + * @deprecated used internally only |
|
| 81 | + * @since 17.0.0 |
|
| 82 | + */ |
|
| 83 | + public function delegateMessage(string $message, array $context = []): void; |
|
| 84 | 84 | |
| 85 | - /** |
|
| 86 | - * Check if any reporter has been registered to delegate to |
|
| 87 | - * |
|
| 88 | - * @return bool |
|
| 89 | - * @deprecated use internally only |
|
| 90 | - * @since 26.0.0 |
|
| 91 | - */ |
|
| 92 | - public function hasReporters(): bool; |
|
| 85 | + /** |
|
| 86 | + * Check if any reporter has been registered to delegate to |
|
| 87 | + * |
|
| 88 | + * @return bool |
|
| 89 | + * @deprecated use internally only |
|
| 90 | + * @since 26.0.0 |
|
| 91 | + */ |
|
| 92 | + public function hasReporters(): bool; |
|
| 93 | 93 | } |
@@ -59,365 +59,365 @@ |
||
| 59 | 59 | * MonoLog is an example implementing this interface. |
| 60 | 60 | */ |
| 61 | 61 | class Log implements ILogger, IDataLogger { |
| 62 | - private IWriter $logger; |
|
| 63 | - private ?SystemConfig $config; |
|
| 64 | - private ?bool $logConditionSatisfied = null; |
|
| 65 | - private ?Normalizer $normalizer; |
|
| 66 | - private ?IRegistry $crashReporters; |
|
| 67 | - |
|
| 68 | - /** |
|
| 69 | - * @param IWriter $logger The logger that should be used |
|
| 70 | - * @param SystemConfig $config the system config object |
|
| 71 | - * @param Normalizer|null $normalizer |
|
| 72 | - * @param IRegistry|null $registry |
|
| 73 | - */ |
|
| 74 | - public function __construct(IWriter $logger, SystemConfig $config = null, Normalizer $normalizer = null, IRegistry $registry = null) { |
|
| 75 | - // FIXME: Add this for backwards compatibility, should be fixed at some point probably |
|
| 76 | - if ($config === null) { |
|
| 77 | - $config = \OC::$server->getSystemConfig(); |
|
| 78 | - } |
|
| 79 | - |
|
| 80 | - $this->config = $config; |
|
| 81 | - $this->logger = $logger; |
|
| 82 | - if ($normalizer === null) { |
|
| 83 | - $this->normalizer = new Normalizer(); |
|
| 84 | - } else { |
|
| 85 | - $this->normalizer = $normalizer; |
|
| 86 | - } |
|
| 87 | - $this->crashReporters = $registry; |
|
| 88 | - } |
|
| 89 | - |
|
| 90 | - /** |
|
| 91 | - * System is unusable. |
|
| 92 | - * |
|
| 93 | - * @param string $message |
|
| 94 | - * @param array $context |
|
| 95 | - * @return void |
|
| 96 | - */ |
|
| 97 | - public function emergency(string $message, array $context = []) { |
|
| 98 | - $this->log(ILogger::FATAL, $message, $context); |
|
| 99 | - } |
|
| 100 | - |
|
| 101 | - /** |
|
| 102 | - * Action must be taken immediately. |
|
| 103 | - * |
|
| 104 | - * Example: Entire website down, database unavailable, etc. This should |
|
| 105 | - * trigger the SMS alerts and wake you up. |
|
| 106 | - * |
|
| 107 | - * @param string $message |
|
| 108 | - * @param array $context |
|
| 109 | - * @return void |
|
| 110 | - */ |
|
| 111 | - public function alert(string $message, array $context = []) { |
|
| 112 | - $this->log(ILogger::ERROR, $message, $context); |
|
| 113 | - } |
|
| 114 | - |
|
| 115 | - /** |
|
| 116 | - * Critical conditions. |
|
| 117 | - * |
|
| 118 | - * Example: Application component unavailable, unexpected exception. |
|
| 119 | - * |
|
| 120 | - * @param string $message |
|
| 121 | - * @param array $context |
|
| 122 | - * @return void |
|
| 123 | - */ |
|
| 124 | - public function critical(string $message, array $context = []) { |
|
| 125 | - $this->log(ILogger::ERROR, $message, $context); |
|
| 126 | - } |
|
| 127 | - |
|
| 128 | - /** |
|
| 129 | - * Runtime errors that do not require immediate action but should typically |
|
| 130 | - * be logged and monitored. |
|
| 131 | - * |
|
| 132 | - * @param string $message |
|
| 133 | - * @param array $context |
|
| 134 | - * @return void |
|
| 135 | - */ |
|
| 136 | - public function error(string $message, array $context = []) { |
|
| 137 | - $this->log(ILogger::ERROR, $message, $context); |
|
| 138 | - } |
|
| 139 | - |
|
| 140 | - /** |
|
| 141 | - * Exceptional occurrences that are not errors. |
|
| 142 | - * |
|
| 143 | - * Example: Use of deprecated APIs, poor use of an API, undesirable things |
|
| 144 | - * that are not necessarily wrong. |
|
| 145 | - * |
|
| 146 | - * @param string $message |
|
| 147 | - * @param array $context |
|
| 148 | - * @return void |
|
| 149 | - */ |
|
| 150 | - public function warning(string $message, array $context = []) { |
|
| 151 | - $this->log(ILogger::WARN, $message, $context); |
|
| 152 | - } |
|
| 153 | - |
|
| 154 | - /** |
|
| 155 | - * Normal but significant events. |
|
| 156 | - * |
|
| 157 | - * @param string $message |
|
| 158 | - * @param array $context |
|
| 159 | - * @return void |
|
| 160 | - */ |
|
| 161 | - public function notice(string $message, array $context = []) { |
|
| 162 | - $this->log(ILogger::INFO, $message, $context); |
|
| 163 | - } |
|
| 164 | - |
|
| 165 | - /** |
|
| 166 | - * Interesting events. |
|
| 167 | - * |
|
| 168 | - * Example: User logs in, SQL logs. |
|
| 169 | - * |
|
| 170 | - * @param string $message |
|
| 171 | - * @param array $context |
|
| 172 | - * @return void |
|
| 173 | - */ |
|
| 174 | - public function info(string $message, array $context = []) { |
|
| 175 | - $this->log(ILogger::INFO, $message, $context); |
|
| 176 | - } |
|
| 177 | - |
|
| 178 | - /** |
|
| 179 | - * Detailed debug information. |
|
| 180 | - * |
|
| 181 | - * @param string $message |
|
| 182 | - * @param array $context |
|
| 183 | - * @return void |
|
| 184 | - */ |
|
| 185 | - public function debug(string $message, array $context = []) { |
|
| 186 | - $this->log(ILogger::DEBUG, $message, $context); |
|
| 187 | - } |
|
| 188 | - |
|
| 189 | - |
|
| 190 | - /** |
|
| 191 | - * Logs with an arbitrary level. |
|
| 192 | - * |
|
| 193 | - * @param int $level |
|
| 194 | - * @param string $message |
|
| 195 | - * @param array $context |
|
| 196 | - * @return void |
|
| 197 | - */ |
|
| 198 | - public function log(int $level, string $message, array $context = []) { |
|
| 199 | - $minLevel = $this->getLogLevel($context); |
|
| 200 | - |
|
| 201 | - array_walk($context, [$this->normalizer, 'format']); |
|
| 202 | - |
|
| 203 | - $app = $context['app'] ?? 'no app in context'; |
|
| 204 | - $entry = $this->interpolateMessage($context, $message); |
|
| 205 | - |
|
| 206 | - try { |
|
| 207 | - if ($level >= $minLevel) { |
|
| 208 | - $this->writeLog($app, $entry, $level); |
|
| 209 | - |
|
| 210 | - if ($this->crashReporters !== null) { |
|
| 211 | - $messageContext = array_merge( |
|
| 212 | - $context, |
|
| 213 | - [ |
|
| 214 | - 'level' => $level |
|
| 215 | - ] |
|
| 216 | - ); |
|
| 217 | - $this->crashReporters->delegateMessage($entry['message'], $messageContext); |
|
| 218 | - } |
|
| 219 | - } else { |
|
| 220 | - if ($this->crashReporters !== null) { |
|
| 221 | - $this->crashReporters->delegateBreadcrumb($entry['message'], 'log', $context); |
|
| 222 | - } |
|
| 223 | - } |
|
| 224 | - } catch (Throwable $e) { |
|
| 225 | - // make sure we dont hard crash if logging fails |
|
| 226 | - } |
|
| 227 | - } |
|
| 228 | - |
|
| 229 | - public function getLogLevel($context) { |
|
| 230 | - $logCondition = $this->config->getValue('log.condition', []); |
|
| 231 | - |
|
| 232 | - /** |
|
| 233 | - * check for a special log condition - this enables an increased log on |
|
| 234 | - * a per request/user base |
|
| 235 | - */ |
|
| 236 | - if ($this->logConditionSatisfied === null) { |
|
| 237 | - // default to false to just process this once per request |
|
| 238 | - $this->logConditionSatisfied = false; |
|
| 239 | - if (!empty($logCondition)) { |
|
| 240 | - |
|
| 241 | - // check for secret token in the request |
|
| 242 | - if (isset($logCondition['shared_secret'])) { |
|
| 243 | - $request = \OC::$server->getRequest(); |
|
| 244 | - |
|
| 245 | - if ($request->getMethod() === 'PUT' && |
|
| 246 | - strpos($request->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === false && |
|
| 247 | - strpos($request->getHeader('Content-Type'), 'application/json') === false) { |
|
| 248 | - $logSecretRequest = ''; |
|
| 249 | - } else { |
|
| 250 | - $logSecretRequest = $request->getParam('log_secret', ''); |
|
| 251 | - } |
|
| 252 | - |
|
| 253 | - // if token is found in the request change set the log condition to satisfied |
|
| 254 | - if ($request && hash_equals($logCondition['shared_secret'], $logSecretRequest)) { |
|
| 255 | - $this->logConditionSatisfied = true; |
|
| 256 | - } |
|
| 257 | - } |
|
| 258 | - |
|
| 259 | - // check for user |
|
| 260 | - if (isset($logCondition['users'])) { |
|
| 261 | - $user = \OC::$server->getUserSession()->getUser(); |
|
| 262 | - |
|
| 263 | - // if the user matches set the log condition to satisfied |
|
| 264 | - if ($user !== null && in_array($user->getUID(), $logCondition['users'], true)) { |
|
| 265 | - $this->logConditionSatisfied = true; |
|
| 266 | - } |
|
| 267 | - } |
|
| 268 | - } |
|
| 269 | - } |
|
| 270 | - |
|
| 271 | - // if log condition is satisfied change the required log level to DEBUG |
|
| 272 | - if ($this->logConditionSatisfied) { |
|
| 273 | - return ILogger::DEBUG; |
|
| 274 | - } |
|
| 275 | - |
|
| 276 | - if (isset($context['app'])) { |
|
| 277 | - $app = $context['app']; |
|
| 278 | - |
|
| 279 | - /** |
|
| 280 | - * check log condition based on the context of each log message |
|
| 281 | - * once this is met -> change the required log level to debug |
|
| 282 | - */ |
|
| 283 | - if (!empty($logCondition) |
|
| 284 | - && isset($logCondition['apps']) |
|
| 285 | - && in_array($app, $logCondition['apps'], true)) { |
|
| 286 | - return ILogger::DEBUG; |
|
| 287 | - } |
|
| 288 | - } |
|
| 289 | - |
|
| 290 | - return min($this->config->getValue('loglevel', ILogger::WARN), ILogger::FATAL); |
|
| 291 | - } |
|
| 292 | - |
|
| 293 | - /** |
|
| 294 | - * Logs an exception very detailed |
|
| 295 | - * |
|
| 296 | - * @param Exception|Throwable $exception |
|
| 297 | - * @param array $context |
|
| 298 | - * @return void |
|
| 299 | - * @since 8.2.0 |
|
| 300 | - */ |
|
| 301 | - public function logException(Throwable $exception, array $context = []) { |
|
| 302 | - $app = $context['app'] ?? 'no app in context'; |
|
| 303 | - $level = $context['level'] ?? ILogger::ERROR; |
|
| 304 | - |
|
| 305 | - $minLevel = $this->getLogLevel($context); |
|
| 306 | - if ($level < $minLevel && ($this->crashReporters === null || !$this->crashReporters->hasReporters())) { |
|
| 307 | - return; |
|
| 308 | - } |
|
| 309 | - |
|
| 310 | - // if an error is raised before the autoloader is properly setup, we can't serialize exceptions |
|
| 311 | - try { |
|
| 312 | - $serializer = $this->getSerializer(); |
|
| 313 | - } catch (Throwable $e) { |
|
| 314 | - $this->error("Failed to load ExceptionSerializer serializer while trying to log " . $exception->getMessage()); |
|
| 315 | - return; |
|
| 316 | - } |
|
| 317 | - $data = $context; |
|
| 318 | - unset($data['app']); |
|
| 319 | - unset($data['level']); |
|
| 320 | - $data = array_merge($serializer->serializeException($exception), $data); |
|
| 321 | - $data = $this->interpolateMessage($data, $context['message'] ?? '--', 'CustomMessage'); |
|
| 322 | - |
|
| 323 | - |
|
| 324 | - array_walk($context, [$this->normalizer, 'format']); |
|
| 325 | - |
|
| 326 | - try { |
|
| 327 | - if ($level >= $minLevel) { |
|
| 328 | - if (!$this->logger instanceof IFileBased) { |
|
| 329 | - $data = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_SLASHES); |
|
| 330 | - } |
|
| 331 | - $this->writeLog($app, $data, $level); |
|
| 332 | - } |
|
| 333 | - |
|
| 334 | - $context['level'] = $level; |
|
| 335 | - if (!is_null($this->crashReporters)) { |
|
| 336 | - $this->crashReporters->delegateReport($exception, $context); |
|
| 337 | - } |
|
| 338 | - } catch (Throwable $e) { |
|
| 339 | - // make sure we dont hard crash if logging fails |
|
| 340 | - } |
|
| 341 | - } |
|
| 342 | - |
|
| 343 | - public function logData(string $message, array $data, array $context = []): void { |
|
| 344 | - $app = $context['app'] ?? 'no app in context'; |
|
| 345 | - $level = $context['level'] ?? ILogger::ERROR; |
|
| 346 | - |
|
| 347 | - $minLevel = $this->getLogLevel($context); |
|
| 348 | - |
|
| 349 | - array_walk($context, [$this->normalizer, 'format']); |
|
| 350 | - |
|
| 351 | - try { |
|
| 352 | - if ($level >= $minLevel) { |
|
| 353 | - $data['message'] = $message; |
|
| 354 | - if (!$this->logger instanceof IFileBased) { |
|
| 355 | - $data = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_SLASHES); |
|
| 356 | - } |
|
| 357 | - $this->writeLog($app, $data, $level); |
|
| 358 | - } |
|
| 359 | - |
|
| 360 | - $context['level'] = $level; |
|
| 361 | - } catch (Throwable $e) { |
|
| 362 | - // make sure we dont hard crash if logging fails |
|
| 363 | - } |
|
| 364 | - } |
|
| 365 | - |
|
| 366 | - /** |
|
| 367 | - * @param string $app |
|
| 368 | - * @param string|array $entry |
|
| 369 | - * @param int $level |
|
| 370 | - */ |
|
| 371 | - protected function writeLog(string $app, $entry, int $level) { |
|
| 372 | - $this->logger->write($app, $entry, $level); |
|
| 373 | - } |
|
| 374 | - |
|
| 375 | - public function getLogPath():string { |
|
| 376 | - if ($this->logger instanceof IFileBased) { |
|
| 377 | - return $this->logger->getLogFilePath(); |
|
| 378 | - } |
|
| 379 | - throw new \RuntimeException('Log implementation has no path'); |
|
| 380 | - } |
|
| 381 | - |
|
| 382 | - /** |
|
| 383 | - * Interpolate $message as defined in PSR-3 |
|
| 384 | - * |
|
| 385 | - * Returns an array containing the context without the interpolated |
|
| 386 | - * parameters placeholders and the message as the 'message' - or |
|
| 387 | - * user-defined - key. |
|
| 388 | - */ |
|
| 389 | - private function interpolateMessage(array $context, string $message, string $messageKey = 'message'): array { |
|
| 390 | - $replace = []; |
|
| 391 | - $usedContextKeys = []; |
|
| 392 | - foreach ($context as $key => $val) { |
|
| 393 | - $fullKey = '{' . $key . '}'; |
|
| 394 | - $replace[$fullKey] = $val; |
|
| 395 | - if (strpos($message, $fullKey) !== false) { |
|
| 396 | - $usedContextKeys[$key] = true; |
|
| 397 | - } |
|
| 398 | - } |
|
| 399 | - return array_merge(array_diff_key($context, $usedContextKeys), [$messageKey => strtr($message, $replace)]); |
|
| 400 | - } |
|
| 401 | - |
|
| 402 | - /** |
|
| 403 | - * @throws Throwable |
|
| 404 | - */ |
|
| 405 | - protected function getSerializer(): ExceptionSerializer { |
|
| 406 | - $serializer = new ExceptionSerializer($this->config); |
|
| 407 | - try { |
|
| 408 | - /** @var Coordinator $coordinator */ |
|
| 409 | - $coordinator = \OCP\Server::get(Coordinator::class); |
|
| 410 | - foreach ($coordinator->getRegistrationContext()->getSensitiveMethods() as $registration) { |
|
| 411 | - $serializer->enlistSensitiveMethods($registration->getName(), $registration->getValue()); |
|
| 412 | - } |
|
| 413 | - // For not every app might be initialized at this time, we cannot assume that the return value |
|
| 414 | - // of getSensitiveMethods() is complete. Running delegates in Coordinator::registerApps() is |
|
| 415 | - // not possible due to dependencies on the one hand. On the other it would work only with |
|
| 416 | - // adding public methods to the PsrLoggerAdapter and this class. |
|
| 417 | - // Thus, serializer cannot be a property. |
|
| 418 | - } catch (Throwable $t) { |
|
| 419 | - // ignore app-defined sensitive methods in this case - they weren't loaded anyway |
|
| 420 | - } |
|
| 421 | - return $serializer; |
|
| 422 | - } |
|
| 62 | + private IWriter $logger; |
|
| 63 | + private ?SystemConfig $config; |
|
| 64 | + private ?bool $logConditionSatisfied = null; |
|
| 65 | + private ?Normalizer $normalizer; |
|
| 66 | + private ?IRegistry $crashReporters; |
|
| 67 | + |
|
| 68 | + /** |
|
| 69 | + * @param IWriter $logger The logger that should be used |
|
| 70 | + * @param SystemConfig $config the system config object |
|
| 71 | + * @param Normalizer|null $normalizer |
|
| 72 | + * @param IRegistry|null $registry |
|
| 73 | + */ |
|
| 74 | + public function __construct(IWriter $logger, SystemConfig $config = null, Normalizer $normalizer = null, IRegistry $registry = null) { |
|
| 75 | + // FIXME: Add this for backwards compatibility, should be fixed at some point probably |
|
| 76 | + if ($config === null) { |
|
| 77 | + $config = \OC::$server->getSystemConfig(); |
|
| 78 | + } |
|
| 79 | + |
|
| 80 | + $this->config = $config; |
|
| 81 | + $this->logger = $logger; |
|
| 82 | + if ($normalizer === null) { |
|
| 83 | + $this->normalizer = new Normalizer(); |
|
| 84 | + } else { |
|
| 85 | + $this->normalizer = $normalizer; |
|
| 86 | + } |
|
| 87 | + $this->crashReporters = $registry; |
|
| 88 | + } |
|
| 89 | + |
|
| 90 | + /** |
|
| 91 | + * System is unusable. |
|
| 92 | + * |
|
| 93 | + * @param string $message |
|
| 94 | + * @param array $context |
|
| 95 | + * @return void |
|
| 96 | + */ |
|
| 97 | + public function emergency(string $message, array $context = []) { |
|
| 98 | + $this->log(ILogger::FATAL, $message, $context); |
|
| 99 | + } |
|
| 100 | + |
|
| 101 | + /** |
|
| 102 | + * Action must be taken immediately. |
|
| 103 | + * |
|
| 104 | + * Example: Entire website down, database unavailable, etc. This should |
|
| 105 | + * trigger the SMS alerts and wake you up. |
|
| 106 | + * |
|
| 107 | + * @param string $message |
|
| 108 | + * @param array $context |
|
| 109 | + * @return void |
|
| 110 | + */ |
|
| 111 | + public function alert(string $message, array $context = []) { |
|
| 112 | + $this->log(ILogger::ERROR, $message, $context); |
|
| 113 | + } |
|
| 114 | + |
|
| 115 | + /** |
|
| 116 | + * Critical conditions. |
|
| 117 | + * |
|
| 118 | + * Example: Application component unavailable, unexpected exception. |
|
| 119 | + * |
|
| 120 | + * @param string $message |
|
| 121 | + * @param array $context |
|
| 122 | + * @return void |
|
| 123 | + */ |
|
| 124 | + public function critical(string $message, array $context = []) { |
|
| 125 | + $this->log(ILogger::ERROR, $message, $context); |
|
| 126 | + } |
|
| 127 | + |
|
| 128 | + /** |
|
| 129 | + * Runtime errors that do not require immediate action but should typically |
|
| 130 | + * be logged and monitored. |
|
| 131 | + * |
|
| 132 | + * @param string $message |
|
| 133 | + * @param array $context |
|
| 134 | + * @return void |
|
| 135 | + */ |
|
| 136 | + public function error(string $message, array $context = []) { |
|
| 137 | + $this->log(ILogger::ERROR, $message, $context); |
|
| 138 | + } |
|
| 139 | + |
|
| 140 | + /** |
|
| 141 | + * Exceptional occurrences that are not errors. |
|
| 142 | + * |
|
| 143 | + * Example: Use of deprecated APIs, poor use of an API, undesirable things |
|
| 144 | + * that are not necessarily wrong. |
|
| 145 | + * |
|
| 146 | + * @param string $message |
|
| 147 | + * @param array $context |
|
| 148 | + * @return void |
|
| 149 | + */ |
|
| 150 | + public function warning(string $message, array $context = []) { |
|
| 151 | + $this->log(ILogger::WARN, $message, $context); |
|
| 152 | + } |
|
| 153 | + |
|
| 154 | + /** |
|
| 155 | + * Normal but significant events. |
|
| 156 | + * |
|
| 157 | + * @param string $message |
|
| 158 | + * @param array $context |
|
| 159 | + * @return void |
|
| 160 | + */ |
|
| 161 | + public function notice(string $message, array $context = []) { |
|
| 162 | + $this->log(ILogger::INFO, $message, $context); |
|
| 163 | + } |
|
| 164 | + |
|
| 165 | + /** |
|
| 166 | + * Interesting events. |
|
| 167 | + * |
|
| 168 | + * Example: User logs in, SQL logs. |
|
| 169 | + * |
|
| 170 | + * @param string $message |
|
| 171 | + * @param array $context |
|
| 172 | + * @return void |
|
| 173 | + */ |
|
| 174 | + public function info(string $message, array $context = []) { |
|
| 175 | + $this->log(ILogger::INFO, $message, $context); |
|
| 176 | + } |
|
| 177 | + |
|
| 178 | + /** |
|
| 179 | + * Detailed debug information. |
|
| 180 | + * |
|
| 181 | + * @param string $message |
|
| 182 | + * @param array $context |
|
| 183 | + * @return void |
|
| 184 | + */ |
|
| 185 | + public function debug(string $message, array $context = []) { |
|
| 186 | + $this->log(ILogger::DEBUG, $message, $context); |
|
| 187 | + } |
|
| 188 | + |
|
| 189 | + |
|
| 190 | + /** |
|
| 191 | + * Logs with an arbitrary level. |
|
| 192 | + * |
|
| 193 | + * @param int $level |
|
| 194 | + * @param string $message |
|
| 195 | + * @param array $context |
|
| 196 | + * @return void |
|
| 197 | + */ |
|
| 198 | + public function log(int $level, string $message, array $context = []) { |
|
| 199 | + $minLevel = $this->getLogLevel($context); |
|
| 200 | + |
|
| 201 | + array_walk($context, [$this->normalizer, 'format']); |
|
| 202 | + |
|
| 203 | + $app = $context['app'] ?? 'no app in context'; |
|
| 204 | + $entry = $this->interpolateMessage($context, $message); |
|
| 205 | + |
|
| 206 | + try { |
|
| 207 | + if ($level >= $minLevel) { |
|
| 208 | + $this->writeLog($app, $entry, $level); |
|
| 209 | + |
|
| 210 | + if ($this->crashReporters !== null) { |
|
| 211 | + $messageContext = array_merge( |
|
| 212 | + $context, |
|
| 213 | + [ |
|
| 214 | + 'level' => $level |
|
| 215 | + ] |
|
| 216 | + ); |
|
| 217 | + $this->crashReporters->delegateMessage($entry['message'], $messageContext); |
|
| 218 | + } |
|
| 219 | + } else { |
|
| 220 | + if ($this->crashReporters !== null) { |
|
| 221 | + $this->crashReporters->delegateBreadcrumb($entry['message'], 'log', $context); |
|
| 222 | + } |
|
| 223 | + } |
|
| 224 | + } catch (Throwable $e) { |
|
| 225 | + // make sure we dont hard crash if logging fails |
|
| 226 | + } |
|
| 227 | + } |
|
| 228 | + |
|
| 229 | + public function getLogLevel($context) { |
|
| 230 | + $logCondition = $this->config->getValue('log.condition', []); |
|
| 231 | + |
|
| 232 | + /** |
|
| 233 | + * check for a special log condition - this enables an increased log on |
|
| 234 | + * a per request/user base |
|
| 235 | + */ |
|
| 236 | + if ($this->logConditionSatisfied === null) { |
|
| 237 | + // default to false to just process this once per request |
|
| 238 | + $this->logConditionSatisfied = false; |
|
| 239 | + if (!empty($logCondition)) { |
|
| 240 | + |
|
| 241 | + // check for secret token in the request |
|
| 242 | + if (isset($logCondition['shared_secret'])) { |
|
| 243 | + $request = \OC::$server->getRequest(); |
|
| 244 | + |
|
| 245 | + if ($request->getMethod() === 'PUT' && |
|
| 246 | + strpos($request->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === false && |
|
| 247 | + strpos($request->getHeader('Content-Type'), 'application/json') === false) { |
|
| 248 | + $logSecretRequest = ''; |
|
| 249 | + } else { |
|
| 250 | + $logSecretRequest = $request->getParam('log_secret', ''); |
|
| 251 | + } |
|
| 252 | + |
|
| 253 | + // if token is found in the request change set the log condition to satisfied |
|
| 254 | + if ($request && hash_equals($logCondition['shared_secret'], $logSecretRequest)) { |
|
| 255 | + $this->logConditionSatisfied = true; |
|
| 256 | + } |
|
| 257 | + } |
|
| 258 | + |
|
| 259 | + // check for user |
|
| 260 | + if (isset($logCondition['users'])) { |
|
| 261 | + $user = \OC::$server->getUserSession()->getUser(); |
|
| 262 | + |
|
| 263 | + // if the user matches set the log condition to satisfied |
|
| 264 | + if ($user !== null && in_array($user->getUID(), $logCondition['users'], true)) { |
|
| 265 | + $this->logConditionSatisfied = true; |
|
| 266 | + } |
|
| 267 | + } |
|
| 268 | + } |
|
| 269 | + } |
|
| 270 | + |
|
| 271 | + // if log condition is satisfied change the required log level to DEBUG |
|
| 272 | + if ($this->logConditionSatisfied) { |
|
| 273 | + return ILogger::DEBUG; |
|
| 274 | + } |
|
| 275 | + |
|
| 276 | + if (isset($context['app'])) { |
|
| 277 | + $app = $context['app']; |
|
| 278 | + |
|
| 279 | + /** |
|
| 280 | + * check log condition based on the context of each log message |
|
| 281 | + * once this is met -> change the required log level to debug |
|
| 282 | + */ |
|
| 283 | + if (!empty($logCondition) |
|
| 284 | + && isset($logCondition['apps']) |
|
| 285 | + && in_array($app, $logCondition['apps'], true)) { |
|
| 286 | + return ILogger::DEBUG; |
|
| 287 | + } |
|
| 288 | + } |
|
| 289 | + |
|
| 290 | + return min($this->config->getValue('loglevel', ILogger::WARN), ILogger::FATAL); |
|
| 291 | + } |
|
| 292 | + |
|
| 293 | + /** |
|
| 294 | + * Logs an exception very detailed |
|
| 295 | + * |
|
| 296 | + * @param Exception|Throwable $exception |
|
| 297 | + * @param array $context |
|
| 298 | + * @return void |
|
| 299 | + * @since 8.2.0 |
|
| 300 | + */ |
|
| 301 | + public function logException(Throwable $exception, array $context = []) { |
|
| 302 | + $app = $context['app'] ?? 'no app in context'; |
|
| 303 | + $level = $context['level'] ?? ILogger::ERROR; |
|
| 304 | + |
|
| 305 | + $minLevel = $this->getLogLevel($context); |
|
| 306 | + if ($level < $minLevel && ($this->crashReporters === null || !$this->crashReporters->hasReporters())) { |
|
| 307 | + return; |
|
| 308 | + } |
|
| 309 | + |
|
| 310 | + // if an error is raised before the autoloader is properly setup, we can't serialize exceptions |
|
| 311 | + try { |
|
| 312 | + $serializer = $this->getSerializer(); |
|
| 313 | + } catch (Throwable $e) { |
|
| 314 | + $this->error("Failed to load ExceptionSerializer serializer while trying to log " . $exception->getMessage()); |
|
| 315 | + return; |
|
| 316 | + } |
|
| 317 | + $data = $context; |
|
| 318 | + unset($data['app']); |
|
| 319 | + unset($data['level']); |
|
| 320 | + $data = array_merge($serializer->serializeException($exception), $data); |
|
| 321 | + $data = $this->interpolateMessage($data, $context['message'] ?? '--', 'CustomMessage'); |
|
| 322 | + |
|
| 323 | + |
|
| 324 | + array_walk($context, [$this->normalizer, 'format']); |
|
| 325 | + |
|
| 326 | + try { |
|
| 327 | + if ($level >= $minLevel) { |
|
| 328 | + if (!$this->logger instanceof IFileBased) { |
|
| 329 | + $data = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_SLASHES); |
|
| 330 | + } |
|
| 331 | + $this->writeLog($app, $data, $level); |
|
| 332 | + } |
|
| 333 | + |
|
| 334 | + $context['level'] = $level; |
|
| 335 | + if (!is_null($this->crashReporters)) { |
|
| 336 | + $this->crashReporters->delegateReport($exception, $context); |
|
| 337 | + } |
|
| 338 | + } catch (Throwable $e) { |
|
| 339 | + // make sure we dont hard crash if logging fails |
|
| 340 | + } |
|
| 341 | + } |
|
| 342 | + |
|
| 343 | + public function logData(string $message, array $data, array $context = []): void { |
|
| 344 | + $app = $context['app'] ?? 'no app in context'; |
|
| 345 | + $level = $context['level'] ?? ILogger::ERROR; |
|
| 346 | + |
|
| 347 | + $minLevel = $this->getLogLevel($context); |
|
| 348 | + |
|
| 349 | + array_walk($context, [$this->normalizer, 'format']); |
|
| 350 | + |
|
| 351 | + try { |
|
| 352 | + if ($level >= $minLevel) { |
|
| 353 | + $data['message'] = $message; |
|
| 354 | + if (!$this->logger instanceof IFileBased) { |
|
| 355 | + $data = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_SLASHES); |
|
| 356 | + } |
|
| 357 | + $this->writeLog($app, $data, $level); |
|
| 358 | + } |
|
| 359 | + |
|
| 360 | + $context['level'] = $level; |
|
| 361 | + } catch (Throwable $e) { |
|
| 362 | + // make sure we dont hard crash if logging fails |
|
| 363 | + } |
|
| 364 | + } |
|
| 365 | + |
|
| 366 | + /** |
|
| 367 | + * @param string $app |
|
| 368 | + * @param string|array $entry |
|
| 369 | + * @param int $level |
|
| 370 | + */ |
|
| 371 | + protected function writeLog(string $app, $entry, int $level) { |
|
| 372 | + $this->logger->write($app, $entry, $level); |
|
| 373 | + } |
|
| 374 | + |
|
| 375 | + public function getLogPath():string { |
|
| 376 | + if ($this->logger instanceof IFileBased) { |
|
| 377 | + return $this->logger->getLogFilePath(); |
|
| 378 | + } |
|
| 379 | + throw new \RuntimeException('Log implementation has no path'); |
|
| 380 | + } |
|
| 381 | + |
|
| 382 | + /** |
|
| 383 | + * Interpolate $message as defined in PSR-3 |
|
| 384 | + * |
|
| 385 | + * Returns an array containing the context without the interpolated |
|
| 386 | + * parameters placeholders and the message as the 'message' - or |
|
| 387 | + * user-defined - key. |
|
| 388 | + */ |
|
| 389 | + private function interpolateMessage(array $context, string $message, string $messageKey = 'message'): array { |
|
| 390 | + $replace = []; |
|
| 391 | + $usedContextKeys = []; |
|
| 392 | + foreach ($context as $key => $val) { |
|
| 393 | + $fullKey = '{' . $key . '}'; |
|
| 394 | + $replace[$fullKey] = $val; |
|
| 395 | + if (strpos($message, $fullKey) !== false) { |
|
| 396 | + $usedContextKeys[$key] = true; |
|
| 397 | + } |
|
| 398 | + } |
|
| 399 | + return array_merge(array_diff_key($context, $usedContextKeys), [$messageKey => strtr($message, $replace)]); |
|
| 400 | + } |
|
| 401 | + |
|
| 402 | + /** |
|
| 403 | + * @throws Throwable |
|
| 404 | + */ |
|
| 405 | + protected function getSerializer(): ExceptionSerializer { |
|
| 406 | + $serializer = new ExceptionSerializer($this->config); |
|
| 407 | + try { |
|
| 408 | + /** @var Coordinator $coordinator */ |
|
| 409 | + $coordinator = \OCP\Server::get(Coordinator::class); |
|
| 410 | + foreach ($coordinator->getRegistrationContext()->getSensitiveMethods() as $registration) { |
|
| 411 | + $serializer->enlistSensitiveMethods($registration->getName(), $registration->getValue()); |
|
| 412 | + } |
|
| 413 | + // For not every app might be initialized at this time, we cannot assume that the return value |
|
| 414 | + // of getSensitiveMethods() is complete. Running delegates in Coordinator::registerApps() is |
|
| 415 | + // not possible due to dependencies on the one hand. On the other it would work only with |
|
| 416 | + // adding public methods to the PsrLoggerAdapter and this class. |
|
| 417 | + // Thus, serializer cannot be a property. |
|
| 418 | + } catch (Throwable $t) { |
|
| 419 | + // ignore app-defined sensitive methods in this case - they weren't loaded anyway |
|
| 420 | + } |
|
| 421 | + return $serializer; |
|
| 422 | + } |
|
| 423 | 423 | } |
@@ -42,258 +42,258 @@ |
||
| 42 | 42 | use OCP\HintException; |
| 43 | 43 | |
| 44 | 44 | class ExceptionSerializer { |
| 45 | - public const SENSITIVE_VALUE_PLACEHOLDER = '*** sensitive parameters replaced ***'; |
|
| 45 | + public const SENSITIVE_VALUE_PLACEHOLDER = '*** sensitive parameters replaced ***'; |
|
| 46 | 46 | |
| 47 | - public const methodsWithSensitiveParameters = [ |
|
| 48 | - // Session/User |
|
| 49 | - 'completeLogin', |
|
| 50 | - 'login', |
|
| 51 | - 'checkPassword', |
|
| 52 | - 'checkPasswordNoLogging', |
|
| 53 | - 'loginWithPassword', |
|
| 54 | - 'updatePrivateKeyPassword', |
|
| 55 | - 'validateUserPass', |
|
| 56 | - 'loginWithToken', |
|
| 57 | - '{closure}', |
|
| 58 | - 'createSessionToken', |
|
| 47 | + public const methodsWithSensitiveParameters = [ |
|
| 48 | + // Session/User |
|
| 49 | + 'completeLogin', |
|
| 50 | + 'login', |
|
| 51 | + 'checkPassword', |
|
| 52 | + 'checkPasswordNoLogging', |
|
| 53 | + 'loginWithPassword', |
|
| 54 | + 'updatePrivateKeyPassword', |
|
| 55 | + 'validateUserPass', |
|
| 56 | + 'loginWithToken', |
|
| 57 | + '{closure}', |
|
| 58 | + 'createSessionToken', |
|
| 59 | 59 | |
| 60 | - // Provisioning |
|
| 61 | - 'addUser', |
|
| 60 | + // Provisioning |
|
| 61 | + 'addUser', |
|
| 62 | 62 | |
| 63 | - // TokenProvider |
|
| 64 | - 'getToken', |
|
| 65 | - 'isTokenPassword', |
|
| 66 | - 'getPassword', |
|
| 67 | - 'decryptPassword', |
|
| 68 | - 'logClientIn', |
|
| 69 | - 'generateToken', |
|
| 70 | - 'validateToken', |
|
| 63 | + // TokenProvider |
|
| 64 | + 'getToken', |
|
| 65 | + 'isTokenPassword', |
|
| 66 | + 'getPassword', |
|
| 67 | + 'decryptPassword', |
|
| 68 | + 'logClientIn', |
|
| 69 | + 'generateToken', |
|
| 70 | + 'validateToken', |
|
| 71 | 71 | |
| 72 | - // TwoFactorAuth |
|
| 73 | - 'solveChallenge', |
|
| 74 | - 'verifyChallenge', |
|
| 72 | + // TwoFactorAuth |
|
| 73 | + 'solveChallenge', |
|
| 74 | + 'verifyChallenge', |
|
| 75 | 75 | |
| 76 | - // ICrypto |
|
| 77 | - 'calculateHMAC', |
|
| 78 | - 'encrypt', |
|
| 79 | - 'decrypt', |
|
| 76 | + // ICrypto |
|
| 77 | + 'calculateHMAC', |
|
| 78 | + 'encrypt', |
|
| 79 | + 'decrypt', |
|
| 80 | 80 | |
| 81 | - // LoginController |
|
| 82 | - 'tryLogin', |
|
| 83 | - 'confirmPassword', |
|
| 81 | + // LoginController |
|
| 82 | + 'tryLogin', |
|
| 83 | + 'confirmPassword', |
|
| 84 | 84 | |
| 85 | - // LDAP |
|
| 86 | - 'bind', |
|
| 87 | - 'areCredentialsValid', |
|
| 88 | - 'invokeLDAPMethod', |
|
| 85 | + // LDAP |
|
| 86 | + 'bind', |
|
| 87 | + 'areCredentialsValid', |
|
| 88 | + 'invokeLDAPMethod', |
|
| 89 | 89 | |
| 90 | - // Encryption |
|
| 91 | - 'storeKeyPair', |
|
| 92 | - 'setupUser', |
|
| 93 | - 'checkSignature', |
|
| 90 | + // Encryption |
|
| 91 | + 'storeKeyPair', |
|
| 92 | + 'setupUser', |
|
| 93 | + 'checkSignature', |
|
| 94 | 94 | |
| 95 | - // files_external: OCA\Files_External\MountConfig |
|
| 96 | - 'getBackendStatus', |
|
| 95 | + // files_external: OCA\Files_External\MountConfig |
|
| 96 | + 'getBackendStatus', |
|
| 97 | 97 | |
| 98 | - // files_external: UserStoragesController |
|
| 99 | - 'update', |
|
| 98 | + // files_external: UserStoragesController |
|
| 99 | + 'update', |
|
| 100 | 100 | |
| 101 | - // Preview providers, don't log big data strings |
|
| 102 | - 'imagecreatefromstring', |
|
| 103 | - ]; |
|
| 101 | + // Preview providers, don't log big data strings |
|
| 102 | + 'imagecreatefromstring', |
|
| 103 | + ]; |
|
| 104 | 104 | |
| 105 | - /** @var SystemConfig */ |
|
| 106 | - private $systemConfig; |
|
| 105 | + /** @var SystemConfig */ |
|
| 106 | + private $systemConfig; |
|
| 107 | 107 | |
| 108 | - public function __construct(SystemConfig $systemConfig) { |
|
| 109 | - $this->systemConfig = $systemConfig; |
|
| 110 | - } |
|
| 108 | + public function __construct(SystemConfig $systemConfig) { |
|
| 109 | + $this->systemConfig = $systemConfig; |
|
| 110 | + } |
|
| 111 | 111 | |
| 112 | - protected array $methodsWithSensitiveParametersByClass = [ |
|
| 113 | - SetupController::class => [ |
|
| 114 | - 'run', |
|
| 115 | - 'display', |
|
| 116 | - 'loadAutoConfig', |
|
| 117 | - ], |
|
| 118 | - Setup::class => [ |
|
| 119 | - 'install' |
|
| 120 | - ], |
|
| 121 | - Key::class => [ |
|
| 122 | - '__construct' |
|
| 123 | - ], |
|
| 124 | - \Redis::class => [ |
|
| 125 | - 'auth' |
|
| 126 | - ], |
|
| 127 | - \RedisCluster::class => [ |
|
| 128 | - '__construct' |
|
| 129 | - ], |
|
| 130 | - Crypt::class => [ |
|
| 131 | - 'symmetricEncryptFileContent', |
|
| 132 | - 'encrypt', |
|
| 133 | - 'generatePasswordHash', |
|
| 134 | - 'encryptPrivateKey', |
|
| 135 | - 'decryptPrivateKey', |
|
| 136 | - 'isValidPrivateKey', |
|
| 137 | - 'symmetricDecryptFileContent', |
|
| 138 | - 'checkSignature', |
|
| 139 | - 'createSignature', |
|
| 140 | - 'decrypt', |
|
| 141 | - 'multiKeyDecrypt', |
|
| 142 | - 'multiKeyEncrypt', |
|
| 143 | - ], |
|
| 144 | - RecoveryController::class => [ |
|
| 145 | - 'adminRecovery', |
|
| 146 | - 'changeRecoveryPassword' |
|
| 147 | - ], |
|
| 148 | - SettingsController::class => [ |
|
| 149 | - 'updatePrivateKeyPassword', |
|
| 150 | - ], |
|
| 151 | - Encryption::class => [ |
|
| 152 | - 'encrypt', |
|
| 153 | - 'decrypt', |
|
| 154 | - ], |
|
| 155 | - KeyManager::class => [ |
|
| 156 | - 'checkRecoveryPassword', |
|
| 157 | - 'storeKeyPair', |
|
| 158 | - 'setRecoveryKey', |
|
| 159 | - 'setPrivateKey', |
|
| 160 | - 'setFileKey', |
|
| 161 | - 'setAllFileKeys', |
|
| 162 | - ], |
|
| 163 | - Session::class => [ |
|
| 164 | - 'setPrivateKey', |
|
| 165 | - 'prepareDecryptAll', |
|
| 166 | - ], |
|
| 167 | - \OCA\Encryption\Users\Setup::class => [ |
|
| 168 | - 'setupUser', |
|
| 169 | - ], |
|
| 170 | - UserHooks::class => [ |
|
| 171 | - 'login', |
|
| 172 | - 'postCreateUser', |
|
| 173 | - 'postDeleteUser', |
|
| 174 | - 'prePasswordReset', |
|
| 175 | - 'postPasswordReset', |
|
| 176 | - 'preSetPassphrase', |
|
| 177 | - 'setPassphrase', |
|
| 178 | - ], |
|
| 179 | - ]; |
|
| 112 | + protected array $methodsWithSensitiveParametersByClass = [ |
|
| 113 | + SetupController::class => [ |
|
| 114 | + 'run', |
|
| 115 | + 'display', |
|
| 116 | + 'loadAutoConfig', |
|
| 117 | + ], |
|
| 118 | + Setup::class => [ |
|
| 119 | + 'install' |
|
| 120 | + ], |
|
| 121 | + Key::class => [ |
|
| 122 | + '__construct' |
|
| 123 | + ], |
|
| 124 | + \Redis::class => [ |
|
| 125 | + 'auth' |
|
| 126 | + ], |
|
| 127 | + \RedisCluster::class => [ |
|
| 128 | + '__construct' |
|
| 129 | + ], |
|
| 130 | + Crypt::class => [ |
|
| 131 | + 'symmetricEncryptFileContent', |
|
| 132 | + 'encrypt', |
|
| 133 | + 'generatePasswordHash', |
|
| 134 | + 'encryptPrivateKey', |
|
| 135 | + 'decryptPrivateKey', |
|
| 136 | + 'isValidPrivateKey', |
|
| 137 | + 'symmetricDecryptFileContent', |
|
| 138 | + 'checkSignature', |
|
| 139 | + 'createSignature', |
|
| 140 | + 'decrypt', |
|
| 141 | + 'multiKeyDecrypt', |
|
| 142 | + 'multiKeyEncrypt', |
|
| 143 | + ], |
|
| 144 | + RecoveryController::class => [ |
|
| 145 | + 'adminRecovery', |
|
| 146 | + 'changeRecoveryPassword' |
|
| 147 | + ], |
|
| 148 | + SettingsController::class => [ |
|
| 149 | + 'updatePrivateKeyPassword', |
|
| 150 | + ], |
|
| 151 | + Encryption::class => [ |
|
| 152 | + 'encrypt', |
|
| 153 | + 'decrypt', |
|
| 154 | + ], |
|
| 155 | + KeyManager::class => [ |
|
| 156 | + 'checkRecoveryPassword', |
|
| 157 | + 'storeKeyPair', |
|
| 158 | + 'setRecoveryKey', |
|
| 159 | + 'setPrivateKey', |
|
| 160 | + 'setFileKey', |
|
| 161 | + 'setAllFileKeys', |
|
| 162 | + ], |
|
| 163 | + Session::class => [ |
|
| 164 | + 'setPrivateKey', |
|
| 165 | + 'prepareDecryptAll', |
|
| 166 | + ], |
|
| 167 | + \OCA\Encryption\Users\Setup::class => [ |
|
| 168 | + 'setupUser', |
|
| 169 | + ], |
|
| 170 | + UserHooks::class => [ |
|
| 171 | + 'login', |
|
| 172 | + 'postCreateUser', |
|
| 173 | + 'postDeleteUser', |
|
| 174 | + 'prePasswordReset', |
|
| 175 | + 'postPasswordReset', |
|
| 176 | + 'preSetPassphrase', |
|
| 177 | + 'setPassphrase', |
|
| 178 | + ], |
|
| 179 | + ]; |
|
| 180 | 180 | |
| 181 | - private function editTrace(array &$sensitiveValues, array $traceLine): array { |
|
| 182 | - if (isset($traceLine['args'])) { |
|
| 183 | - $sensitiveValues = array_merge($sensitiveValues, $traceLine['args']); |
|
| 184 | - } |
|
| 185 | - $traceLine['args'] = [self::SENSITIVE_VALUE_PLACEHOLDER]; |
|
| 186 | - return $traceLine; |
|
| 187 | - } |
|
| 181 | + private function editTrace(array &$sensitiveValues, array $traceLine): array { |
|
| 182 | + if (isset($traceLine['args'])) { |
|
| 183 | + $sensitiveValues = array_merge($sensitiveValues, $traceLine['args']); |
|
| 184 | + } |
|
| 185 | + $traceLine['args'] = [self::SENSITIVE_VALUE_PLACEHOLDER]; |
|
| 186 | + return $traceLine; |
|
| 187 | + } |
|
| 188 | 188 | |
| 189 | - private function filterTrace(array $trace) { |
|
| 190 | - $sensitiveValues = []; |
|
| 191 | - $trace = array_map(function (array $traceLine) use (&$sensitiveValues) { |
|
| 192 | - $className = $traceLine['class'] ?? ''; |
|
| 193 | - if ($className && isset($this->methodsWithSensitiveParametersByClass[$className]) |
|
| 194 | - && in_array($traceLine['function'], $this->methodsWithSensitiveParametersByClass[$className], true)) { |
|
| 195 | - return $this->editTrace($sensitiveValues, $traceLine); |
|
| 196 | - } |
|
| 197 | - foreach (self::methodsWithSensitiveParameters as $sensitiveMethod) { |
|
| 198 | - if (strpos($traceLine['function'], $sensitiveMethod) !== false) { |
|
| 199 | - return $this->editTrace($sensitiveValues, $traceLine); |
|
| 200 | - } |
|
| 201 | - } |
|
| 202 | - return $traceLine; |
|
| 203 | - }, $trace); |
|
| 204 | - return array_map(function (array $traceLine) use ($sensitiveValues) { |
|
| 205 | - if (isset($traceLine['args'])) { |
|
| 206 | - $traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues); |
|
| 207 | - } |
|
| 208 | - return $traceLine; |
|
| 209 | - }, $trace); |
|
| 210 | - } |
|
| 189 | + private function filterTrace(array $trace) { |
|
| 190 | + $sensitiveValues = []; |
|
| 191 | + $trace = array_map(function (array $traceLine) use (&$sensitiveValues) { |
|
| 192 | + $className = $traceLine['class'] ?? ''; |
|
| 193 | + if ($className && isset($this->methodsWithSensitiveParametersByClass[$className]) |
|
| 194 | + && in_array($traceLine['function'], $this->methodsWithSensitiveParametersByClass[$className], true)) { |
|
| 195 | + return $this->editTrace($sensitiveValues, $traceLine); |
|
| 196 | + } |
|
| 197 | + foreach (self::methodsWithSensitiveParameters as $sensitiveMethod) { |
|
| 198 | + if (strpos($traceLine['function'], $sensitiveMethod) !== false) { |
|
| 199 | + return $this->editTrace($sensitiveValues, $traceLine); |
|
| 200 | + } |
|
| 201 | + } |
|
| 202 | + return $traceLine; |
|
| 203 | + }, $trace); |
|
| 204 | + return array_map(function (array $traceLine) use ($sensitiveValues) { |
|
| 205 | + if (isset($traceLine['args'])) { |
|
| 206 | + $traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues); |
|
| 207 | + } |
|
| 208 | + return $traceLine; |
|
| 209 | + }, $trace); |
|
| 210 | + } |
|
| 211 | 211 | |
| 212 | - private function removeValuesFromArgs($args, $values) { |
|
| 213 | - $workArgs = []; |
|
| 214 | - foreach ($args as $arg) { |
|
| 215 | - if (in_array($arg, $values, true)) { |
|
| 216 | - $arg = self::SENSITIVE_VALUE_PLACEHOLDER; |
|
| 217 | - } elseif (is_array($arg)) { |
|
| 218 | - $arg = $this->removeValuesFromArgs($arg, $values); |
|
| 219 | - } |
|
| 220 | - $workArgs[] = $arg; |
|
| 221 | - } |
|
| 222 | - return $workArgs; |
|
| 223 | - } |
|
| 212 | + private function removeValuesFromArgs($args, $values) { |
|
| 213 | + $workArgs = []; |
|
| 214 | + foreach ($args as $arg) { |
|
| 215 | + if (in_array($arg, $values, true)) { |
|
| 216 | + $arg = self::SENSITIVE_VALUE_PLACEHOLDER; |
|
| 217 | + } elseif (is_array($arg)) { |
|
| 218 | + $arg = $this->removeValuesFromArgs($arg, $values); |
|
| 219 | + } |
|
| 220 | + $workArgs[] = $arg; |
|
| 221 | + } |
|
| 222 | + return $workArgs; |
|
| 223 | + } |
|
| 224 | 224 | |
| 225 | - private function encodeTrace($trace) { |
|
| 226 | - $trace = array_map(function (array $line) { |
|
| 227 | - if (isset($line['args'])) { |
|
| 228 | - $line['args'] = array_map([$this, 'encodeArg'], $line['args']); |
|
| 229 | - } |
|
| 230 | - return $line; |
|
| 231 | - }, $trace); |
|
| 232 | - return $this->filterTrace($trace); |
|
| 233 | - } |
|
| 225 | + private function encodeTrace($trace) { |
|
| 226 | + $trace = array_map(function (array $line) { |
|
| 227 | + if (isset($line['args'])) { |
|
| 228 | + $line['args'] = array_map([$this, 'encodeArg'], $line['args']); |
|
| 229 | + } |
|
| 230 | + return $line; |
|
| 231 | + }, $trace); |
|
| 232 | + return $this->filterTrace($trace); |
|
| 233 | + } |
|
| 234 | 234 | |
| 235 | - private function encodeArg($arg, $nestingLevel = 5) { |
|
| 236 | - if (is_object($arg)) { |
|
| 237 | - if ($nestingLevel === 0) { |
|
| 238 | - return [ |
|
| 239 | - '__class__' => get_class($arg), |
|
| 240 | - '__properties__' => 'Encoding skipped as the maximum nesting level was reached', |
|
| 241 | - ]; |
|
| 242 | - } |
|
| 235 | + private function encodeArg($arg, $nestingLevel = 5) { |
|
| 236 | + if (is_object($arg)) { |
|
| 237 | + if ($nestingLevel === 0) { |
|
| 238 | + return [ |
|
| 239 | + '__class__' => get_class($arg), |
|
| 240 | + '__properties__' => 'Encoding skipped as the maximum nesting level was reached', |
|
| 241 | + ]; |
|
| 242 | + } |
|
| 243 | 243 | |
| 244 | - $objectInfo = [ '__class__' => get_class($arg) ]; |
|
| 245 | - $objectVars = get_object_vars($arg); |
|
| 246 | - return array_map(function ($arg) use ($nestingLevel) { |
|
| 247 | - return $this->encodeArg($arg, $nestingLevel - 1); |
|
| 248 | - }, array_merge($objectInfo, $objectVars)); |
|
| 249 | - } |
|
| 244 | + $objectInfo = [ '__class__' => get_class($arg) ]; |
|
| 245 | + $objectVars = get_object_vars($arg); |
|
| 246 | + return array_map(function ($arg) use ($nestingLevel) { |
|
| 247 | + return $this->encodeArg($arg, $nestingLevel - 1); |
|
| 248 | + }, array_merge($objectInfo, $objectVars)); |
|
| 249 | + } |
|
| 250 | 250 | |
| 251 | - if (is_array($arg)) { |
|
| 252 | - if ($nestingLevel === 0) { |
|
| 253 | - return ['Encoding skipped as the maximum nesting level was reached']; |
|
| 254 | - } |
|
| 251 | + if (is_array($arg)) { |
|
| 252 | + if ($nestingLevel === 0) { |
|
| 253 | + return ['Encoding skipped as the maximum nesting level was reached']; |
|
| 254 | + } |
|
| 255 | 255 | |
| 256 | - // Only log the first 5 elements of an array unless we are on debug |
|
| 257 | - if ((int)$this->systemConfig->getValue('loglevel', 2) !== 0) { |
|
| 258 | - $elemCount = count($arg); |
|
| 259 | - if ($elemCount > 5) { |
|
| 260 | - $arg = array_slice($arg, 0, 5); |
|
| 261 | - $arg[] = 'And ' . ($elemCount - 5) . ' more entries, set log level to debug to see all entries'; |
|
| 262 | - } |
|
| 263 | - } |
|
| 264 | - return array_map(function ($e) use ($nestingLevel) { |
|
| 265 | - return $this->encodeArg($e, $nestingLevel - 1); |
|
| 266 | - }, $arg); |
|
| 267 | - } |
|
| 256 | + // Only log the first 5 elements of an array unless we are on debug |
|
| 257 | + if ((int)$this->systemConfig->getValue('loglevel', 2) !== 0) { |
|
| 258 | + $elemCount = count($arg); |
|
| 259 | + if ($elemCount > 5) { |
|
| 260 | + $arg = array_slice($arg, 0, 5); |
|
| 261 | + $arg[] = 'And ' . ($elemCount - 5) . ' more entries, set log level to debug to see all entries'; |
|
| 262 | + } |
|
| 263 | + } |
|
| 264 | + return array_map(function ($e) use ($nestingLevel) { |
|
| 265 | + return $this->encodeArg($e, $nestingLevel - 1); |
|
| 266 | + }, $arg); |
|
| 267 | + } |
|
| 268 | 268 | |
| 269 | - return $arg; |
|
| 270 | - } |
|
| 269 | + return $arg; |
|
| 270 | + } |
|
| 271 | 271 | |
| 272 | - public function serializeException(\Throwable $exception) { |
|
| 273 | - $data = [ |
|
| 274 | - 'Exception' => get_class($exception), |
|
| 275 | - 'Message' => $exception->getMessage(), |
|
| 276 | - 'Code' => $exception->getCode(), |
|
| 277 | - 'Trace' => $this->encodeTrace($exception->getTrace()), |
|
| 278 | - 'File' => $exception->getFile(), |
|
| 279 | - 'Line' => $exception->getLine(), |
|
| 280 | - ]; |
|
| 272 | + public function serializeException(\Throwable $exception) { |
|
| 273 | + $data = [ |
|
| 274 | + 'Exception' => get_class($exception), |
|
| 275 | + 'Message' => $exception->getMessage(), |
|
| 276 | + 'Code' => $exception->getCode(), |
|
| 277 | + 'Trace' => $this->encodeTrace($exception->getTrace()), |
|
| 278 | + 'File' => $exception->getFile(), |
|
| 279 | + 'Line' => $exception->getLine(), |
|
| 280 | + ]; |
|
| 281 | 281 | |
| 282 | - if ($exception instanceof HintException) { |
|
| 283 | - $data['Hint'] = $exception->getHint(); |
|
| 284 | - } |
|
| 282 | + if ($exception instanceof HintException) { |
|
| 283 | + $data['Hint'] = $exception->getHint(); |
|
| 284 | + } |
|
| 285 | 285 | |
| 286 | - if ($exception->getPrevious()) { |
|
| 287 | - $data['Previous'] = $this->serializeException($exception->getPrevious()); |
|
| 288 | - } |
|
| 286 | + if ($exception->getPrevious()) { |
|
| 287 | + $data['Previous'] = $this->serializeException($exception->getPrevious()); |
|
| 288 | + } |
|
| 289 | 289 | |
| 290 | - return $data; |
|
| 291 | - } |
|
| 290 | + return $data; |
|
| 291 | + } |
|
| 292 | 292 | |
| 293 | - public function enlistSensitiveMethods(string $class, array $methods): void { |
|
| 294 | - if (!isset($this->methodsWithSensitiveParametersByClass[$class])) { |
|
| 295 | - $this->methodsWithSensitiveParametersByClass[$class] = []; |
|
| 296 | - } |
|
| 297 | - $this->methodsWithSensitiveParametersByClass[$class] = array_merge($this->methodsWithSensitiveParametersByClass[$class], $methods); |
|
| 298 | - } |
|
| 293 | + public function enlistSensitiveMethods(string $class, array $methods): void { |
|
| 294 | + if (!isset($this->methodsWithSensitiveParametersByClass[$class])) { |
|
| 295 | + $this->methodsWithSensitiveParametersByClass[$class] = []; |
|
| 296 | + } |
|
| 297 | + $this->methodsWithSensitiveParametersByClass[$class] = array_merge($this->methodsWithSensitiveParametersByClass[$class], $methods); |
|
| 298 | + } |
|
| 299 | 299 | } |
@@ -188,7 +188,7 @@ discard block |
||
| 188 | 188 | |
| 189 | 189 | private function filterTrace(array $trace) { |
| 190 | 190 | $sensitiveValues = []; |
| 191 | - $trace = array_map(function (array $traceLine) use (&$sensitiveValues) { |
|
| 191 | + $trace = array_map(function(array $traceLine) use (&$sensitiveValues) { |
|
| 192 | 192 | $className = $traceLine['class'] ?? ''; |
| 193 | 193 | if ($className && isset($this->methodsWithSensitiveParametersByClass[$className]) |
| 194 | 194 | && in_array($traceLine['function'], $this->methodsWithSensitiveParametersByClass[$className], true)) { |
@@ -201,7 +201,7 @@ discard block |
||
| 201 | 201 | } |
| 202 | 202 | return $traceLine; |
| 203 | 203 | }, $trace); |
| 204 | - return array_map(function (array $traceLine) use ($sensitiveValues) { |
|
| 204 | + return array_map(function(array $traceLine) use ($sensitiveValues) { |
|
| 205 | 205 | if (isset($traceLine['args'])) { |
| 206 | 206 | $traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues); |
| 207 | 207 | } |
@@ -223,7 +223,7 @@ discard block |
||
| 223 | 223 | } |
| 224 | 224 | |
| 225 | 225 | private function encodeTrace($trace) { |
| 226 | - $trace = array_map(function (array $line) { |
|
| 226 | + $trace = array_map(function(array $line) { |
|
| 227 | 227 | if (isset($line['args'])) { |
| 228 | 228 | $line['args'] = array_map([$this, 'encodeArg'], $line['args']); |
| 229 | 229 | } |
@@ -241,9 +241,9 @@ discard block |
||
| 241 | 241 | ]; |
| 242 | 242 | } |
| 243 | 243 | |
| 244 | - $objectInfo = [ '__class__' => get_class($arg) ]; |
|
| 244 | + $objectInfo = ['__class__' => get_class($arg)]; |
|
| 245 | 245 | $objectVars = get_object_vars($arg); |
| 246 | - return array_map(function ($arg) use ($nestingLevel) { |
|
| 246 | + return array_map(function($arg) use ($nestingLevel) { |
|
| 247 | 247 | return $this->encodeArg($arg, $nestingLevel - 1); |
| 248 | 248 | }, array_merge($objectInfo, $objectVars)); |
| 249 | 249 | } |
@@ -254,14 +254,14 @@ discard block |
||
| 254 | 254 | } |
| 255 | 255 | |
| 256 | 256 | // Only log the first 5 elements of an array unless we are on debug |
| 257 | - if ((int)$this->systemConfig->getValue('loglevel', 2) !== 0) { |
|
| 257 | + if ((int) $this->systemConfig->getValue('loglevel', 2) !== 0) { |
|
| 258 | 258 | $elemCount = count($arg); |
| 259 | 259 | if ($elemCount > 5) { |
| 260 | 260 | $arg = array_slice($arg, 0, 5); |
| 261 | - $arg[] = 'And ' . ($elemCount - 5) . ' more entries, set log level to debug to see all entries'; |
|
| 261 | + $arg[] = 'And '.($elemCount - 5).' more entries, set log level to debug to see all entries'; |
|
| 262 | 262 | } |
| 263 | 263 | } |
| 264 | - return array_map(function ($e) use ($nestingLevel) { |
|
| 264 | + return array_map(function($e) use ($nestingLevel) { |
|
| 265 | 265 | return $this->encodeArg($e, $nestingLevel - 1); |
| 266 | 266 | }, $arg); |
| 267 | 267 | } |
@@ -39,116 +39,116 @@ |
||
| 39 | 39 | |
| 40 | 40 | class Registry implements IRegistry { |
| 41 | 41 | |
| 42 | - /** @var string[] */ |
|
| 43 | - private $lazyReporters = []; |
|
| 44 | - |
|
| 45 | - /** @var IReporter[] */ |
|
| 46 | - private $reporters = []; |
|
| 47 | - |
|
| 48 | - /** @var IServerContainer */ |
|
| 49 | - private $serverContainer; |
|
| 50 | - |
|
| 51 | - public function __construct(IServerContainer $serverContainer) { |
|
| 52 | - $this->serverContainer = $serverContainer; |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - /** |
|
| 56 | - * Register a reporter instance |
|
| 57 | - * |
|
| 58 | - * @param IReporter $reporter |
|
| 59 | - */ |
|
| 60 | - public function register(IReporter $reporter): void { |
|
| 61 | - $this->reporters[] = $reporter; |
|
| 62 | - } |
|
| 63 | - |
|
| 64 | - public function registerLazy(string $class): void { |
|
| 65 | - $this->lazyReporters[] = $class; |
|
| 66 | - } |
|
| 67 | - |
|
| 68 | - /** |
|
| 69 | - * Delegate breadcrumb collection to all registered reporters |
|
| 70 | - * |
|
| 71 | - * @param string $message |
|
| 72 | - * @param string $category |
|
| 73 | - * @param array $context |
|
| 74 | - * |
|
| 75 | - * @since 15.0.0 |
|
| 76 | - */ |
|
| 77 | - public function delegateBreadcrumb(string $message, string $category, array $context = []): void { |
|
| 78 | - $this->loadLazyProviders(); |
|
| 79 | - |
|
| 80 | - foreach ($this->reporters as $reporter) { |
|
| 81 | - if ($reporter instanceof ICollectBreadcrumbs) { |
|
| 82 | - $reporter->collect($message, $category, $context); |
|
| 83 | - } |
|
| 84 | - } |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - /** |
|
| 88 | - * Delegate crash reporting to all registered reporters |
|
| 89 | - * |
|
| 90 | - * @param Exception|Throwable $exception |
|
| 91 | - * @param array $context |
|
| 92 | - */ |
|
| 93 | - public function delegateReport($exception, array $context = []): void { |
|
| 94 | - $this->loadLazyProviders(); |
|
| 95 | - |
|
| 96 | - foreach ($this->reporters as $reporter) { |
|
| 97 | - $reporter->report($exception, $context); |
|
| 98 | - } |
|
| 99 | - } |
|
| 100 | - |
|
| 101 | - /** |
|
| 102 | - * Delegate a message to all reporters that implement IMessageReporter |
|
| 103 | - * |
|
| 104 | - * @param string $message |
|
| 105 | - * @param array $context |
|
| 106 | - * |
|
| 107 | - * @return void |
|
| 108 | - */ |
|
| 109 | - public function delegateMessage(string $message, array $context = []): void { |
|
| 110 | - $this->loadLazyProviders(); |
|
| 111 | - |
|
| 112 | - foreach ($this->reporters as $reporter) { |
|
| 113 | - if ($reporter instanceof IMessageReporter) { |
|
| 114 | - $reporter->reportMessage($message, $context); |
|
| 115 | - } |
|
| 116 | - } |
|
| 117 | - } |
|
| 118 | - |
|
| 119 | - private function loadLazyProviders(): void { |
|
| 120 | - while (($class = array_shift($this->lazyReporters)) !== null) { |
|
| 121 | - try { |
|
| 122 | - /** @var IReporter $reporter */ |
|
| 123 | - $reporter = $this->serverContainer->query($class); |
|
| 124 | - } catch (QueryException $e) { |
|
| 125 | - /* |
|
| 42 | + /** @var string[] */ |
|
| 43 | + private $lazyReporters = []; |
|
| 44 | + |
|
| 45 | + /** @var IReporter[] */ |
|
| 46 | + private $reporters = []; |
|
| 47 | + |
|
| 48 | + /** @var IServerContainer */ |
|
| 49 | + private $serverContainer; |
|
| 50 | + |
|
| 51 | + public function __construct(IServerContainer $serverContainer) { |
|
| 52 | + $this->serverContainer = $serverContainer; |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + /** |
|
| 56 | + * Register a reporter instance |
|
| 57 | + * |
|
| 58 | + * @param IReporter $reporter |
|
| 59 | + */ |
|
| 60 | + public function register(IReporter $reporter): void { |
|
| 61 | + $this->reporters[] = $reporter; |
|
| 62 | + } |
|
| 63 | + |
|
| 64 | + public function registerLazy(string $class): void { |
|
| 65 | + $this->lazyReporters[] = $class; |
|
| 66 | + } |
|
| 67 | + |
|
| 68 | + /** |
|
| 69 | + * Delegate breadcrumb collection to all registered reporters |
|
| 70 | + * |
|
| 71 | + * @param string $message |
|
| 72 | + * @param string $category |
|
| 73 | + * @param array $context |
|
| 74 | + * |
|
| 75 | + * @since 15.0.0 |
|
| 76 | + */ |
|
| 77 | + public function delegateBreadcrumb(string $message, string $category, array $context = []): void { |
|
| 78 | + $this->loadLazyProviders(); |
|
| 79 | + |
|
| 80 | + foreach ($this->reporters as $reporter) { |
|
| 81 | + if ($reporter instanceof ICollectBreadcrumbs) { |
|
| 82 | + $reporter->collect($message, $category, $context); |
|
| 83 | + } |
|
| 84 | + } |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + /** |
|
| 88 | + * Delegate crash reporting to all registered reporters |
|
| 89 | + * |
|
| 90 | + * @param Exception|Throwable $exception |
|
| 91 | + * @param array $context |
|
| 92 | + */ |
|
| 93 | + public function delegateReport($exception, array $context = []): void { |
|
| 94 | + $this->loadLazyProviders(); |
|
| 95 | + |
|
| 96 | + foreach ($this->reporters as $reporter) { |
|
| 97 | + $reporter->report($exception, $context); |
|
| 98 | + } |
|
| 99 | + } |
|
| 100 | + |
|
| 101 | + /** |
|
| 102 | + * Delegate a message to all reporters that implement IMessageReporter |
|
| 103 | + * |
|
| 104 | + * @param string $message |
|
| 105 | + * @param array $context |
|
| 106 | + * |
|
| 107 | + * @return void |
|
| 108 | + */ |
|
| 109 | + public function delegateMessage(string $message, array $context = []): void { |
|
| 110 | + $this->loadLazyProviders(); |
|
| 111 | + |
|
| 112 | + foreach ($this->reporters as $reporter) { |
|
| 113 | + if ($reporter instanceof IMessageReporter) { |
|
| 114 | + $reporter->reportMessage($message, $context); |
|
| 115 | + } |
|
| 116 | + } |
|
| 117 | + } |
|
| 118 | + |
|
| 119 | + private function loadLazyProviders(): void { |
|
| 120 | + while (($class = array_shift($this->lazyReporters)) !== null) { |
|
| 121 | + try { |
|
| 122 | + /** @var IReporter $reporter */ |
|
| 123 | + $reporter = $this->serverContainer->query($class); |
|
| 124 | + } catch (QueryException $e) { |
|
| 125 | + /* |
|
| 126 | 126 | * There is a circular dependency between the logger and the registry, so |
| 127 | 127 | * we can not inject it. Thus the static call. |
| 128 | 128 | */ |
| 129 | - \OC::$server->get(LoggerInterface::class)->critical('Could not load lazy crash reporter: ' . $e->getMessage(), [ |
|
| 130 | - 'exception' => $e, |
|
| 131 | - ]); |
|
| 132 | - } |
|
| 133 | - /** |
|
| 134 | - * Try to register the loaded reporter. Theoretically it could be of a wrong |
|
| 135 | - * type, so we might get a TypeError here that we should catch. |
|
| 136 | - */ |
|
| 137 | - try { |
|
| 138 | - $this->register($reporter); |
|
| 139 | - } catch (Throwable $e) { |
|
| 140 | - /* |
|
| 129 | + \OC::$server->get(LoggerInterface::class)->critical('Could not load lazy crash reporter: ' . $e->getMessage(), [ |
|
| 130 | + 'exception' => $e, |
|
| 131 | + ]); |
|
| 132 | + } |
|
| 133 | + /** |
|
| 134 | + * Try to register the loaded reporter. Theoretically it could be of a wrong |
|
| 135 | + * type, so we might get a TypeError here that we should catch. |
|
| 136 | + */ |
|
| 137 | + try { |
|
| 138 | + $this->register($reporter); |
|
| 139 | + } catch (Throwable $e) { |
|
| 140 | + /* |
|
| 141 | 141 | * There is a circular dependency between the logger and the registry, so |
| 142 | 142 | * we can not inject it. Thus the static call. |
| 143 | 143 | */ |
| 144 | - \OC::$server->get(LoggerInterface::class)->critical('Could not register lazy crash reporter: ' . $e->getMessage(), [ |
|
| 145 | - 'exception' => $e, |
|
| 146 | - ]); |
|
| 147 | - } |
|
| 148 | - } |
|
| 149 | - } |
|
| 150 | - |
|
| 151 | - public function hasReporters(): bool { |
|
| 152 | - return !empty($this->lazyReporters) || !empty($this->reporters); |
|
| 153 | - } |
|
| 144 | + \OC::$server->get(LoggerInterface::class)->critical('Could not register lazy crash reporter: ' . $e->getMessage(), [ |
|
| 145 | + 'exception' => $e, |
|
| 146 | + ]); |
|
| 147 | + } |
|
| 148 | + } |
|
| 149 | + } |
|
| 150 | + |
|
| 151 | + public function hasReporters(): bool { |
|
| 152 | + return !empty($this->lazyReporters) || !empty($this->reporters); |
|
| 153 | + } |
|
| 154 | 154 | } |