@@ -57,505 +57,505 @@ |
||
57 | 57 | * @since 4.0.0 |
58 | 58 | */ |
59 | 59 | class Util { |
60 | - /** |
|
61 | - * @deprecated 14.0.0 use \OCP\ILogger::DEBUG |
|
62 | - */ |
|
63 | - const DEBUG=0; |
|
64 | - /** |
|
65 | - * @deprecated 14.0.0 use \OCP\ILogger::INFO |
|
66 | - */ |
|
67 | - const INFO=1; |
|
68 | - /** |
|
69 | - * @deprecated 14.0.0 use \OCP\ILogger::WARN |
|
70 | - */ |
|
71 | - const WARN=2; |
|
72 | - /** |
|
73 | - * @deprecated 14.0.0 use \OCP\ILogger::ERROR |
|
74 | - */ |
|
75 | - const ERROR=3; |
|
76 | - /** |
|
77 | - * @deprecated 14.0.0 use \OCP\ILogger::FATAL |
|
78 | - */ |
|
79 | - const FATAL=4; |
|
80 | - |
|
81 | - /** \OCP\Share\IManager */ |
|
82 | - private static $shareManager; |
|
83 | - |
|
84 | - /** |
|
85 | - * get the current installed version of ownCloud |
|
86 | - * @return array |
|
87 | - * @since 4.0.0 |
|
88 | - */ |
|
89 | - public static function getVersion() { |
|
90 | - return \OC_Util::getVersion(); |
|
91 | - } |
|
60 | + /** |
|
61 | + * @deprecated 14.0.0 use \OCP\ILogger::DEBUG |
|
62 | + */ |
|
63 | + const DEBUG=0; |
|
64 | + /** |
|
65 | + * @deprecated 14.0.0 use \OCP\ILogger::INFO |
|
66 | + */ |
|
67 | + const INFO=1; |
|
68 | + /** |
|
69 | + * @deprecated 14.0.0 use \OCP\ILogger::WARN |
|
70 | + */ |
|
71 | + const WARN=2; |
|
72 | + /** |
|
73 | + * @deprecated 14.0.0 use \OCP\ILogger::ERROR |
|
74 | + */ |
|
75 | + const ERROR=3; |
|
76 | + /** |
|
77 | + * @deprecated 14.0.0 use \OCP\ILogger::FATAL |
|
78 | + */ |
|
79 | + const FATAL=4; |
|
80 | + |
|
81 | + /** \OCP\Share\IManager */ |
|
82 | + private static $shareManager; |
|
83 | + |
|
84 | + /** |
|
85 | + * get the current installed version of ownCloud |
|
86 | + * @return array |
|
87 | + * @since 4.0.0 |
|
88 | + */ |
|
89 | + public static function getVersion() { |
|
90 | + return \OC_Util::getVersion(); |
|
91 | + } |
|
92 | 92 | |
93 | - /** |
|
94 | - * Set current update channel |
|
95 | - * @param string $channel |
|
96 | - * @since 8.1.0 |
|
97 | - */ |
|
98 | - public static function setChannel($channel) { |
|
99 | - \OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel); |
|
100 | - } |
|
93 | + /** |
|
94 | + * Set current update channel |
|
95 | + * @param string $channel |
|
96 | + * @since 8.1.0 |
|
97 | + */ |
|
98 | + public static function setChannel($channel) { |
|
99 | + \OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel); |
|
100 | + } |
|
101 | 101 | |
102 | - /** |
|
103 | - * Get current update channel |
|
104 | - * @return string |
|
105 | - * @since 8.1.0 |
|
106 | - */ |
|
107 | - public static function getChannel() { |
|
108 | - return \OC_Util::getChannel(); |
|
109 | - } |
|
110 | - |
|
111 | - /** |
|
112 | - * write a message in the log |
|
113 | - * @param string $app |
|
114 | - * @param string $message |
|
115 | - * @param int $level |
|
116 | - * @since 4.0.0 |
|
117 | - * @deprecated 13.0.0 use log of \OCP\ILogger |
|
118 | - */ |
|
119 | - public static function writeLog( $app, $message, $level ) { |
|
120 | - $context = ['app' => $app]; |
|
121 | - \OC::$server->getLogger()->log($level, $message, $context); |
|
122 | - } |
|
123 | - |
|
124 | - /** |
|
125 | - * write exception into the log |
|
126 | - * @param string $app app name |
|
127 | - * @param \Exception $ex exception to log |
|
128 | - * @param int $level log level, defaults to \OCP\Util::FATAL |
|
129 | - * @since ....0.0 - parameter $level was added in 7.0.0 |
|
130 | - * @deprecated 8.2.0 use logException of \OCP\ILogger |
|
131 | - */ |
|
132 | - public static function logException( $app, \Exception $ex, $level = ILogger::FATAL) { |
|
133 | - \OC::$server->getLogger()->logException($ex, ['app' => $app]); |
|
134 | - } |
|
135 | - |
|
136 | - /** |
|
137 | - * check if sharing is disabled for the current user |
|
138 | - * |
|
139 | - * @return boolean |
|
140 | - * @since 7.0.0 |
|
141 | - * @deprecated 9.1.0 Use \OC::$server->getShareManager()->sharingDisabledForUser |
|
142 | - */ |
|
143 | - public static function isSharingDisabledForUser() { |
|
144 | - if (self::$shareManager === null) { |
|
145 | - self::$shareManager = \OC::$server->getShareManager(); |
|
146 | - } |
|
147 | - |
|
148 | - $user = \OC::$server->getUserSession()->getUser(); |
|
149 | - if ($user !== null) { |
|
150 | - $user = $user->getUID(); |
|
151 | - } |
|
152 | - |
|
153 | - return self::$shareManager->sharingDisabledForUser($user); |
|
154 | - } |
|
155 | - |
|
156 | - /** |
|
157 | - * get l10n object |
|
158 | - * @param string $application |
|
159 | - * @param string|null $language |
|
160 | - * @return \OCP\IL10N |
|
161 | - * @since 6.0.0 - parameter $language was added in 8.0.0 |
|
162 | - */ |
|
163 | - public static function getL10N($application, $language = null) { |
|
164 | - return \OC::$server->getL10N($application, $language); |
|
165 | - } |
|
166 | - |
|
167 | - /** |
|
168 | - * add a css file |
|
169 | - * @param string $application |
|
170 | - * @param string $file |
|
171 | - * @since 4.0.0 |
|
172 | - */ |
|
173 | - public static function addStyle( $application, $file = null ) { |
|
174 | - \OC_Util::addStyle( $application, $file ); |
|
175 | - } |
|
176 | - |
|
177 | - /** |
|
178 | - * add a javascript file |
|
179 | - * @param string $application |
|
180 | - * @param string $file |
|
181 | - * @since 4.0.0 |
|
182 | - */ |
|
183 | - public static function addScript( $application, $file = null ) { |
|
184 | - \OC_Util::addScript( $application, $file ); |
|
185 | - } |
|
186 | - |
|
187 | - /** |
|
188 | - * Add a translation JS file |
|
189 | - * @param string $application application id |
|
190 | - * @param string $languageCode language code, defaults to the current locale |
|
191 | - * @since 8.0.0 |
|
192 | - */ |
|
193 | - public static function addTranslations($application, $languageCode = null) { |
|
194 | - \OC_Util::addTranslations($application, $languageCode); |
|
195 | - } |
|
196 | - |
|
197 | - /** |
|
198 | - * Add a custom element to the header |
|
199 | - * If $text is null then the element will be written as empty element. |
|
200 | - * So use "" to get a closing tag. |
|
201 | - * @param string $tag tag name of the element |
|
202 | - * @param array $attributes array of attributes for the element |
|
203 | - * @param string $text the text content for the element |
|
204 | - * @since 4.0.0 |
|
205 | - */ |
|
206 | - public static function addHeader($tag, $attributes, $text=null) { |
|
207 | - \OC_Util::addHeader($tag, $attributes, $text); |
|
208 | - } |
|
209 | - |
|
210 | - /** |
|
211 | - * Creates an absolute url to the given app and file. |
|
212 | - * @param string $app app |
|
213 | - * @param string $file file |
|
214 | - * @param array $args array with param=>value, will be appended to the returned url |
|
215 | - * The value of $args will be urlencoded |
|
216 | - * @return string the url |
|
217 | - * @since 4.0.0 - parameter $args was added in 4.5.0 |
|
218 | - */ |
|
219 | - public static function linkToAbsolute( $app, $file, $args = array() ) { |
|
220 | - $urlGenerator = \OC::$server->getURLGenerator(); |
|
221 | - return $urlGenerator->getAbsoluteURL( |
|
222 | - $urlGenerator->linkTo($app, $file, $args) |
|
223 | - ); |
|
224 | - } |
|
225 | - |
|
226 | - /** |
|
227 | - * Creates an absolute url for remote use. |
|
228 | - * @param string $service id |
|
229 | - * @return string the url |
|
230 | - * @since 4.0.0 |
|
231 | - */ |
|
232 | - public static function linkToRemote( $service ) { |
|
233 | - $urlGenerator = \OC::$server->getURLGenerator(); |
|
234 | - $remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service; |
|
235 | - return $urlGenerator->getAbsoluteURL( |
|
236 | - $remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '') |
|
237 | - ); |
|
238 | - } |
|
239 | - |
|
240 | - /** |
|
241 | - * Creates an absolute url for public use |
|
242 | - * @param string $service id |
|
243 | - * @return string the url |
|
244 | - * @since 4.5.0 |
|
245 | - */ |
|
246 | - public static function linkToPublic($service) { |
|
247 | - return \OC_Helper::linkToPublic($service); |
|
248 | - } |
|
249 | - |
|
250 | - /** |
|
251 | - * Returns the server host name without an eventual port number |
|
252 | - * @return string the server hostname |
|
253 | - * @since 5.0.0 |
|
254 | - */ |
|
255 | - public static function getServerHostName() { |
|
256 | - $host_name = \OC::$server->getRequest()->getServerHost(); |
|
257 | - // strip away port number (if existing) |
|
258 | - $colon_pos = strpos($host_name, ':'); |
|
259 | - if ($colon_pos != FALSE) { |
|
260 | - $host_name = substr($host_name, 0, $colon_pos); |
|
261 | - } |
|
262 | - return $host_name; |
|
263 | - } |
|
264 | - |
|
265 | - /** |
|
266 | - * Returns the default email address |
|
267 | - * @param string $user_part the user part of the address |
|
268 | - * @return string the default email address |
|
269 | - * |
|
270 | - * Assembles a default email address (using the server hostname |
|
271 | - * and the given user part, and returns it |
|
272 | - * Example: when given lostpassword-noreply as $user_part param, |
|
273 | - * and is currently accessed via http(s)://example.com/, |
|
274 | - * it would return '[email protected]' |
|
275 | - * |
|
276 | - * If the configuration value 'mail_from_address' is set in |
|
277 | - * config.php, this value will override the $user_part that |
|
278 | - * is passed to this function |
|
279 | - * @since 5.0.0 |
|
280 | - */ |
|
281 | - public static function getDefaultEmailAddress($user_part) { |
|
282 | - $config = \OC::$server->getConfig(); |
|
283 | - $user_part = $config->getSystemValue('mail_from_address', $user_part); |
|
284 | - $host_name = self::getServerHostName(); |
|
285 | - $host_name = $config->getSystemValue('mail_domain', $host_name); |
|
286 | - $defaultEmailAddress = $user_part.'@'.$host_name; |
|
287 | - |
|
288 | - $mailer = \OC::$server->getMailer(); |
|
289 | - if ($mailer->validateMailAddress($defaultEmailAddress)) { |
|
290 | - return $defaultEmailAddress; |
|
291 | - } |
|
292 | - |
|
293 | - // in case we cannot build a valid email address from the hostname let's fallback to 'localhost.localdomain' |
|
294 | - return $user_part.'@localhost.localdomain'; |
|
295 | - } |
|
296 | - |
|
297 | - /** |
|
298 | - * Make a human file size (2048 to 2 kB) |
|
299 | - * @param int $bytes file size in bytes |
|
300 | - * @return string a human readable file size |
|
301 | - * @since 4.0.0 |
|
302 | - */ |
|
303 | - public static function humanFileSize($bytes) { |
|
304 | - return \OC_Helper::humanFileSize($bytes); |
|
305 | - } |
|
306 | - |
|
307 | - /** |
|
308 | - * Make a computer file size (2 kB to 2048) |
|
309 | - * @param string $str file size in a fancy format |
|
310 | - * @return float a file size in bytes |
|
311 | - * |
|
312 | - * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418 |
|
313 | - * @since 4.0.0 |
|
314 | - */ |
|
315 | - public static function computerFileSize($str) { |
|
316 | - return \OC_Helper::computerFileSize($str); |
|
317 | - } |
|
318 | - |
|
319 | - /** |
|
320 | - * connects a function to a hook |
|
321 | - * |
|
322 | - * @param string $signalClass class name of emitter |
|
323 | - * @param string $signalName name of signal |
|
324 | - * @param string|object $slotClass class name of slot |
|
325 | - * @param string $slotName name of slot |
|
326 | - * @return bool |
|
327 | - * |
|
328 | - * This function makes it very easy to connect to use hooks. |
|
329 | - * |
|
330 | - * TODO: write example |
|
331 | - * @since 4.0.0 |
|
332 | - */ |
|
333 | - static public function connectHook($signalClass, $signalName, $slotClass, $slotName) { |
|
334 | - return \OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName); |
|
335 | - } |
|
336 | - |
|
337 | - /** |
|
338 | - * Emits a signal. To get data from the slot use references! |
|
339 | - * @param string $signalclass class name of emitter |
|
340 | - * @param string $signalname name of signal |
|
341 | - * @param array $params default: array() array with additional data |
|
342 | - * @return bool true if slots exists or false if not |
|
343 | - * |
|
344 | - * TODO: write example |
|
345 | - * @since 4.0.0 |
|
346 | - */ |
|
347 | - static public function emitHook($signalclass, $signalname, $params = array()) { |
|
348 | - return \OC_Hook::emit($signalclass, $signalname, $params); |
|
349 | - } |
|
350 | - |
|
351 | - /** |
|
352 | - * Cached encrypted CSRF token. Some static unit-tests of ownCloud compare |
|
353 | - * multiple OC_Template elements which invoke `callRegister`. If the value |
|
354 | - * would not be cached these unit-tests would fail. |
|
355 | - * @var string |
|
356 | - */ |
|
357 | - private static $token = ''; |
|
358 | - |
|
359 | - /** |
|
360 | - * Register an get/post call. This is important to prevent CSRF attacks |
|
361 | - * @since 4.5.0 |
|
362 | - */ |
|
363 | - public static function callRegister() { |
|
364 | - if(self::$token === '') { |
|
365 | - self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue(); |
|
366 | - } |
|
367 | - return self::$token; |
|
368 | - } |
|
369 | - |
|
370 | - /** |
|
371 | - * Check an ajax get/post call if the request token is valid. exit if not. |
|
372 | - * @since 4.5.0 |
|
373 | - * @deprecated 9.0.0 Use annotations based on the app framework. |
|
374 | - */ |
|
375 | - public static function callCheck() { |
|
376 | - if(!\OC::$server->getRequest()->passesStrictCookieCheck()) { |
|
377 | - header('Location: '.\OC::$WEBROOT); |
|
378 | - exit(); |
|
379 | - } |
|
380 | - |
|
381 | - if (!\OC::$server->getRequest()->passesCSRFCheck()) { |
|
382 | - exit(); |
|
383 | - } |
|
384 | - } |
|
385 | - |
|
386 | - /** |
|
387 | - * Used to sanitize HTML |
|
388 | - * |
|
389 | - * This function is used to sanitize HTML and should be applied on any |
|
390 | - * string or array of strings before displaying it on a web page. |
|
391 | - * |
|
392 | - * @param string|array $value |
|
393 | - * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter. |
|
394 | - * @since 4.5.0 |
|
395 | - */ |
|
396 | - public static function sanitizeHTML($value) { |
|
397 | - return \OC_Util::sanitizeHTML($value); |
|
398 | - } |
|
399 | - |
|
400 | - /** |
|
401 | - * Public function to encode url parameters |
|
402 | - * |
|
403 | - * This function is used to encode path to file before output. |
|
404 | - * Encoding is done according to RFC 3986 with one exception: |
|
405 | - * Character '/' is preserved as is. |
|
406 | - * |
|
407 | - * @param string $component part of URI to encode |
|
408 | - * @return string |
|
409 | - * @since 6.0.0 |
|
410 | - */ |
|
411 | - public static function encodePath($component) { |
|
412 | - return \OC_Util::encodePath($component); |
|
413 | - } |
|
414 | - |
|
415 | - /** |
|
416 | - * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. |
|
417 | - * |
|
418 | - * @param array $input The array to work on |
|
419 | - * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default) |
|
420 | - * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
421 | - * @return array |
|
422 | - * @since 4.5.0 |
|
423 | - */ |
|
424 | - public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') { |
|
425 | - return \OC_Helper::mb_array_change_key_case($input, $case, $encoding); |
|
426 | - } |
|
427 | - |
|
428 | - /** |
|
429 | - * replaces a copy of string delimited by the start and (optionally) length parameters with the string given in replacement. |
|
430 | - * |
|
431 | - * @param string $string The input string. Opposite to the PHP build-in function does not accept an array. |
|
432 | - * @param string $replacement The replacement string. |
|
433 | - * @param int $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string. |
|
434 | - * @param int $length Length of the part to be replaced |
|
435 | - * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
436 | - * @return string |
|
437 | - * @since 4.5.0 |
|
438 | - * @deprecated 8.2.0 Use substr_replace() instead. |
|
439 | - */ |
|
440 | - public static function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = 'UTF-8') { |
|
441 | - return substr_replace($string, $replacement, $start, $length); |
|
442 | - } |
|
443 | - |
|
444 | - /** |
|
445 | - * Replace all occurrences of the search string with the replacement string |
|
446 | - * |
|
447 | - * @param string $search The value being searched for, otherwise known as the needle. String. |
|
448 | - * @param string $replace The replacement string. |
|
449 | - * @param string $subject The string or array being searched and replaced on, otherwise known as the haystack. |
|
450 | - * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
451 | - * @param int $count If passed, this will be set to the number of replacements performed. |
|
452 | - * @return string |
|
453 | - * @since 4.5.0 |
|
454 | - * @deprecated 8.2.0 Use str_replace() instead. |
|
455 | - */ |
|
456 | - public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { |
|
457 | - return str_replace($search, $replace, $subject, $count); |
|
458 | - } |
|
459 | - |
|
460 | - /** |
|
461 | - * performs a search in a nested array |
|
462 | - * |
|
463 | - * @param array $haystack the array to be searched |
|
464 | - * @param string $needle the search string |
|
465 | - * @param mixed $index optional, only search this key name |
|
466 | - * @return mixed the key of the matching field, otherwise false |
|
467 | - * @since 4.5.0 |
|
468 | - */ |
|
469 | - public static function recursiveArraySearch($haystack, $needle, $index = null) { |
|
470 | - return \OC_Helper::recursiveArraySearch($haystack, $needle, $index); |
|
471 | - } |
|
472 | - |
|
473 | - /** |
|
474 | - * calculates the maximum upload size respecting system settings, free space and user quota |
|
475 | - * |
|
476 | - * @param string $dir the current folder where the user currently operates |
|
477 | - * @param int $free the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly |
|
478 | - * @return int number of bytes representing |
|
479 | - * @since 5.0.0 |
|
480 | - */ |
|
481 | - public static function maxUploadFilesize($dir, $free = null) { |
|
482 | - return \OC_Helper::maxUploadFilesize($dir, $free); |
|
483 | - } |
|
484 | - |
|
485 | - /** |
|
486 | - * Calculate free space left within user quota |
|
487 | - * @param string $dir the current folder where the user currently operates |
|
488 | - * @return int number of bytes representing |
|
489 | - * @since 7.0.0 |
|
490 | - */ |
|
491 | - public static function freeSpace($dir) { |
|
492 | - return \OC_Helper::freeSpace($dir); |
|
493 | - } |
|
494 | - |
|
495 | - /** |
|
496 | - * Calculate PHP upload limit |
|
497 | - * |
|
498 | - * @return int number of bytes representing |
|
499 | - * @since 7.0.0 |
|
500 | - */ |
|
501 | - public static function uploadLimit() { |
|
502 | - return \OC_Helper::uploadLimit(); |
|
503 | - } |
|
504 | - |
|
505 | - /** |
|
506 | - * Returns whether the given file name is valid |
|
507 | - * @param string $file file name to check |
|
508 | - * @return bool true if the file name is valid, false otherwise |
|
509 | - * @deprecated 8.1.0 use \OC\Files\View::verifyPath() |
|
510 | - * @since 7.0.0 |
|
511 | - * @suppress PhanDeprecatedFunction |
|
512 | - */ |
|
513 | - public static function isValidFileName($file) { |
|
514 | - return \OC_Util::isValidFileName($file); |
|
515 | - } |
|
516 | - |
|
517 | - /** |
|
518 | - * Compare two strings to provide a natural sort |
|
519 | - * @param string $a first string to compare |
|
520 | - * @param string $b second string to compare |
|
521 | - * @return int -1 if $b comes before $a, 1 if $a comes before $b |
|
522 | - * or 0 if the strings are identical |
|
523 | - * @since 7.0.0 |
|
524 | - */ |
|
525 | - public static function naturalSortCompare($a, $b) { |
|
526 | - return \OC\NaturalSort::getInstance()->compare($a, $b); |
|
527 | - } |
|
528 | - |
|
529 | - /** |
|
530 | - * check if a password is required for each public link |
|
531 | - * @return boolean |
|
532 | - * @since 7.0.0 |
|
533 | - */ |
|
534 | - public static function isPublicLinkPasswordRequired() { |
|
535 | - return \OC_Util::isPublicLinkPasswordRequired(); |
|
536 | - } |
|
537 | - |
|
538 | - /** |
|
539 | - * check if share API enforces a default expire date |
|
540 | - * @return boolean |
|
541 | - * @since 8.0.0 |
|
542 | - */ |
|
543 | - public static function isDefaultExpireDateEnforced() { |
|
544 | - return \OC_Util::isDefaultExpireDateEnforced(); |
|
545 | - } |
|
546 | - |
|
547 | - protected static $needUpgradeCache = null; |
|
548 | - |
|
549 | - /** |
|
550 | - * Checks whether the current version needs upgrade. |
|
551 | - * |
|
552 | - * @return bool true if upgrade is needed, false otherwise |
|
553 | - * @since 7.0.0 |
|
554 | - */ |
|
555 | - public static function needUpgrade() { |
|
556 | - if (!isset(self::$needUpgradeCache)) { |
|
557 | - self::$needUpgradeCache=\OC_Util::needUpgrade(\OC::$server->getSystemConfig()); |
|
558 | - } |
|
559 | - return self::$needUpgradeCache; |
|
560 | - } |
|
102 | + /** |
|
103 | + * Get current update channel |
|
104 | + * @return string |
|
105 | + * @since 8.1.0 |
|
106 | + */ |
|
107 | + public static function getChannel() { |
|
108 | + return \OC_Util::getChannel(); |
|
109 | + } |
|
110 | + |
|
111 | + /** |
|
112 | + * write a message in the log |
|
113 | + * @param string $app |
|
114 | + * @param string $message |
|
115 | + * @param int $level |
|
116 | + * @since 4.0.0 |
|
117 | + * @deprecated 13.0.0 use log of \OCP\ILogger |
|
118 | + */ |
|
119 | + public static function writeLog( $app, $message, $level ) { |
|
120 | + $context = ['app' => $app]; |
|
121 | + \OC::$server->getLogger()->log($level, $message, $context); |
|
122 | + } |
|
123 | + |
|
124 | + /** |
|
125 | + * write exception into the log |
|
126 | + * @param string $app app name |
|
127 | + * @param \Exception $ex exception to log |
|
128 | + * @param int $level log level, defaults to \OCP\Util::FATAL |
|
129 | + * @since ....0.0 - parameter $level was added in 7.0.0 |
|
130 | + * @deprecated 8.2.0 use logException of \OCP\ILogger |
|
131 | + */ |
|
132 | + public static function logException( $app, \Exception $ex, $level = ILogger::FATAL) { |
|
133 | + \OC::$server->getLogger()->logException($ex, ['app' => $app]); |
|
134 | + } |
|
135 | + |
|
136 | + /** |
|
137 | + * check if sharing is disabled for the current user |
|
138 | + * |
|
139 | + * @return boolean |
|
140 | + * @since 7.0.0 |
|
141 | + * @deprecated 9.1.0 Use \OC::$server->getShareManager()->sharingDisabledForUser |
|
142 | + */ |
|
143 | + public static function isSharingDisabledForUser() { |
|
144 | + if (self::$shareManager === null) { |
|
145 | + self::$shareManager = \OC::$server->getShareManager(); |
|
146 | + } |
|
147 | + |
|
148 | + $user = \OC::$server->getUserSession()->getUser(); |
|
149 | + if ($user !== null) { |
|
150 | + $user = $user->getUID(); |
|
151 | + } |
|
152 | + |
|
153 | + return self::$shareManager->sharingDisabledForUser($user); |
|
154 | + } |
|
155 | + |
|
156 | + /** |
|
157 | + * get l10n object |
|
158 | + * @param string $application |
|
159 | + * @param string|null $language |
|
160 | + * @return \OCP\IL10N |
|
161 | + * @since 6.0.0 - parameter $language was added in 8.0.0 |
|
162 | + */ |
|
163 | + public static function getL10N($application, $language = null) { |
|
164 | + return \OC::$server->getL10N($application, $language); |
|
165 | + } |
|
166 | + |
|
167 | + /** |
|
168 | + * add a css file |
|
169 | + * @param string $application |
|
170 | + * @param string $file |
|
171 | + * @since 4.0.0 |
|
172 | + */ |
|
173 | + public static function addStyle( $application, $file = null ) { |
|
174 | + \OC_Util::addStyle( $application, $file ); |
|
175 | + } |
|
176 | + |
|
177 | + /** |
|
178 | + * add a javascript file |
|
179 | + * @param string $application |
|
180 | + * @param string $file |
|
181 | + * @since 4.0.0 |
|
182 | + */ |
|
183 | + public static function addScript( $application, $file = null ) { |
|
184 | + \OC_Util::addScript( $application, $file ); |
|
185 | + } |
|
186 | + |
|
187 | + /** |
|
188 | + * Add a translation JS file |
|
189 | + * @param string $application application id |
|
190 | + * @param string $languageCode language code, defaults to the current locale |
|
191 | + * @since 8.0.0 |
|
192 | + */ |
|
193 | + public static function addTranslations($application, $languageCode = null) { |
|
194 | + \OC_Util::addTranslations($application, $languageCode); |
|
195 | + } |
|
196 | + |
|
197 | + /** |
|
198 | + * Add a custom element to the header |
|
199 | + * If $text is null then the element will be written as empty element. |
|
200 | + * So use "" to get a closing tag. |
|
201 | + * @param string $tag tag name of the element |
|
202 | + * @param array $attributes array of attributes for the element |
|
203 | + * @param string $text the text content for the element |
|
204 | + * @since 4.0.0 |
|
205 | + */ |
|
206 | + public static function addHeader($tag, $attributes, $text=null) { |
|
207 | + \OC_Util::addHeader($tag, $attributes, $text); |
|
208 | + } |
|
209 | + |
|
210 | + /** |
|
211 | + * Creates an absolute url to the given app and file. |
|
212 | + * @param string $app app |
|
213 | + * @param string $file file |
|
214 | + * @param array $args array with param=>value, will be appended to the returned url |
|
215 | + * The value of $args will be urlencoded |
|
216 | + * @return string the url |
|
217 | + * @since 4.0.0 - parameter $args was added in 4.5.0 |
|
218 | + */ |
|
219 | + public static function linkToAbsolute( $app, $file, $args = array() ) { |
|
220 | + $urlGenerator = \OC::$server->getURLGenerator(); |
|
221 | + return $urlGenerator->getAbsoluteURL( |
|
222 | + $urlGenerator->linkTo($app, $file, $args) |
|
223 | + ); |
|
224 | + } |
|
225 | + |
|
226 | + /** |
|
227 | + * Creates an absolute url for remote use. |
|
228 | + * @param string $service id |
|
229 | + * @return string the url |
|
230 | + * @since 4.0.0 |
|
231 | + */ |
|
232 | + public static function linkToRemote( $service ) { |
|
233 | + $urlGenerator = \OC::$server->getURLGenerator(); |
|
234 | + $remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service; |
|
235 | + return $urlGenerator->getAbsoluteURL( |
|
236 | + $remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '') |
|
237 | + ); |
|
238 | + } |
|
239 | + |
|
240 | + /** |
|
241 | + * Creates an absolute url for public use |
|
242 | + * @param string $service id |
|
243 | + * @return string the url |
|
244 | + * @since 4.5.0 |
|
245 | + */ |
|
246 | + public static function linkToPublic($service) { |
|
247 | + return \OC_Helper::linkToPublic($service); |
|
248 | + } |
|
249 | + |
|
250 | + /** |
|
251 | + * Returns the server host name without an eventual port number |
|
252 | + * @return string the server hostname |
|
253 | + * @since 5.0.0 |
|
254 | + */ |
|
255 | + public static function getServerHostName() { |
|
256 | + $host_name = \OC::$server->getRequest()->getServerHost(); |
|
257 | + // strip away port number (if existing) |
|
258 | + $colon_pos = strpos($host_name, ':'); |
|
259 | + if ($colon_pos != FALSE) { |
|
260 | + $host_name = substr($host_name, 0, $colon_pos); |
|
261 | + } |
|
262 | + return $host_name; |
|
263 | + } |
|
264 | + |
|
265 | + /** |
|
266 | + * Returns the default email address |
|
267 | + * @param string $user_part the user part of the address |
|
268 | + * @return string the default email address |
|
269 | + * |
|
270 | + * Assembles a default email address (using the server hostname |
|
271 | + * and the given user part, and returns it |
|
272 | + * Example: when given lostpassword-noreply as $user_part param, |
|
273 | + * and is currently accessed via http(s)://example.com/, |
|
274 | + * it would return '[email protected]' |
|
275 | + * |
|
276 | + * If the configuration value 'mail_from_address' is set in |
|
277 | + * config.php, this value will override the $user_part that |
|
278 | + * is passed to this function |
|
279 | + * @since 5.0.0 |
|
280 | + */ |
|
281 | + public static function getDefaultEmailAddress($user_part) { |
|
282 | + $config = \OC::$server->getConfig(); |
|
283 | + $user_part = $config->getSystemValue('mail_from_address', $user_part); |
|
284 | + $host_name = self::getServerHostName(); |
|
285 | + $host_name = $config->getSystemValue('mail_domain', $host_name); |
|
286 | + $defaultEmailAddress = $user_part.'@'.$host_name; |
|
287 | + |
|
288 | + $mailer = \OC::$server->getMailer(); |
|
289 | + if ($mailer->validateMailAddress($defaultEmailAddress)) { |
|
290 | + return $defaultEmailAddress; |
|
291 | + } |
|
292 | + |
|
293 | + // in case we cannot build a valid email address from the hostname let's fallback to 'localhost.localdomain' |
|
294 | + return $user_part.'@localhost.localdomain'; |
|
295 | + } |
|
296 | + |
|
297 | + /** |
|
298 | + * Make a human file size (2048 to 2 kB) |
|
299 | + * @param int $bytes file size in bytes |
|
300 | + * @return string a human readable file size |
|
301 | + * @since 4.0.0 |
|
302 | + */ |
|
303 | + public static function humanFileSize($bytes) { |
|
304 | + return \OC_Helper::humanFileSize($bytes); |
|
305 | + } |
|
306 | + |
|
307 | + /** |
|
308 | + * Make a computer file size (2 kB to 2048) |
|
309 | + * @param string $str file size in a fancy format |
|
310 | + * @return float a file size in bytes |
|
311 | + * |
|
312 | + * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418 |
|
313 | + * @since 4.0.0 |
|
314 | + */ |
|
315 | + public static function computerFileSize($str) { |
|
316 | + return \OC_Helper::computerFileSize($str); |
|
317 | + } |
|
318 | + |
|
319 | + /** |
|
320 | + * connects a function to a hook |
|
321 | + * |
|
322 | + * @param string $signalClass class name of emitter |
|
323 | + * @param string $signalName name of signal |
|
324 | + * @param string|object $slotClass class name of slot |
|
325 | + * @param string $slotName name of slot |
|
326 | + * @return bool |
|
327 | + * |
|
328 | + * This function makes it very easy to connect to use hooks. |
|
329 | + * |
|
330 | + * TODO: write example |
|
331 | + * @since 4.0.0 |
|
332 | + */ |
|
333 | + static public function connectHook($signalClass, $signalName, $slotClass, $slotName) { |
|
334 | + return \OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName); |
|
335 | + } |
|
336 | + |
|
337 | + /** |
|
338 | + * Emits a signal. To get data from the slot use references! |
|
339 | + * @param string $signalclass class name of emitter |
|
340 | + * @param string $signalname name of signal |
|
341 | + * @param array $params default: array() array with additional data |
|
342 | + * @return bool true if slots exists or false if not |
|
343 | + * |
|
344 | + * TODO: write example |
|
345 | + * @since 4.0.0 |
|
346 | + */ |
|
347 | + static public function emitHook($signalclass, $signalname, $params = array()) { |
|
348 | + return \OC_Hook::emit($signalclass, $signalname, $params); |
|
349 | + } |
|
350 | + |
|
351 | + /** |
|
352 | + * Cached encrypted CSRF token. Some static unit-tests of ownCloud compare |
|
353 | + * multiple OC_Template elements which invoke `callRegister`. If the value |
|
354 | + * would not be cached these unit-tests would fail. |
|
355 | + * @var string |
|
356 | + */ |
|
357 | + private static $token = ''; |
|
358 | + |
|
359 | + /** |
|
360 | + * Register an get/post call. This is important to prevent CSRF attacks |
|
361 | + * @since 4.5.0 |
|
362 | + */ |
|
363 | + public static function callRegister() { |
|
364 | + if(self::$token === '') { |
|
365 | + self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue(); |
|
366 | + } |
|
367 | + return self::$token; |
|
368 | + } |
|
369 | + |
|
370 | + /** |
|
371 | + * Check an ajax get/post call if the request token is valid. exit if not. |
|
372 | + * @since 4.5.0 |
|
373 | + * @deprecated 9.0.0 Use annotations based on the app framework. |
|
374 | + */ |
|
375 | + public static function callCheck() { |
|
376 | + if(!\OC::$server->getRequest()->passesStrictCookieCheck()) { |
|
377 | + header('Location: '.\OC::$WEBROOT); |
|
378 | + exit(); |
|
379 | + } |
|
380 | + |
|
381 | + if (!\OC::$server->getRequest()->passesCSRFCheck()) { |
|
382 | + exit(); |
|
383 | + } |
|
384 | + } |
|
385 | + |
|
386 | + /** |
|
387 | + * Used to sanitize HTML |
|
388 | + * |
|
389 | + * This function is used to sanitize HTML and should be applied on any |
|
390 | + * string or array of strings before displaying it on a web page. |
|
391 | + * |
|
392 | + * @param string|array $value |
|
393 | + * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter. |
|
394 | + * @since 4.5.0 |
|
395 | + */ |
|
396 | + public static function sanitizeHTML($value) { |
|
397 | + return \OC_Util::sanitizeHTML($value); |
|
398 | + } |
|
399 | + |
|
400 | + /** |
|
401 | + * Public function to encode url parameters |
|
402 | + * |
|
403 | + * This function is used to encode path to file before output. |
|
404 | + * Encoding is done according to RFC 3986 with one exception: |
|
405 | + * Character '/' is preserved as is. |
|
406 | + * |
|
407 | + * @param string $component part of URI to encode |
|
408 | + * @return string |
|
409 | + * @since 6.0.0 |
|
410 | + */ |
|
411 | + public static function encodePath($component) { |
|
412 | + return \OC_Util::encodePath($component); |
|
413 | + } |
|
414 | + |
|
415 | + /** |
|
416 | + * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. |
|
417 | + * |
|
418 | + * @param array $input The array to work on |
|
419 | + * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default) |
|
420 | + * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
421 | + * @return array |
|
422 | + * @since 4.5.0 |
|
423 | + */ |
|
424 | + public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') { |
|
425 | + return \OC_Helper::mb_array_change_key_case($input, $case, $encoding); |
|
426 | + } |
|
427 | + |
|
428 | + /** |
|
429 | + * replaces a copy of string delimited by the start and (optionally) length parameters with the string given in replacement. |
|
430 | + * |
|
431 | + * @param string $string The input string. Opposite to the PHP build-in function does not accept an array. |
|
432 | + * @param string $replacement The replacement string. |
|
433 | + * @param int $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string. |
|
434 | + * @param int $length Length of the part to be replaced |
|
435 | + * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
436 | + * @return string |
|
437 | + * @since 4.5.0 |
|
438 | + * @deprecated 8.2.0 Use substr_replace() instead. |
|
439 | + */ |
|
440 | + public static function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = 'UTF-8') { |
|
441 | + return substr_replace($string, $replacement, $start, $length); |
|
442 | + } |
|
443 | + |
|
444 | + /** |
|
445 | + * Replace all occurrences of the search string with the replacement string |
|
446 | + * |
|
447 | + * @param string $search The value being searched for, otherwise known as the needle. String. |
|
448 | + * @param string $replace The replacement string. |
|
449 | + * @param string $subject The string or array being searched and replaced on, otherwise known as the haystack. |
|
450 | + * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
451 | + * @param int $count If passed, this will be set to the number of replacements performed. |
|
452 | + * @return string |
|
453 | + * @since 4.5.0 |
|
454 | + * @deprecated 8.2.0 Use str_replace() instead. |
|
455 | + */ |
|
456 | + public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { |
|
457 | + return str_replace($search, $replace, $subject, $count); |
|
458 | + } |
|
459 | + |
|
460 | + /** |
|
461 | + * performs a search in a nested array |
|
462 | + * |
|
463 | + * @param array $haystack the array to be searched |
|
464 | + * @param string $needle the search string |
|
465 | + * @param mixed $index optional, only search this key name |
|
466 | + * @return mixed the key of the matching field, otherwise false |
|
467 | + * @since 4.5.0 |
|
468 | + */ |
|
469 | + public static function recursiveArraySearch($haystack, $needle, $index = null) { |
|
470 | + return \OC_Helper::recursiveArraySearch($haystack, $needle, $index); |
|
471 | + } |
|
472 | + |
|
473 | + /** |
|
474 | + * calculates the maximum upload size respecting system settings, free space and user quota |
|
475 | + * |
|
476 | + * @param string $dir the current folder where the user currently operates |
|
477 | + * @param int $free the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly |
|
478 | + * @return int number of bytes representing |
|
479 | + * @since 5.0.0 |
|
480 | + */ |
|
481 | + public static function maxUploadFilesize($dir, $free = null) { |
|
482 | + return \OC_Helper::maxUploadFilesize($dir, $free); |
|
483 | + } |
|
484 | + |
|
485 | + /** |
|
486 | + * Calculate free space left within user quota |
|
487 | + * @param string $dir the current folder where the user currently operates |
|
488 | + * @return int number of bytes representing |
|
489 | + * @since 7.0.0 |
|
490 | + */ |
|
491 | + public static function freeSpace($dir) { |
|
492 | + return \OC_Helper::freeSpace($dir); |
|
493 | + } |
|
494 | + |
|
495 | + /** |
|
496 | + * Calculate PHP upload limit |
|
497 | + * |
|
498 | + * @return int number of bytes representing |
|
499 | + * @since 7.0.0 |
|
500 | + */ |
|
501 | + public static function uploadLimit() { |
|
502 | + return \OC_Helper::uploadLimit(); |
|
503 | + } |
|
504 | + |
|
505 | + /** |
|
506 | + * Returns whether the given file name is valid |
|
507 | + * @param string $file file name to check |
|
508 | + * @return bool true if the file name is valid, false otherwise |
|
509 | + * @deprecated 8.1.0 use \OC\Files\View::verifyPath() |
|
510 | + * @since 7.0.0 |
|
511 | + * @suppress PhanDeprecatedFunction |
|
512 | + */ |
|
513 | + public static function isValidFileName($file) { |
|
514 | + return \OC_Util::isValidFileName($file); |
|
515 | + } |
|
516 | + |
|
517 | + /** |
|
518 | + * Compare two strings to provide a natural sort |
|
519 | + * @param string $a first string to compare |
|
520 | + * @param string $b second string to compare |
|
521 | + * @return int -1 if $b comes before $a, 1 if $a comes before $b |
|
522 | + * or 0 if the strings are identical |
|
523 | + * @since 7.0.0 |
|
524 | + */ |
|
525 | + public static function naturalSortCompare($a, $b) { |
|
526 | + return \OC\NaturalSort::getInstance()->compare($a, $b); |
|
527 | + } |
|
528 | + |
|
529 | + /** |
|
530 | + * check if a password is required for each public link |
|
531 | + * @return boolean |
|
532 | + * @since 7.0.0 |
|
533 | + */ |
|
534 | + public static function isPublicLinkPasswordRequired() { |
|
535 | + return \OC_Util::isPublicLinkPasswordRequired(); |
|
536 | + } |
|
537 | + |
|
538 | + /** |
|
539 | + * check if share API enforces a default expire date |
|
540 | + * @return boolean |
|
541 | + * @since 8.0.0 |
|
542 | + */ |
|
543 | + public static function isDefaultExpireDateEnforced() { |
|
544 | + return \OC_Util::isDefaultExpireDateEnforced(); |
|
545 | + } |
|
546 | + |
|
547 | + protected static $needUpgradeCache = null; |
|
548 | + |
|
549 | + /** |
|
550 | + * Checks whether the current version needs upgrade. |
|
551 | + * |
|
552 | + * @return bool true if upgrade is needed, false otherwise |
|
553 | + * @since 7.0.0 |
|
554 | + */ |
|
555 | + public static function needUpgrade() { |
|
556 | + if (!isset(self::$needUpgradeCache)) { |
|
557 | + self::$needUpgradeCache=\OC_Util::needUpgrade(\OC::$server->getSystemConfig()); |
|
558 | + } |
|
559 | + return self::$needUpgradeCache; |
|
560 | + } |
|
561 | 561 | } |
@@ -36,134 +36,134 @@ |
||
36 | 36 | * https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#3-psrlogloggerinterface |
37 | 37 | */ |
38 | 38 | interface ILogger { |
39 | - /** |
|
40 | - * @since 14.0.0 |
|
41 | - */ |
|
42 | - const DEBUG=0; |
|
43 | - /** |
|
44 | - * @since 14.0.0 |
|
45 | - */ |
|
46 | - const INFO=1; |
|
47 | - /** |
|
48 | - * @since 14.0.0 |
|
49 | - */ |
|
50 | - const WARN=2; |
|
51 | - /** |
|
52 | - * @since 14.0.0 |
|
53 | - */ |
|
54 | - const ERROR=3; |
|
55 | - /** |
|
56 | - * @since 14.0.0 |
|
57 | - */ |
|
58 | - const FATAL=4; |
|
39 | + /** |
|
40 | + * @since 14.0.0 |
|
41 | + */ |
|
42 | + const DEBUG=0; |
|
43 | + /** |
|
44 | + * @since 14.0.0 |
|
45 | + */ |
|
46 | + const INFO=1; |
|
47 | + /** |
|
48 | + * @since 14.0.0 |
|
49 | + */ |
|
50 | + const WARN=2; |
|
51 | + /** |
|
52 | + * @since 14.0.0 |
|
53 | + */ |
|
54 | + const ERROR=3; |
|
55 | + /** |
|
56 | + * @since 14.0.0 |
|
57 | + */ |
|
58 | + const FATAL=4; |
|
59 | 59 | |
60 | - /** |
|
61 | - * System is unusable. |
|
62 | - * |
|
63 | - * @param string $message |
|
64 | - * @param array $context |
|
65 | - * @return null |
|
66 | - * @since 7.0.0 |
|
67 | - */ |
|
68 | - public function emergency(string $message, array $context = []); |
|
60 | + /** |
|
61 | + * System is unusable. |
|
62 | + * |
|
63 | + * @param string $message |
|
64 | + * @param array $context |
|
65 | + * @return null |
|
66 | + * @since 7.0.0 |
|
67 | + */ |
|
68 | + public function emergency(string $message, array $context = []); |
|
69 | 69 | |
70 | - /** |
|
71 | - * Action must be taken immediately. |
|
72 | - * |
|
73 | - * @param string $message |
|
74 | - * @param array $context |
|
75 | - * @return null |
|
76 | - * @since 7.0.0 |
|
77 | - */ |
|
78 | - public function alert(string $message, array $context = []); |
|
70 | + /** |
|
71 | + * Action must be taken immediately. |
|
72 | + * |
|
73 | + * @param string $message |
|
74 | + * @param array $context |
|
75 | + * @return null |
|
76 | + * @since 7.0.0 |
|
77 | + */ |
|
78 | + public function alert(string $message, array $context = []); |
|
79 | 79 | |
80 | - /** |
|
81 | - * Critical conditions. |
|
82 | - * |
|
83 | - * @param string $message |
|
84 | - * @param array $context |
|
85 | - * @return null |
|
86 | - * @since 7.0.0 |
|
87 | - */ |
|
88 | - public function critical(string $message, array $context = []); |
|
80 | + /** |
|
81 | + * Critical conditions. |
|
82 | + * |
|
83 | + * @param string $message |
|
84 | + * @param array $context |
|
85 | + * @return null |
|
86 | + * @since 7.0.0 |
|
87 | + */ |
|
88 | + public function critical(string $message, array $context = []); |
|
89 | 89 | |
90 | - /** |
|
91 | - * Runtime errors that do not require immediate action but should typically |
|
92 | - * be logged and monitored. |
|
93 | - * |
|
94 | - * @param string $message |
|
95 | - * @param array $context |
|
96 | - * @return null |
|
97 | - * @since 7.0.0 |
|
98 | - */ |
|
99 | - public function error(string $message, array $context = []); |
|
90 | + /** |
|
91 | + * Runtime errors that do not require immediate action but should typically |
|
92 | + * be logged and monitored. |
|
93 | + * |
|
94 | + * @param string $message |
|
95 | + * @param array $context |
|
96 | + * @return null |
|
97 | + * @since 7.0.0 |
|
98 | + */ |
|
99 | + public function error(string $message, array $context = []); |
|
100 | 100 | |
101 | - /** |
|
102 | - * Exceptional occurrences that are not errors. |
|
103 | - * |
|
104 | - * @param string $message |
|
105 | - * @param array $context |
|
106 | - * @return null |
|
107 | - * @since 7.0.0 |
|
108 | - */ |
|
109 | - public function warning(string $message, array $context = []); |
|
101 | + /** |
|
102 | + * Exceptional occurrences that are not errors. |
|
103 | + * |
|
104 | + * @param string $message |
|
105 | + * @param array $context |
|
106 | + * @return null |
|
107 | + * @since 7.0.0 |
|
108 | + */ |
|
109 | + public function warning(string $message, array $context = []); |
|
110 | 110 | |
111 | - /** |
|
112 | - * Normal but significant events. |
|
113 | - * |
|
114 | - * @param string $message |
|
115 | - * @param array $context |
|
116 | - * @return null |
|
117 | - * @since 7.0.0 |
|
118 | - */ |
|
119 | - public function notice(string $message, array $context = []); |
|
111 | + /** |
|
112 | + * Normal but significant events. |
|
113 | + * |
|
114 | + * @param string $message |
|
115 | + * @param array $context |
|
116 | + * @return null |
|
117 | + * @since 7.0.0 |
|
118 | + */ |
|
119 | + public function notice(string $message, array $context = []); |
|
120 | 120 | |
121 | - /** |
|
122 | - * Interesting events. |
|
123 | - * |
|
124 | - * @param string $message |
|
125 | - * @param array $context |
|
126 | - * @return null |
|
127 | - * @since 7.0.0 |
|
128 | - */ |
|
129 | - public function info(string $message, array $context = []); |
|
121 | + /** |
|
122 | + * Interesting events. |
|
123 | + * |
|
124 | + * @param string $message |
|
125 | + * @param array $context |
|
126 | + * @return null |
|
127 | + * @since 7.0.0 |
|
128 | + */ |
|
129 | + public function info(string $message, array $context = []); |
|
130 | 130 | |
131 | - /** |
|
132 | - * Detailed debug information. |
|
133 | - * |
|
134 | - * @param string $message |
|
135 | - * @param array $context |
|
136 | - * @return null |
|
137 | - * @since 7.0.0 |
|
138 | - */ |
|
139 | - public function debug(string $message, array $context = []); |
|
131 | + /** |
|
132 | + * Detailed debug information. |
|
133 | + * |
|
134 | + * @param string $message |
|
135 | + * @param array $context |
|
136 | + * @return null |
|
137 | + * @since 7.0.0 |
|
138 | + */ |
|
139 | + public function debug(string $message, array $context = []); |
|
140 | 140 | |
141 | - /** |
|
142 | - * Logs with an arbitrary level. |
|
143 | - * |
|
144 | - * @param int $level |
|
145 | - * @param string $message |
|
146 | - * @param array $context |
|
147 | - * @return mixed |
|
148 | - * @since 7.0.0 |
|
149 | - */ |
|
150 | - public function log(int $level, string $message, array $context = []); |
|
141 | + /** |
|
142 | + * Logs with an arbitrary level. |
|
143 | + * |
|
144 | + * @param int $level |
|
145 | + * @param string $message |
|
146 | + * @param array $context |
|
147 | + * @return mixed |
|
148 | + * @since 7.0.0 |
|
149 | + */ |
|
150 | + public function log(int $level, string $message, array $context = []); |
|
151 | 151 | |
152 | - /** |
|
153 | - * Logs an exception very detailed |
|
154 | - * An additional message can we written to the log by adding it to the |
|
155 | - * context. |
|
156 | - * |
|
157 | - * <code> |
|
158 | - * $logger->logException($ex, [ |
|
159 | - * 'message' => 'Exception during background job execution' |
|
160 | - * ]); |
|
161 | - * </code> |
|
162 | - * |
|
163 | - * @param \Exception|\Throwable $exception |
|
164 | - * @param array $context |
|
165 | - * @return void |
|
166 | - * @since 8.2.0 |
|
167 | - */ |
|
168 | - public function logException(\Throwable $exception, array $context = []); |
|
152 | + /** |
|
153 | + * Logs an exception very detailed |
|
154 | + * An additional message can we written to the log by adding it to the |
|
155 | + * context. |
|
156 | + * |
|
157 | + * <code> |
|
158 | + * $logger->logException($ex, [ |
|
159 | + * 'message' => 'Exception during background job execution' |
|
160 | + * ]); |
|
161 | + * </code> |
|
162 | + * |
|
163 | + * @param \Exception|\Throwable $exception |
|
164 | + * @param array $context |
|
165 | + * @return void |
|
166 | + * @since 8.2.0 |
|
167 | + */ |
|
168 | + public function logException(\Throwable $exception, array $context = []); |
|
169 | 169 | } |
@@ -32,30 +32,30 @@ |
||
32 | 32 | |
33 | 33 | $lastConfirm = (int) \OC::$server->getSession()->get('last-password-confirm'); |
34 | 34 | if ($lastConfirm < (time() - 30 * 60 + 15)) { // allow 15 seconds delay |
35 | - $l = \OC::$server->getL10N('core'); |
|
36 | - OC_JSON::error(array( 'data' => array( 'message' => $l->t('Password confirmation is required')))); |
|
37 | - exit(); |
|
35 | + $l = \OC::$server->getL10N('core'); |
|
36 | + OC_JSON::error(array( 'data' => array( 'message' => $l->t('Password confirmation is required')))); |
|
37 | + exit(); |
|
38 | 38 | } |
39 | 39 | |
40 | 40 | $groups = isset($_POST['groups']) ? (array)$_POST['groups'] : []; |
41 | 41 | $appIds = isset($_POST['appIds']) ? (array)$_POST['appIds'] : []; |
42 | 42 | |
43 | 43 | try { |
44 | - $updateRequired = false; |
|
45 | - foreach($appIds as $appId) { |
|
46 | - $app = new OC_App(); |
|
47 | - $appId = OC_App::cleanAppId($appId); |
|
48 | - $app->enable($appId, $groups); |
|
49 | - if(\OC_App::shouldUpgrade($appId)) { |
|
50 | - $updateRequired = true; |
|
51 | - } |
|
52 | - } |
|
44 | + $updateRequired = false; |
|
45 | + foreach($appIds as $appId) { |
|
46 | + $app = new OC_App(); |
|
47 | + $appId = OC_App::cleanAppId($appId); |
|
48 | + $app->enable($appId, $groups); |
|
49 | + if(\OC_App::shouldUpgrade($appId)) { |
|
50 | + $updateRequired = true; |
|
51 | + } |
|
52 | + } |
|
53 | 53 | |
54 | - OC_JSON::success(['data' => ['update_required' => $updateRequired]]); |
|
54 | + OC_JSON::success(['data' => ['update_required' => $updateRequired]]); |
|
55 | 55 | } catch (Exception $e) { |
56 | - \OC::$server->getLogger()->logException($e, [ |
|
57 | - 'level' => ILogger::DEBUG, |
|
58 | - 'app' => 'core', |
|
59 | - ]); |
|
60 | - OC_JSON::error(array("data" => array("message" => $e->getMessage()) )); |
|
56 | + \OC::$server->getLogger()->logException($e, [ |
|
57 | + 'level' => ILogger::DEBUG, |
|
58 | + 'app' => 'core', |
|
59 | + ]); |
|
60 | + OC_JSON::error(array("data" => array("message" => $e->getMessage()) )); |
|
61 | 61 | } |
@@ -71,948 +71,948 @@ |
||
71 | 71 | * @package OC\Settings\Controller |
72 | 72 | */ |
73 | 73 | class UsersController extends Controller { |
74 | - /** @var IL10N */ |
|
75 | - private $l10n; |
|
76 | - /** @var IUserSession */ |
|
77 | - private $userSession; |
|
78 | - /** @var bool */ |
|
79 | - private $isAdmin; |
|
80 | - /** @var IUserManager */ |
|
81 | - private $userManager; |
|
82 | - /** @var IGroupManager */ |
|
83 | - private $groupManager; |
|
84 | - /** @var IConfig */ |
|
85 | - private $config; |
|
86 | - /** @var ILogger */ |
|
87 | - private $log; |
|
88 | - /** @var IMailer */ |
|
89 | - private $mailer; |
|
90 | - /** @var bool contains the state of the encryption app */ |
|
91 | - private $isEncryptionAppEnabled; |
|
92 | - /** @var bool contains the state of the admin recovery setting */ |
|
93 | - private $isRestoreEnabled = false; |
|
94 | - /** @var IAppManager */ |
|
95 | - private $appManager; |
|
96 | - /** @var IAvatarManager */ |
|
97 | - private $avatarManager; |
|
98 | - /** @var AccountManager */ |
|
99 | - private $accountManager; |
|
100 | - /** @var ISecureRandom */ |
|
101 | - private $secureRandom; |
|
102 | - /** @var NewUserMailHelper */ |
|
103 | - private $newUserMailHelper; |
|
104 | - /** @var Manager */ |
|
105 | - private $keyManager; |
|
106 | - /** @var IJobList */ |
|
107 | - private $jobList; |
|
108 | - |
|
109 | - /** @var IUserMountCache */ |
|
110 | - private $userMountCache; |
|
111 | - |
|
112 | - /** @var IManager */ |
|
113 | - private $encryptionManager; |
|
114 | - |
|
115 | - public function __construct(string $appName, |
|
116 | - IRequest $request, |
|
117 | - IUserManager $userManager, |
|
118 | - IGroupManager $groupManager, |
|
119 | - IUserSession $userSession, |
|
120 | - IConfig $config, |
|
121 | - bool $isAdmin, |
|
122 | - IL10N $l10n, |
|
123 | - ILogger $log, |
|
124 | - IMailer $mailer, |
|
125 | - IURLGenerator $urlGenerator, |
|
126 | - IAppManager $appManager, |
|
127 | - IAvatarManager $avatarManager, |
|
128 | - AccountManager $accountManager, |
|
129 | - ISecureRandom $secureRandom, |
|
130 | - NewUserMailHelper $newUserMailHelper, |
|
131 | - Manager $keyManager, |
|
132 | - IJobList $jobList, |
|
133 | - IUserMountCache $userMountCache, |
|
134 | - IManager $encryptionManager) { |
|
135 | - parent::__construct($appName, $request); |
|
136 | - $this->userManager = $userManager; |
|
137 | - $this->groupManager = $groupManager; |
|
138 | - $this->userSession = $userSession; |
|
139 | - $this->config = $config; |
|
140 | - $this->isAdmin = $isAdmin; |
|
141 | - $this->l10n = $l10n; |
|
142 | - $this->log = $log; |
|
143 | - $this->mailer = $mailer; |
|
144 | - $this->appManager = $appManager; |
|
145 | - $this->avatarManager = $avatarManager; |
|
146 | - $this->accountManager = $accountManager; |
|
147 | - $this->secureRandom = $secureRandom; |
|
148 | - $this->newUserMailHelper = $newUserMailHelper; |
|
149 | - $this->keyManager = $keyManager; |
|
150 | - $this->jobList = $jobList; |
|
151 | - $this->userMountCache = $userMountCache; |
|
152 | - $this->encryptionManager = $encryptionManager; |
|
153 | - |
|
154 | - // check for encryption state - TODO see formatUserForIndex |
|
155 | - $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption'); |
|
156 | - if ($this->isEncryptionAppEnabled) { |
|
157 | - // putting this directly in empty is possible in PHP 5.5+ |
|
158 | - $result = $config->getAppValue('encryption', 'recoveryAdminEnabled', '0'); |
|
159 | - $this->isRestoreEnabled = !empty($result); |
|
160 | - } |
|
161 | - } |
|
162 | - |
|
163 | - /** |
|
164 | - * @param IUser $user |
|
165 | - * @param array|null $userGroups |
|
166 | - * @return array |
|
167 | - */ |
|
168 | - private function formatUserForIndex(IUser $user, array $userGroups = null): array { |
|
169 | - |
|
170 | - // TODO: eliminate this encryption specific code below and somehow |
|
171 | - // hook in additional user info from other apps |
|
172 | - |
|
173 | - // recovery isn't possible if admin or user has it disabled and encryption |
|
174 | - // is enabled - so we eliminate the else paths in the conditional tree |
|
175 | - // below |
|
176 | - $restorePossible = false; |
|
177 | - |
|
178 | - if ($this->isEncryptionAppEnabled) { |
|
179 | - if ($this->isRestoreEnabled) { |
|
180 | - // check for the users recovery setting |
|
181 | - $recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0'); |
|
182 | - // method call inside empty is possible with PHP 5.5+ |
|
183 | - $recoveryModeEnabled = !empty($recoveryMode); |
|
184 | - if ($recoveryModeEnabled) { |
|
185 | - // user also has recovery mode enabled |
|
186 | - $restorePossible = true; |
|
187 | - } |
|
188 | - } else { |
|
189 | - $modules = $this->encryptionManager->getEncryptionModules(); |
|
190 | - $restorePossible = true; |
|
191 | - foreach ($modules as $id => $module) { |
|
192 | - /* @var IEncryptionModule $instance */ |
|
193 | - $instance = call_user_func($module['callback']); |
|
194 | - if ($instance->needDetailedAccessList()) { |
|
195 | - $restorePossible = false; |
|
196 | - break; |
|
197 | - } |
|
198 | - } |
|
199 | - } |
|
200 | - } else { |
|
201 | - // recovery is possible if encryption is disabled (plain files are |
|
202 | - // available) |
|
203 | - $restorePossible = true; |
|
204 | - } |
|
205 | - |
|
206 | - $subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroupsName($user); |
|
207 | - |
|
208 | - $displayName = $user->getEMailAddress(); |
|
209 | - if (is_null($displayName)) { |
|
210 | - $displayName = ''; |
|
211 | - } |
|
212 | - |
|
213 | - $avatarAvailable = false; |
|
214 | - try { |
|
215 | - $avatarAvailable = $this->avatarManager->getAvatar($user->getUID())->exists(); |
|
216 | - } catch (\Exception $e) { |
|
217 | - //No avatar yet |
|
218 | - } |
|
219 | - |
|
220 | - return [ |
|
221 | - 'name' => $user->getUID(), |
|
222 | - 'displayname' => $user->getDisplayName(), |
|
223 | - 'groups' => empty($userGroups) ? $this->groupManager->getUserGroupNames($user) : $userGroups, |
|
224 | - 'subadmin' => $subAdminGroups, |
|
225 | - 'quota' => $user->getQuota(), |
|
226 | - 'quota_bytes' => Util::computerFileSize($user->getQuota()), |
|
227 | - 'storageLocation' => $user->getHome(), |
|
228 | - 'lastLogin' => $user->getLastLogin() * 1000, |
|
229 | - 'backend' => $user->getBackendClassName(), |
|
230 | - 'email' => $displayName, |
|
231 | - 'isRestoreDisabled' => !$restorePossible, |
|
232 | - 'isAvatarAvailable' => $avatarAvailable, |
|
233 | - 'isEnabled' => $user->isEnabled(), |
|
234 | - ]; |
|
235 | - } |
|
236 | - |
|
237 | - /** |
|
238 | - * @param array $userIDs Array with schema [$uid => $displayName] |
|
239 | - * @return IUser[] |
|
240 | - */ |
|
241 | - private function getUsersForUID(array $userIDs): array { |
|
242 | - $users = []; |
|
243 | - foreach ($userIDs as $uid => $displayName) { |
|
244 | - $users[$uid] = $this->userManager->get($uid); |
|
245 | - } |
|
246 | - return $users; |
|
247 | - } |
|
248 | - |
|
249 | - /** |
|
250 | - * @NoAdminRequired |
|
251 | - * |
|
252 | - * @param int $offset |
|
253 | - * @param int $limit |
|
254 | - * @param string $gid GID to filter for |
|
255 | - * @param string $pattern Pattern to search for in the username |
|
256 | - * @param string $backend Backend to filter for (class-name) |
|
257 | - * @return DataResponse |
|
258 | - * |
|
259 | - * TODO: Tidy up and write unit tests - code is mainly static method calls |
|
260 | - */ |
|
261 | - public function index(int $offset = 0, int $limit = 10, string $gid = '', string $pattern = '', string $backend = ''): DataResponse { |
|
262 | - // Remove backends |
|
263 | - if (!empty($backend)) { |
|
264 | - $activeBackends = $this->userManager->getBackends(); |
|
265 | - $this->userManager->clearBackends(); |
|
266 | - foreach ($activeBackends as $singleActiveBackend) { |
|
267 | - if ($backend === get_class($singleActiveBackend)) { |
|
268 | - $this->userManager->registerBackend($singleActiveBackend); |
|
269 | - break; |
|
270 | - } |
|
271 | - } |
|
272 | - } |
|
273 | - |
|
274 | - $userObjects = []; |
|
275 | - $users = []; |
|
276 | - if ($this->isAdmin) { |
|
277 | - if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') { |
|
278 | - $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset)); |
|
279 | - } else { |
|
280 | - $batch = $this->userManager->search($pattern, $limit, $offset); |
|
281 | - } |
|
282 | - |
|
283 | - foreach ($batch as $user) { |
|
284 | - if (($gid !== '_disabledUsers' && $user->isEnabled()) || |
|
285 | - ($gid === '_disabledUsers' && !$user->isEnabled()) |
|
286 | - ) { |
|
287 | - $userObjects[] = $user; |
|
288 | - $users[] = $this->formatUserForIndex($user); |
|
289 | - } |
|
290 | - } |
|
291 | - |
|
292 | - } else { |
|
293 | - $subAdminOfGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser()); |
|
294 | - // New class returns IGroup[] so convert back |
|
295 | - $gids = []; |
|
296 | - foreach ($subAdminOfGroups as $group) { |
|
297 | - $gids[] = $group->getGID(); |
|
298 | - } |
|
299 | - $subAdminOfGroups = $gids; |
|
300 | - |
|
301 | - // Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group |
|
302 | - if ($gid !== '' && $gid !== '_disabledUsers' && !in_array($gid, $subAdminOfGroups)) { |
|
303 | - $gid = ''; |
|
304 | - } |
|
305 | - |
|
306 | - // Batch all groups the user is subadmin of when a group is specified |
|
307 | - $batch = []; |
|
308 | - if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') { |
|
309 | - $batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset); |
|
310 | - } else { |
|
311 | - foreach ($subAdminOfGroups as $group) { |
|
312 | - $groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset); |
|
313 | - |
|
314 | - foreach ($groupUsers as $uid => $displayName) { |
|
315 | - $batch[$uid] = $displayName; |
|
316 | - } |
|
317 | - } |
|
318 | - } |
|
319 | - $batch = $this->getUsersForUID($batch); |
|
320 | - |
|
321 | - foreach ($batch as $user) { |
|
322 | - // Only add the groups, this user is a subadmin of |
|
323 | - $userGroups = array_values(array_intersect( |
|
324 | - $this->groupManager->getUserGroupIds($user), |
|
325 | - $subAdminOfGroups |
|
326 | - )); |
|
327 | - if (($gid !== '_disabledUsers' && $user->isEnabled()) || |
|
328 | - ($gid === '_disabledUsers' && !$user->isEnabled()) |
|
329 | - ) { |
|
330 | - $userObjects[] = $user; |
|
331 | - $users[] = $this->formatUserForIndex($user, $userGroups); |
|
332 | - } |
|
333 | - } |
|
334 | - } |
|
335 | - |
|
336 | - $usedSpace = $this->userMountCache->getUsedSpaceForUsers($userObjects); |
|
337 | - |
|
338 | - foreach ($users as &$userData) { |
|
339 | - $userData['size'] = isset($usedSpace[$userData['name']]) ? $usedSpace[$userData['name']] : 0; |
|
340 | - } |
|
341 | - |
|
342 | - return new DataResponse($users); |
|
343 | - } |
|
344 | - |
|
345 | - /** |
|
346 | - * @NoAdminRequired |
|
347 | - * @PasswordConfirmationRequired |
|
348 | - * |
|
349 | - * @param string $username |
|
350 | - * @param string $password |
|
351 | - * @param array $groups |
|
352 | - * @param string $email |
|
353 | - * @return DataResponse |
|
354 | - */ |
|
355 | - public function create(string $username, string $password, array $groups = [], $email = ''): DataResponse { |
|
356 | - if ($email !== '' && !$this->mailer->validateMailAddress($email)) { |
|
357 | - return new DataResponse( |
|
358 | - [ |
|
359 | - 'message' => $this->l10n->t('Invalid mail address') |
|
360 | - ], |
|
361 | - Http::STATUS_UNPROCESSABLE_ENTITY |
|
362 | - ); |
|
363 | - } |
|
364 | - |
|
365 | - $currentUser = $this->userSession->getUser(); |
|
366 | - |
|
367 | - if (!$this->isAdmin) { |
|
368 | - if (!empty($groups)) { |
|
369 | - foreach ($groups as $key => $group) { |
|
370 | - $groupObject = $this->groupManager->get($group); |
|
371 | - if ($groupObject === null) { |
|
372 | - unset($groups[$key]); |
|
373 | - continue; |
|
374 | - } |
|
375 | - |
|
376 | - if (!$this->groupManager->getSubAdmin()->isSubAdminOfGroup($currentUser, $groupObject)) { |
|
377 | - unset($groups[$key]); |
|
378 | - } |
|
379 | - } |
|
380 | - } |
|
381 | - |
|
382 | - if (empty($groups)) { |
|
383 | - return new DataResponse( |
|
384 | - [ |
|
385 | - 'message' => $this->l10n->t('No valid group selected'), |
|
386 | - ], |
|
387 | - Http::STATUS_FORBIDDEN |
|
388 | - ); |
|
389 | - } |
|
390 | - } |
|
391 | - |
|
392 | - if ($this->userManager->userExists($username)) { |
|
393 | - return new DataResponse( |
|
394 | - [ |
|
395 | - 'message' => $this->l10n->t('A user with that name already exists.') |
|
396 | - ], |
|
397 | - Http::STATUS_CONFLICT |
|
398 | - ); |
|
399 | - } |
|
400 | - |
|
401 | - $generatePasswordResetToken = false; |
|
402 | - if ($password === '') { |
|
403 | - if ($email === '') { |
|
404 | - return new DataResponse( |
|
405 | - [ |
|
406 | - 'message' => $this->l10n->t('To send a password link to the user an email address is required.') |
|
407 | - ], |
|
408 | - Http::STATUS_UNPROCESSABLE_ENTITY |
|
409 | - ); |
|
410 | - } |
|
411 | - |
|
412 | - $password = $this->secureRandom->generate(30); |
|
413 | - // Make sure we pass the password_policy |
|
414 | - $password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()'); |
|
415 | - $generatePasswordResetToken = true; |
|
416 | - } |
|
417 | - |
|
418 | - try { |
|
419 | - $user = $this->userManager->createUser($username, $password); |
|
420 | - } catch (\Exception $exception) { |
|
421 | - $message = $exception->getMessage(); |
|
422 | - if ($exception instanceof HintException && $exception->getHint()) { |
|
423 | - $message = $exception->getHint(); |
|
424 | - } |
|
425 | - if (!$message) { |
|
426 | - $message = $this->l10n->t('Unable to create user.'); |
|
427 | - } |
|
428 | - return new DataResponse( |
|
429 | - [ |
|
430 | - 'message' => (string)$message, |
|
431 | - ], |
|
432 | - Http::STATUS_FORBIDDEN |
|
433 | - ); |
|
434 | - } |
|
435 | - |
|
436 | - if ($user instanceof IUser) { |
|
437 | - if ($groups !== null) { |
|
438 | - foreach ($groups as $groupName) { |
|
439 | - $group = $this->groupManager->get($groupName); |
|
440 | - |
|
441 | - if (empty($group)) { |
|
442 | - $group = $this->groupManager->createGroup($groupName); |
|
443 | - } |
|
444 | - $group->addUser($user); |
|
445 | - } |
|
446 | - } |
|
447 | - /** |
|
448 | - * Send new user mail only if a mail is set |
|
449 | - */ |
|
450 | - if ($email !== '') { |
|
451 | - $user->setEMailAddress($email); |
|
452 | - try { |
|
453 | - $emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken); |
|
454 | - $this->newUserMailHelper->sendMail($user, $emailTemplate); |
|
455 | - } catch (\Exception $e) { |
|
456 | - $this->log->logException($e, [ |
|
457 | - 'message' => "Can't send new user mail to $email", |
|
458 | - 'level' => ILogger::ERROR, |
|
459 | - 'app' => 'settings', |
|
460 | - ]); |
|
461 | - } |
|
462 | - } |
|
463 | - // fetch users groups |
|
464 | - $userGroups = $this->groupManager->getUserGroupNames($user); |
|
465 | - |
|
466 | - return new DataResponse( |
|
467 | - $this->formatUserForIndex($user, $userGroups), |
|
468 | - Http::STATUS_CREATED |
|
469 | - ); |
|
470 | - } |
|
471 | - |
|
472 | - return new DataResponse( |
|
473 | - [ |
|
474 | - 'message' => $this->l10n->t('Unable to create user.') |
|
475 | - ], |
|
476 | - Http::STATUS_FORBIDDEN |
|
477 | - ); |
|
478 | - |
|
479 | - } |
|
480 | - |
|
481 | - /** |
|
482 | - * @NoAdminRequired |
|
483 | - * @PasswordConfirmationRequired |
|
484 | - * |
|
485 | - * @param string $id |
|
486 | - * @return DataResponse |
|
487 | - */ |
|
488 | - public function destroy(string $id): DataResponse { |
|
489 | - $userId = $this->userSession->getUser()->getUID(); |
|
490 | - $user = $this->userManager->get($id); |
|
491 | - |
|
492 | - if ($userId === $id) { |
|
493 | - return new DataResponse( |
|
494 | - [ |
|
495 | - 'status' => 'error', |
|
496 | - 'data' => [ |
|
497 | - 'message' => $this->l10n->t('Unable to delete user.') |
|
498 | - ] |
|
499 | - ], |
|
500 | - Http::STATUS_FORBIDDEN |
|
501 | - ); |
|
502 | - } |
|
503 | - |
|
504 | - if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) { |
|
505 | - return new DataResponse( |
|
506 | - [ |
|
507 | - 'status' => 'error', |
|
508 | - 'data' => [ |
|
509 | - 'message' => $this->l10n->t('Authentication error') |
|
510 | - ] |
|
511 | - ], |
|
512 | - Http::STATUS_FORBIDDEN |
|
513 | - ); |
|
514 | - } |
|
515 | - |
|
516 | - if ($user && $user->delete()) { |
|
517 | - return new DataResponse( |
|
518 | - [ |
|
519 | - 'status' => 'success', |
|
520 | - 'data' => [ |
|
521 | - 'username' => $id |
|
522 | - ] |
|
523 | - ], |
|
524 | - Http::STATUS_NO_CONTENT |
|
525 | - ); |
|
526 | - } |
|
527 | - |
|
528 | - return new DataResponse( |
|
529 | - [ |
|
530 | - 'status' => 'error', |
|
531 | - 'data' => [ |
|
532 | - 'message' => $this->l10n->t('Unable to delete user.') |
|
533 | - ] |
|
534 | - ], |
|
535 | - Http::STATUS_FORBIDDEN |
|
536 | - ); |
|
537 | - } |
|
538 | - |
|
539 | - /** |
|
540 | - * @NoAdminRequired |
|
541 | - * |
|
542 | - * @param string $id |
|
543 | - * @param int $enabled |
|
544 | - * @return DataResponse |
|
545 | - */ |
|
546 | - public function setEnabled(string $id, int $enabled): DataResponse { |
|
547 | - $enabled = (bool)$enabled; |
|
548 | - if ($enabled) { |
|
549 | - $errorMsgGeneral = $this->l10n->t('Error while enabling user.'); |
|
550 | - } else { |
|
551 | - $errorMsgGeneral = $this->l10n->t('Error while disabling user.'); |
|
552 | - } |
|
553 | - |
|
554 | - $userId = $this->userSession->getUser()->getUID(); |
|
555 | - $user = $this->userManager->get($id); |
|
556 | - |
|
557 | - if ($userId === $id) { |
|
558 | - return new DataResponse( |
|
559 | - [ |
|
560 | - 'status' => 'error', |
|
561 | - 'data' => [ |
|
562 | - 'message' => $errorMsgGeneral |
|
563 | - ] |
|
564 | - ], Http::STATUS_FORBIDDEN |
|
565 | - ); |
|
566 | - } |
|
567 | - |
|
568 | - if ($user) { |
|
569 | - if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) { |
|
570 | - return new DataResponse( |
|
571 | - [ |
|
572 | - 'status' => 'error', |
|
573 | - 'data' => [ |
|
574 | - 'message' => $this->l10n->t('Authentication error') |
|
575 | - ] |
|
576 | - ], |
|
577 | - Http::STATUS_FORBIDDEN |
|
578 | - ); |
|
579 | - } |
|
580 | - |
|
581 | - $user->setEnabled($enabled); |
|
582 | - return new DataResponse( |
|
583 | - [ |
|
584 | - 'status' => 'success', |
|
585 | - 'data' => [ |
|
586 | - 'username' => $id, |
|
587 | - 'enabled' => $enabled |
|
588 | - ] |
|
589 | - ] |
|
590 | - ); |
|
591 | - } else { |
|
592 | - return new DataResponse( |
|
593 | - [ |
|
594 | - 'status' => 'error', |
|
595 | - 'data' => [ |
|
596 | - 'message' => $errorMsgGeneral |
|
597 | - ] |
|
598 | - ], |
|
599 | - Http::STATUS_FORBIDDEN |
|
600 | - ); |
|
601 | - } |
|
602 | - |
|
603 | - } |
|
604 | - |
|
605 | - /** |
|
606 | - * Set the mail address of a user |
|
607 | - * |
|
608 | - * @NoAdminRequired |
|
609 | - * @NoSubadminRequired |
|
610 | - * @PasswordConfirmationRequired |
|
611 | - * |
|
612 | - * @param string $account |
|
613 | - * @param bool $onlyVerificationCode only return verification code without updating the data |
|
614 | - * @return DataResponse |
|
615 | - */ |
|
616 | - public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse { |
|
617 | - |
|
618 | - $user = $this->userSession->getUser(); |
|
619 | - |
|
620 | - if ($user === null) { |
|
621 | - return new DataResponse([], Http::STATUS_BAD_REQUEST); |
|
622 | - } |
|
623 | - |
|
624 | - $accountData = $this->accountManager->getUser($user); |
|
625 | - $cloudId = $user->getCloudId(); |
|
626 | - $message = 'Use my Federated Cloud ID to share with me: ' . $cloudId; |
|
627 | - $signature = $this->signMessage($user, $message); |
|
628 | - |
|
629 | - $code = $message . ' ' . $signature; |
|
630 | - $codeMd5 = $message . ' ' . md5($signature); |
|
631 | - |
|
632 | - switch ($account) { |
|
633 | - case 'verify-twitter': |
|
634 | - $accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS; |
|
635 | - $msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):'); |
|
636 | - $code = $codeMd5; |
|
637 | - $type = AccountManager::PROPERTY_TWITTER; |
|
638 | - $data = $accountData[AccountManager::PROPERTY_TWITTER]['value']; |
|
639 | - $accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature; |
|
640 | - break; |
|
641 | - case 'verify-website': |
|
642 | - $accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS; |
|
643 | - $msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):'); |
|
644 | - $type = AccountManager::PROPERTY_WEBSITE; |
|
645 | - $data = $accountData[AccountManager::PROPERTY_WEBSITE]['value']; |
|
646 | - $accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature; |
|
647 | - break; |
|
648 | - default: |
|
649 | - return new DataResponse([], Http::STATUS_BAD_REQUEST); |
|
650 | - } |
|
651 | - |
|
652 | - if ($onlyVerificationCode === false) { |
|
653 | - $this->accountManager->updateUser($user, $accountData); |
|
654 | - |
|
655 | - $this->jobList->add(VerifyUserData::class, |
|
656 | - [ |
|
657 | - 'verificationCode' => $code, |
|
658 | - 'data' => $data, |
|
659 | - 'type' => $type, |
|
660 | - 'uid' => $user->getUID(), |
|
661 | - 'try' => 0, |
|
662 | - 'lastRun' => $this->getCurrentTime() |
|
663 | - ] |
|
664 | - ); |
|
665 | - } |
|
666 | - |
|
667 | - return new DataResponse(['msg' => $msg, 'code' => $code]); |
|
668 | - } |
|
669 | - |
|
670 | - /** |
|
671 | - * get current timestamp |
|
672 | - * |
|
673 | - * @return int |
|
674 | - */ |
|
675 | - protected function getCurrentTime(): int { |
|
676 | - return time(); |
|
677 | - } |
|
678 | - |
|
679 | - /** |
|
680 | - * sign message with users private key |
|
681 | - * |
|
682 | - * @param IUser $user |
|
683 | - * @param string $message |
|
684 | - * |
|
685 | - * @return string base64 encoded signature |
|
686 | - */ |
|
687 | - protected function signMessage(IUser $user, string $message): string { |
|
688 | - $privateKey = $this->keyManager->getKey($user)->getPrivate(); |
|
689 | - openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512); |
|
690 | - return base64_encode($signature); |
|
691 | - } |
|
692 | - |
|
693 | - /** |
|
694 | - * @NoAdminRequired |
|
695 | - * @NoSubadminRequired |
|
696 | - * @PasswordConfirmationRequired |
|
697 | - * |
|
698 | - * @param string $avatarScope |
|
699 | - * @param string $displayname |
|
700 | - * @param string $displaynameScope |
|
701 | - * @param string $phone |
|
702 | - * @param string $phoneScope |
|
703 | - * @param string $email |
|
704 | - * @param string $emailScope |
|
705 | - * @param string $website |
|
706 | - * @param string $websiteScope |
|
707 | - * @param string $address |
|
708 | - * @param string $addressScope |
|
709 | - * @param string $twitter |
|
710 | - * @param string $twitterScope |
|
711 | - * @return DataResponse |
|
712 | - */ |
|
713 | - public function setUserSettings($avatarScope, |
|
714 | - $displayname, |
|
715 | - $displaynameScope, |
|
716 | - $phone, |
|
717 | - $phoneScope, |
|
718 | - $email, |
|
719 | - $emailScope, |
|
720 | - $website, |
|
721 | - $websiteScope, |
|
722 | - $address, |
|
723 | - $addressScope, |
|
724 | - $twitter, |
|
725 | - $twitterScope |
|
726 | - ) { |
|
727 | - |
|
728 | - if (!empty($email) && !$this->mailer->validateMailAddress($email)) { |
|
729 | - return new DataResponse( |
|
730 | - [ |
|
731 | - 'status' => 'error', |
|
732 | - 'data' => [ |
|
733 | - 'message' => $this->l10n->t('Invalid mail address') |
|
734 | - ] |
|
735 | - ], |
|
736 | - Http::STATUS_UNPROCESSABLE_ENTITY |
|
737 | - ); |
|
738 | - } |
|
739 | - |
|
740 | - $user = $this->userSession->getUser(); |
|
741 | - |
|
742 | - $data = $this->accountManager->getUser($user); |
|
743 | - |
|
744 | - $data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope]; |
|
745 | - if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) { |
|
746 | - $data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope]; |
|
747 | - $data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope]; |
|
748 | - } |
|
749 | - |
|
750 | - if ($this->appManager->isEnabledForUser('federatedfilesharing')) { |
|
751 | - $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application(); |
|
752 | - $shareProvider = $federatedFileSharing->getFederatedShareProvider(); |
|
753 | - if ($shareProvider->isLookupServerUploadEnabled()) { |
|
754 | - $data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope]; |
|
755 | - $data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope]; |
|
756 | - $data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope]; |
|
757 | - $data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope]; |
|
758 | - } |
|
759 | - } |
|
760 | - |
|
761 | - try { |
|
762 | - $this->saveUserSettings($user, $data); |
|
763 | - return new DataResponse( |
|
764 | - [ |
|
765 | - 'status' => 'success', |
|
766 | - 'data' => [ |
|
767 | - 'userId' => $user->getUID(), |
|
768 | - 'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'], |
|
769 | - 'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'], |
|
770 | - 'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'], |
|
771 | - 'email' => $data[AccountManager::PROPERTY_EMAIL]['value'], |
|
772 | - 'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'], |
|
773 | - 'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'], |
|
774 | - 'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'], |
|
775 | - 'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'], |
|
776 | - 'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'], |
|
777 | - 'message' => $this->l10n->t('Settings saved') |
|
778 | - ] |
|
779 | - ], |
|
780 | - Http::STATUS_OK |
|
781 | - ); |
|
782 | - } catch (ForbiddenException $e) { |
|
783 | - return new DataResponse([ |
|
784 | - 'status' => 'error', |
|
785 | - 'data' => [ |
|
786 | - 'message' => $e->getMessage() |
|
787 | - ], |
|
788 | - ]); |
|
789 | - } |
|
790 | - |
|
791 | - } |
|
792 | - |
|
793 | - |
|
794 | - /** |
|
795 | - * update account manager with new user data |
|
796 | - * |
|
797 | - * @param IUser $user |
|
798 | - * @param array $data |
|
799 | - * @throws ForbiddenException |
|
800 | - */ |
|
801 | - protected function saveUserSettings(IUser $user, array $data) { |
|
802 | - |
|
803 | - // keep the user back-end up-to-date with the latest display name and email |
|
804 | - // address |
|
805 | - $oldDisplayName = $user->getDisplayName(); |
|
806 | - $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName; |
|
807 | - if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value']) |
|
808 | - && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value'] |
|
809 | - ) { |
|
810 | - $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']); |
|
811 | - if ($result === false) { |
|
812 | - throw new ForbiddenException($this->l10n->t('Unable to change full name')); |
|
813 | - } |
|
814 | - } |
|
815 | - |
|
816 | - $oldEmailAddress = $user->getEMailAddress(); |
|
817 | - $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress; |
|
818 | - if (isset($data[AccountManager::PROPERTY_EMAIL]['value']) |
|
819 | - && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value'] |
|
820 | - ) { |
|
821 | - // this is the only permission a backend provides and is also used |
|
822 | - // for the permission of setting a email address |
|
823 | - if (!$user->canChangeDisplayName()) { |
|
824 | - throw new ForbiddenException($this->l10n->t('Unable to change email address')); |
|
825 | - } |
|
826 | - $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']); |
|
827 | - } |
|
828 | - |
|
829 | - $this->accountManager->updateUser($user, $data); |
|
830 | - } |
|
831 | - |
|
832 | - /** |
|
833 | - * Count all unique users visible for the current admin/subadmin. |
|
834 | - * |
|
835 | - * @NoAdminRequired |
|
836 | - * |
|
837 | - * @return DataResponse |
|
838 | - */ |
|
839 | - public function stats(): DataResponse { |
|
840 | - $userCount = 0; |
|
841 | - if ($this->isAdmin) { |
|
842 | - $countByBackend = $this->userManager->countUsers(); |
|
843 | - |
|
844 | - if (!empty($countByBackend)) { |
|
845 | - foreach ($countByBackend as $count) { |
|
846 | - $userCount += $count; |
|
847 | - } |
|
848 | - } |
|
849 | - } else { |
|
850 | - $groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser()); |
|
851 | - |
|
852 | - $uniqueUsers = []; |
|
853 | - foreach ($groups as $group) { |
|
854 | - foreach ($group->getUsers() as $uid => $displayName) { |
|
855 | - $uniqueUsers[$uid] = true; |
|
856 | - } |
|
857 | - } |
|
858 | - |
|
859 | - $userCount = count($uniqueUsers); |
|
860 | - } |
|
861 | - |
|
862 | - return new DataResponse( |
|
863 | - [ |
|
864 | - 'totalUsers' => $userCount |
|
865 | - ] |
|
866 | - ); |
|
867 | - } |
|
868 | - |
|
869 | - |
|
870 | - /** |
|
871 | - * Set the displayName of a user |
|
872 | - * |
|
873 | - * @NoAdminRequired |
|
874 | - * @NoSubadminRequired |
|
875 | - * @PasswordConfirmationRequired |
|
876 | - * @todo merge into saveUserSettings |
|
877 | - * |
|
878 | - * @param string $username |
|
879 | - * @param string $displayName |
|
880 | - * @return DataResponse |
|
881 | - */ |
|
882 | - public function setDisplayName(string $username, string $displayName) { |
|
883 | - $currentUser = $this->userSession->getUser(); |
|
884 | - $user = $this->userManager->get($username); |
|
885 | - |
|
886 | - if ($user === null || |
|
887 | - !$user->canChangeDisplayName() || |
|
888 | - ( |
|
889 | - !$this->groupManager->isAdmin($currentUser->getUID()) && |
|
890 | - !$this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $user) && |
|
891 | - $currentUser->getUID() !== $username |
|
892 | - |
|
893 | - ) |
|
894 | - ) { |
|
895 | - return new DataResponse([ |
|
896 | - 'status' => 'error', |
|
897 | - 'data' => [ |
|
898 | - 'message' => $this->l10n->t('Authentication error'), |
|
899 | - ], |
|
900 | - ]); |
|
901 | - } |
|
902 | - |
|
903 | - $userData = $this->accountManager->getUser($user); |
|
904 | - $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $displayName; |
|
905 | - |
|
906 | - |
|
907 | - try { |
|
908 | - $this->saveUserSettings($user, $userData); |
|
909 | - return new DataResponse([ |
|
910 | - 'status' => 'success', |
|
911 | - 'data' => [ |
|
912 | - 'message' => $this->l10n->t('Your full name has been changed.'), |
|
913 | - 'username' => $username, |
|
914 | - 'displayName' => $displayName, |
|
915 | - ], |
|
916 | - ]); |
|
917 | - } catch (ForbiddenException $e) { |
|
918 | - return new DataResponse([ |
|
919 | - 'status' => 'error', |
|
920 | - 'data' => [ |
|
921 | - 'message' => $e->getMessage(), |
|
922 | - 'displayName' => $user->getDisplayName(), |
|
923 | - ], |
|
924 | - ]); |
|
925 | - } |
|
926 | - } |
|
927 | - |
|
928 | - /** |
|
929 | - * Set the mail address of a user |
|
930 | - * |
|
931 | - * @NoAdminRequired |
|
932 | - * @NoSubadminRequired |
|
933 | - * @PasswordConfirmationRequired |
|
934 | - * |
|
935 | - * @param string $id |
|
936 | - * @param string $mailAddress |
|
937 | - * @return DataResponse |
|
938 | - */ |
|
939 | - public function setEMailAddress(string $id, string $mailAddress) { |
|
940 | - $user = $this->userManager->get($id); |
|
941 | - if (!$this->isAdmin |
|
942 | - && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user) |
|
943 | - ) { |
|
944 | - return new DataResponse( |
|
945 | - [ |
|
946 | - 'status' => 'error', |
|
947 | - 'data' => [ |
|
948 | - 'message' => $this->l10n->t('Forbidden') |
|
949 | - ] |
|
950 | - ], |
|
951 | - Http::STATUS_FORBIDDEN |
|
952 | - ); |
|
953 | - } |
|
954 | - |
|
955 | - if ($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) { |
|
956 | - return new DataResponse( |
|
957 | - [ |
|
958 | - 'status' => 'error', |
|
959 | - 'data' => [ |
|
960 | - 'message' => $this->l10n->t('Invalid mail address') |
|
961 | - ] |
|
962 | - ], |
|
963 | - Http::STATUS_UNPROCESSABLE_ENTITY |
|
964 | - ); |
|
965 | - } |
|
966 | - |
|
967 | - if (!$user) { |
|
968 | - return new DataResponse( |
|
969 | - [ |
|
970 | - 'status' => 'error', |
|
971 | - 'data' => [ |
|
972 | - 'message' => $this->l10n->t('Invalid user') |
|
973 | - ] |
|
974 | - ], |
|
975 | - Http::STATUS_UNPROCESSABLE_ENTITY |
|
976 | - ); |
|
977 | - } |
|
978 | - // this is the only permission a backend provides and is also used |
|
979 | - // for the permission of setting a email address |
|
980 | - if (!$user->canChangeDisplayName()) { |
|
981 | - return new DataResponse( |
|
982 | - [ |
|
983 | - 'status' => 'error', |
|
984 | - 'data' => [ |
|
985 | - 'message' => $this->l10n->t('Unable to change mail address') |
|
986 | - ] |
|
987 | - ], |
|
988 | - Http::STATUS_FORBIDDEN |
|
989 | - ); |
|
990 | - } |
|
991 | - |
|
992 | - $userData = $this->accountManager->getUser($user); |
|
993 | - $userData[AccountManager::PROPERTY_EMAIL]['value'] = $mailAddress; |
|
994 | - |
|
995 | - try { |
|
996 | - $this->saveUserSettings($user, $userData); |
|
997 | - return new DataResponse( |
|
998 | - [ |
|
999 | - 'status' => 'success', |
|
1000 | - 'data' => [ |
|
1001 | - 'username' => $id, |
|
1002 | - 'mailAddress' => $mailAddress, |
|
1003 | - 'message' => $this->l10n->t('Email saved') |
|
1004 | - ] |
|
1005 | - ], |
|
1006 | - Http::STATUS_OK |
|
1007 | - ); |
|
1008 | - } catch (ForbiddenException $e) { |
|
1009 | - return new DataResponse([ |
|
1010 | - 'status' => 'error', |
|
1011 | - 'data' => [ |
|
1012 | - 'message' => $e->getMessage() |
|
1013 | - ], |
|
1014 | - ]); |
|
1015 | - } |
|
1016 | - } |
|
74 | + /** @var IL10N */ |
|
75 | + private $l10n; |
|
76 | + /** @var IUserSession */ |
|
77 | + private $userSession; |
|
78 | + /** @var bool */ |
|
79 | + private $isAdmin; |
|
80 | + /** @var IUserManager */ |
|
81 | + private $userManager; |
|
82 | + /** @var IGroupManager */ |
|
83 | + private $groupManager; |
|
84 | + /** @var IConfig */ |
|
85 | + private $config; |
|
86 | + /** @var ILogger */ |
|
87 | + private $log; |
|
88 | + /** @var IMailer */ |
|
89 | + private $mailer; |
|
90 | + /** @var bool contains the state of the encryption app */ |
|
91 | + private $isEncryptionAppEnabled; |
|
92 | + /** @var bool contains the state of the admin recovery setting */ |
|
93 | + private $isRestoreEnabled = false; |
|
94 | + /** @var IAppManager */ |
|
95 | + private $appManager; |
|
96 | + /** @var IAvatarManager */ |
|
97 | + private $avatarManager; |
|
98 | + /** @var AccountManager */ |
|
99 | + private $accountManager; |
|
100 | + /** @var ISecureRandom */ |
|
101 | + private $secureRandom; |
|
102 | + /** @var NewUserMailHelper */ |
|
103 | + private $newUserMailHelper; |
|
104 | + /** @var Manager */ |
|
105 | + private $keyManager; |
|
106 | + /** @var IJobList */ |
|
107 | + private $jobList; |
|
108 | + |
|
109 | + /** @var IUserMountCache */ |
|
110 | + private $userMountCache; |
|
111 | + |
|
112 | + /** @var IManager */ |
|
113 | + private $encryptionManager; |
|
114 | + |
|
115 | + public function __construct(string $appName, |
|
116 | + IRequest $request, |
|
117 | + IUserManager $userManager, |
|
118 | + IGroupManager $groupManager, |
|
119 | + IUserSession $userSession, |
|
120 | + IConfig $config, |
|
121 | + bool $isAdmin, |
|
122 | + IL10N $l10n, |
|
123 | + ILogger $log, |
|
124 | + IMailer $mailer, |
|
125 | + IURLGenerator $urlGenerator, |
|
126 | + IAppManager $appManager, |
|
127 | + IAvatarManager $avatarManager, |
|
128 | + AccountManager $accountManager, |
|
129 | + ISecureRandom $secureRandom, |
|
130 | + NewUserMailHelper $newUserMailHelper, |
|
131 | + Manager $keyManager, |
|
132 | + IJobList $jobList, |
|
133 | + IUserMountCache $userMountCache, |
|
134 | + IManager $encryptionManager) { |
|
135 | + parent::__construct($appName, $request); |
|
136 | + $this->userManager = $userManager; |
|
137 | + $this->groupManager = $groupManager; |
|
138 | + $this->userSession = $userSession; |
|
139 | + $this->config = $config; |
|
140 | + $this->isAdmin = $isAdmin; |
|
141 | + $this->l10n = $l10n; |
|
142 | + $this->log = $log; |
|
143 | + $this->mailer = $mailer; |
|
144 | + $this->appManager = $appManager; |
|
145 | + $this->avatarManager = $avatarManager; |
|
146 | + $this->accountManager = $accountManager; |
|
147 | + $this->secureRandom = $secureRandom; |
|
148 | + $this->newUserMailHelper = $newUserMailHelper; |
|
149 | + $this->keyManager = $keyManager; |
|
150 | + $this->jobList = $jobList; |
|
151 | + $this->userMountCache = $userMountCache; |
|
152 | + $this->encryptionManager = $encryptionManager; |
|
153 | + |
|
154 | + // check for encryption state - TODO see formatUserForIndex |
|
155 | + $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption'); |
|
156 | + if ($this->isEncryptionAppEnabled) { |
|
157 | + // putting this directly in empty is possible in PHP 5.5+ |
|
158 | + $result = $config->getAppValue('encryption', 'recoveryAdminEnabled', '0'); |
|
159 | + $this->isRestoreEnabled = !empty($result); |
|
160 | + } |
|
161 | + } |
|
162 | + |
|
163 | + /** |
|
164 | + * @param IUser $user |
|
165 | + * @param array|null $userGroups |
|
166 | + * @return array |
|
167 | + */ |
|
168 | + private function formatUserForIndex(IUser $user, array $userGroups = null): array { |
|
169 | + |
|
170 | + // TODO: eliminate this encryption specific code below and somehow |
|
171 | + // hook in additional user info from other apps |
|
172 | + |
|
173 | + // recovery isn't possible if admin or user has it disabled and encryption |
|
174 | + // is enabled - so we eliminate the else paths in the conditional tree |
|
175 | + // below |
|
176 | + $restorePossible = false; |
|
177 | + |
|
178 | + if ($this->isEncryptionAppEnabled) { |
|
179 | + if ($this->isRestoreEnabled) { |
|
180 | + // check for the users recovery setting |
|
181 | + $recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0'); |
|
182 | + // method call inside empty is possible with PHP 5.5+ |
|
183 | + $recoveryModeEnabled = !empty($recoveryMode); |
|
184 | + if ($recoveryModeEnabled) { |
|
185 | + // user also has recovery mode enabled |
|
186 | + $restorePossible = true; |
|
187 | + } |
|
188 | + } else { |
|
189 | + $modules = $this->encryptionManager->getEncryptionModules(); |
|
190 | + $restorePossible = true; |
|
191 | + foreach ($modules as $id => $module) { |
|
192 | + /* @var IEncryptionModule $instance */ |
|
193 | + $instance = call_user_func($module['callback']); |
|
194 | + if ($instance->needDetailedAccessList()) { |
|
195 | + $restorePossible = false; |
|
196 | + break; |
|
197 | + } |
|
198 | + } |
|
199 | + } |
|
200 | + } else { |
|
201 | + // recovery is possible if encryption is disabled (plain files are |
|
202 | + // available) |
|
203 | + $restorePossible = true; |
|
204 | + } |
|
205 | + |
|
206 | + $subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroupsName($user); |
|
207 | + |
|
208 | + $displayName = $user->getEMailAddress(); |
|
209 | + if (is_null($displayName)) { |
|
210 | + $displayName = ''; |
|
211 | + } |
|
212 | + |
|
213 | + $avatarAvailable = false; |
|
214 | + try { |
|
215 | + $avatarAvailable = $this->avatarManager->getAvatar($user->getUID())->exists(); |
|
216 | + } catch (\Exception $e) { |
|
217 | + //No avatar yet |
|
218 | + } |
|
219 | + |
|
220 | + return [ |
|
221 | + 'name' => $user->getUID(), |
|
222 | + 'displayname' => $user->getDisplayName(), |
|
223 | + 'groups' => empty($userGroups) ? $this->groupManager->getUserGroupNames($user) : $userGroups, |
|
224 | + 'subadmin' => $subAdminGroups, |
|
225 | + 'quota' => $user->getQuota(), |
|
226 | + 'quota_bytes' => Util::computerFileSize($user->getQuota()), |
|
227 | + 'storageLocation' => $user->getHome(), |
|
228 | + 'lastLogin' => $user->getLastLogin() * 1000, |
|
229 | + 'backend' => $user->getBackendClassName(), |
|
230 | + 'email' => $displayName, |
|
231 | + 'isRestoreDisabled' => !$restorePossible, |
|
232 | + 'isAvatarAvailable' => $avatarAvailable, |
|
233 | + 'isEnabled' => $user->isEnabled(), |
|
234 | + ]; |
|
235 | + } |
|
236 | + |
|
237 | + /** |
|
238 | + * @param array $userIDs Array with schema [$uid => $displayName] |
|
239 | + * @return IUser[] |
|
240 | + */ |
|
241 | + private function getUsersForUID(array $userIDs): array { |
|
242 | + $users = []; |
|
243 | + foreach ($userIDs as $uid => $displayName) { |
|
244 | + $users[$uid] = $this->userManager->get($uid); |
|
245 | + } |
|
246 | + return $users; |
|
247 | + } |
|
248 | + |
|
249 | + /** |
|
250 | + * @NoAdminRequired |
|
251 | + * |
|
252 | + * @param int $offset |
|
253 | + * @param int $limit |
|
254 | + * @param string $gid GID to filter for |
|
255 | + * @param string $pattern Pattern to search for in the username |
|
256 | + * @param string $backend Backend to filter for (class-name) |
|
257 | + * @return DataResponse |
|
258 | + * |
|
259 | + * TODO: Tidy up and write unit tests - code is mainly static method calls |
|
260 | + */ |
|
261 | + public function index(int $offset = 0, int $limit = 10, string $gid = '', string $pattern = '', string $backend = ''): DataResponse { |
|
262 | + // Remove backends |
|
263 | + if (!empty($backend)) { |
|
264 | + $activeBackends = $this->userManager->getBackends(); |
|
265 | + $this->userManager->clearBackends(); |
|
266 | + foreach ($activeBackends as $singleActiveBackend) { |
|
267 | + if ($backend === get_class($singleActiveBackend)) { |
|
268 | + $this->userManager->registerBackend($singleActiveBackend); |
|
269 | + break; |
|
270 | + } |
|
271 | + } |
|
272 | + } |
|
273 | + |
|
274 | + $userObjects = []; |
|
275 | + $users = []; |
|
276 | + if ($this->isAdmin) { |
|
277 | + if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') { |
|
278 | + $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset)); |
|
279 | + } else { |
|
280 | + $batch = $this->userManager->search($pattern, $limit, $offset); |
|
281 | + } |
|
282 | + |
|
283 | + foreach ($batch as $user) { |
|
284 | + if (($gid !== '_disabledUsers' && $user->isEnabled()) || |
|
285 | + ($gid === '_disabledUsers' && !$user->isEnabled()) |
|
286 | + ) { |
|
287 | + $userObjects[] = $user; |
|
288 | + $users[] = $this->formatUserForIndex($user); |
|
289 | + } |
|
290 | + } |
|
291 | + |
|
292 | + } else { |
|
293 | + $subAdminOfGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser()); |
|
294 | + // New class returns IGroup[] so convert back |
|
295 | + $gids = []; |
|
296 | + foreach ($subAdminOfGroups as $group) { |
|
297 | + $gids[] = $group->getGID(); |
|
298 | + } |
|
299 | + $subAdminOfGroups = $gids; |
|
300 | + |
|
301 | + // Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group |
|
302 | + if ($gid !== '' && $gid !== '_disabledUsers' && !in_array($gid, $subAdminOfGroups)) { |
|
303 | + $gid = ''; |
|
304 | + } |
|
305 | + |
|
306 | + // Batch all groups the user is subadmin of when a group is specified |
|
307 | + $batch = []; |
|
308 | + if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') { |
|
309 | + $batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset); |
|
310 | + } else { |
|
311 | + foreach ($subAdminOfGroups as $group) { |
|
312 | + $groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset); |
|
313 | + |
|
314 | + foreach ($groupUsers as $uid => $displayName) { |
|
315 | + $batch[$uid] = $displayName; |
|
316 | + } |
|
317 | + } |
|
318 | + } |
|
319 | + $batch = $this->getUsersForUID($batch); |
|
320 | + |
|
321 | + foreach ($batch as $user) { |
|
322 | + // Only add the groups, this user is a subadmin of |
|
323 | + $userGroups = array_values(array_intersect( |
|
324 | + $this->groupManager->getUserGroupIds($user), |
|
325 | + $subAdminOfGroups |
|
326 | + )); |
|
327 | + if (($gid !== '_disabledUsers' && $user->isEnabled()) || |
|
328 | + ($gid === '_disabledUsers' && !$user->isEnabled()) |
|
329 | + ) { |
|
330 | + $userObjects[] = $user; |
|
331 | + $users[] = $this->formatUserForIndex($user, $userGroups); |
|
332 | + } |
|
333 | + } |
|
334 | + } |
|
335 | + |
|
336 | + $usedSpace = $this->userMountCache->getUsedSpaceForUsers($userObjects); |
|
337 | + |
|
338 | + foreach ($users as &$userData) { |
|
339 | + $userData['size'] = isset($usedSpace[$userData['name']]) ? $usedSpace[$userData['name']] : 0; |
|
340 | + } |
|
341 | + |
|
342 | + return new DataResponse($users); |
|
343 | + } |
|
344 | + |
|
345 | + /** |
|
346 | + * @NoAdminRequired |
|
347 | + * @PasswordConfirmationRequired |
|
348 | + * |
|
349 | + * @param string $username |
|
350 | + * @param string $password |
|
351 | + * @param array $groups |
|
352 | + * @param string $email |
|
353 | + * @return DataResponse |
|
354 | + */ |
|
355 | + public function create(string $username, string $password, array $groups = [], $email = ''): DataResponse { |
|
356 | + if ($email !== '' && !$this->mailer->validateMailAddress($email)) { |
|
357 | + return new DataResponse( |
|
358 | + [ |
|
359 | + 'message' => $this->l10n->t('Invalid mail address') |
|
360 | + ], |
|
361 | + Http::STATUS_UNPROCESSABLE_ENTITY |
|
362 | + ); |
|
363 | + } |
|
364 | + |
|
365 | + $currentUser = $this->userSession->getUser(); |
|
366 | + |
|
367 | + if (!$this->isAdmin) { |
|
368 | + if (!empty($groups)) { |
|
369 | + foreach ($groups as $key => $group) { |
|
370 | + $groupObject = $this->groupManager->get($group); |
|
371 | + if ($groupObject === null) { |
|
372 | + unset($groups[$key]); |
|
373 | + continue; |
|
374 | + } |
|
375 | + |
|
376 | + if (!$this->groupManager->getSubAdmin()->isSubAdminOfGroup($currentUser, $groupObject)) { |
|
377 | + unset($groups[$key]); |
|
378 | + } |
|
379 | + } |
|
380 | + } |
|
381 | + |
|
382 | + if (empty($groups)) { |
|
383 | + return new DataResponse( |
|
384 | + [ |
|
385 | + 'message' => $this->l10n->t('No valid group selected'), |
|
386 | + ], |
|
387 | + Http::STATUS_FORBIDDEN |
|
388 | + ); |
|
389 | + } |
|
390 | + } |
|
391 | + |
|
392 | + if ($this->userManager->userExists($username)) { |
|
393 | + return new DataResponse( |
|
394 | + [ |
|
395 | + 'message' => $this->l10n->t('A user with that name already exists.') |
|
396 | + ], |
|
397 | + Http::STATUS_CONFLICT |
|
398 | + ); |
|
399 | + } |
|
400 | + |
|
401 | + $generatePasswordResetToken = false; |
|
402 | + if ($password === '') { |
|
403 | + if ($email === '') { |
|
404 | + return new DataResponse( |
|
405 | + [ |
|
406 | + 'message' => $this->l10n->t('To send a password link to the user an email address is required.') |
|
407 | + ], |
|
408 | + Http::STATUS_UNPROCESSABLE_ENTITY |
|
409 | + ); |
|
410 | + } |
|
411 | + |
|
412 | + $password = $this->secureRandom->generate(30); |
|
413 | + // Make sure we pass the password_policy |
|
414 | + $password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()'); |
|
415 | + $generatePasswordResetToken = true; |
|
416 | + } |
|
417 | + |
|
418 | + try { |
|
419 | + $user = $this->userManager->createUser($username, $password); |
|
420 | + } catch (\Exception $exception) { |
|
421 | + $message = $exception->getMessage(); |
|
422 | + if ($exception instanceof HintException && $exception->getHint()) { |
|
423 | + $message = $exception->getHint(); |
|
424 | + } |
|
425 | + if (!$message) { |
|
426 | + $message = $this->l10n->t('Unable to create user.'); |
|
427 | + } |
|
428 | + return new DataResponse( |
|
429 | + [ |
|
430 | + 'message' => (string)$message, |
|
431 | + ], |
|
432 | + Http::STATUS_FORBIDDEN |
|
433 | + ); |
|
434 | + } |
|
435 | + |
|
436 | + if ($user instanceof IUser) { |
|
437 | + if ($groups !== null) { |
|
438 | + foreach ($groups as $groupName) { |
|
439 | + $group = $this->groupManager->get($groupName); |
|
440 | + |
|
441 | + if (empty($group)) { |
|
442 | + $group = $this->groupManager->createGroup($groupName); |
|
443 | + } |
|
444 | + $group->addUser($user); |
|
445 | + } |
|
446 | + } |
|
447 | + /** |
|
448 | + * Send new user mail only if a mail is set |
|
449 | + */ |
|
450 | + if ($email !== '') { |
|
451 | + $user->setEMailAddress($email); |
|
452 | + try { |
|
453 | + $emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken); |
|
454 | + $this->newUserMailHelper->sendMail($user, $emailTemplate); |
|
455 | + } catch (\Exception $e) { |
|
456 | + $this->log->logException($e, [ |
|
457 | + 'message' => "Can't send new user mail to $email", |
|
458 | + 'level' => ILogger::ERROR, |
|
459 | + 'app' => 'settings', |
|
460 | + ]); |
|
461 | + } |
|
462 | + } |
|
463 | + // fetch users groups |
|
464 | + $userGroups = $this->groupManager->getUserGroupNames($user); |
|
465 | + |
|
466 | + return new DataResponse( |
|
467 | + $this->formatUserForIndex($user, $userGroups), |
|
468 | + Http::STATUS_CREATED |
|
469 | + ); |
|
470 | + } |
|
471 | + |
|
472 | + return new DataResponse( |
|
473 | + [ |
|
474 | + 'message' => $this->l10n->t('Unable to create user.') |
|
475 | + ], |
|
476 | + Http::STATUS_FORBIDDEN |
|
477 | + ); |
|
478 | + |
|
479 | + } |
|
480 | + |
|
481 | + /** |
|
482 | + * @NoAdminRequired |
|
483 | + * @PasswordConfirmationRequired |
|
484 | + * |
|
485 | + * @param string $id |
|
486 | + * @return DataResponse |
|
487 | + */ |
|
488 | + public function destroy(string $id): DataResponse { |
|
489 | + $userId = $this->userSession->getUser()->getUID(); |
|
490 | + $user = $this->userManager->get($id); |
|
491 | + |
|
492 | + if ($userId === $id) { |
|
493 | + return new DataResponse( |
|
494 | + [ |
|
495 | + 'status' => 'error', |
|
496 | + 'data' => [ |
|
497 | + 'message' => $this->l10n->t('Unable to delete user.') |
|
498 | + ] |
|
499 | + ], |
|
500 | + Http::STATUS_FORBIDDEN |
|
501 | + ); |
|
502 | + } |
|
503 | + |
|
504 | + if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) { |
|
505 | + return new DataResponse( |
|
506 | + [ |
|
507 | + 'status' => 'error', |
|
508 | + 'data' => [ |
|
509 | + 'message' => $this->l10n->t('Authentication error') |
|
510 | + ] |
|
511 | + ], |
|
512 | + Http::STATUS_FORBIDDEN |
|
513 | + ); |
|
514 | + } |
|
515 | + |
|
516 | + if ($user && $user->delete()) { |
|
517 | + return new DataResponse( |
|
518 | + [ |
|
519 | + 'status' => 'success', |
|
520 | + 'data' => [ |
|
521 | + 'username' => $id |
|
522 | + ] |
|
523 | + ], |
|
524 | + Http::STATUS_NO_CONTENT |
|
525 | + ); |
|
526 | + } |
|
527 | + |
|
528 | + return new DataResponse( |
|
529 | + [ |
|
530 | + 'status' => 'error', |
|
531 | + 'data' => [ |
|
532 | + 'message' => $this->l10n->t('Unable to delete user.') |
|
533 | + ] |
|
534 | + ], |
|
535 | + Http::STATUS_FORBIDDEN |
|
536 | + ); |
|
537 | + } |
|
538 | + |
|
539 | + /** |
|
540 | + * @NoAdminRequired |
|
541 | + * |
|
542 | + * @param string $id |
|
543 | + * @param int $enabled |
|
544 | + * @return DataResponse |
|
545 | + */ |
|
546 | + public function setEnabled(string $id, int $enabled): DataResponse { |
|
547 | + $enabled = (bool)$enabled; |
|
548 | + if ($enabled) { |
|
549 | + $errorMsgGeneral = $this->l10n->t('Error while enabling user.'); |
|
550 | + } else { |
|
551 | + $errorMsgGeneral = $this->l10n->t('Error while disabling user.'); |
|
552 | + } |
|
553 | + |
|
554 | + $userId = $this->userSession->getUser()->getUID(); |
|
555 | + $user = $this->userManager->get($id); |
|
556 | + |
|
557 | + if ($userId === $id) { |
|
558 | + return new DataResponse( |
|
559 | + [ |
|
560 | + 'status' => 'error', |
|
561 | + 'data' => [ |
|
562 | + 'message' => $errorMsgGeneral |
|
563 | + ] |
|
564 | + ], Http::STATUS_FORBIDDEN |
|
565 | + ); |
|
566 | + } |
|
567 | + |
|
568 | + if ($user) { |
|
569 | + if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) { |
|
570 | + return new DataResponse( |
|
571 | + [ |
|
572 | + 'status' => 'error', |
|
573 | + 'data' => [ |
|
574 | + 'message' => $this->l10n->t('Authentication error') |
|
575 | + ] |
|
576 | + ], |
|
577 | + Http::STATUS_FORBIDDEN |
|
578 | + ); |
|
579 | + } |
|
580 | + |
|
581 | + $user->setEnabled($enabled); |
|
582 | + return new DataResponse( |
|
583 | + [ |
|
584 | + 'status' => 'success', |
|
585 | + 'data' => [ |
|
586 | + 'username' => $id, |
|
587 | + 'enabled' => $enabled |
|
588 | + ] |
|
589 | + ] |
|
590 | + ); |
|
591 | + } else { |
|
592 | + return new DataResponse( |
|
593 | + [ |
|
594 | + 'status' => 'error', |
|
595 | + 'data' => [ |
|
596 | + 'message' => $errorMsgGeneral |
|
597 | + ] |
|
598 | + ], |
|
599 | + Http::STATUS_FORBIDDEN |
|
600 | + ); |
|
601 | + } |
|
602 | + |
|
603 | + } |
|
604 | + |
|
605 | + /** |
|
606 | + * Set the mail address of a user |
|
607 | + * |
|
608 | + * @NoAdminRequired |
|
609 | + * @NoSubadminRequired |
|
610 | + * @PasswordConfirmationRequired |
|
611 | + * |
|
612 | + * @param string $account |
|
613 | + * @param bool $onlyVerificationCode only return verification code without updating the data |
|
614 | + * @return DataResponse |
|
615 | + */ |
|
616 | + public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse { |
|
617 | + |
|
618 | + $user = $this->userSession->getUser(); |
|
619 | + |
|
620 | + if ($user === null) { |
|
621 | + return new DataResponse([], Http::STATUS_BAD_REQUEST); |
|
622 | + } |
|
623 | + |
|
624 | + $accountData = $this->accountManager->getUser($user); |
|
625 | + $cloudId = $user->getCloudId(); |
|
626 | + $message = 'Use my Federated Cloud ID to share with me: ' . $cloudId; |
|
627 | + $signature = $this->signMessage($user, $message); |
|
628 | + |
|
629 | + $code = $message . ' ' . $signature; |
|
630 | + $codeMd5 = $message . ' ' . md5($signature); |
|
631 | + |
|
632 | + switch ($account) { |
|
633 | + case 'verify-twitter': |
|
634 | + $accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS; |
|
635 | + $msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):'); |
|
636 | + $code = $codeMd5; |
|
637 | + $type = AccountManager::PROPERTY_TWITTER; |
|
638 | + $data = $accountData[AccountManager::PROPERTY_TWITTER]['value']; |
|
639 | + $accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature; |
|
640 | + break; |
|
641 | + case 'verify-website': |
|
642 | + $accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS; |
|
643 | + $msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):'); |
|
644 | + $type = AccountManager::PROPERTY_WEBSITE; |
|
645 | + $data = $accountData[AccountManager::PROPERTY_WEBSITE]['value']; |
|
646 | + $accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature; |
|
647 | + break; |
|
648 | + default: |
|
649 | + return new DataResponse([], Http::STATUS_BAD_REQUEST); |
|
650 | + } |
|
651 | + |
|
652 | + if ($onlyVerificationCode === false) { |
|
653 | + $this->accountManager->updateUser($user, $accountData); |
|
654 | + |
|
655 | + $this->jobList->add(VerifyUserData::class, |
|
656 | + [ |
|
657 | + 'verificationCode' => $code, |
|
658 | + 'data' => $data, |
|
659 | + 'type' => $type, |
|
660 | + 'uid' => $user->getUID(), |
|
661 | + 'try' => 0, |
|
662 | + 'lastRun' => $this->getCurrentTime() |
|
663 | + ] |
|
664 | + ); |
|
665 | + } |
|
666 | + |
|
667 | + return new DataResponse(['msg' => $msg, 'code' => $code]); |
|
668 | + } |
|
669 | + |
|
670 | + /** |
|
671 | + * get current timestamp |
|
672 | + * |
|
673 | + * @return int |
|
674 | + */ |
|
675 | + protected function getCurrentTime(): int { |
|
676 | + return time(); |
|
677 | + } |
|
678 | + |
|
679 | + /** |
|
680 | + * sign message with users private key |
|
681 | + * |
|
682 | + * @param IUser $user |
|
683 | + * @param string $message |
|
684 | + * |
|
685 | + * @return string base64 encoded signature |
|
686 | + */ |
|
687 | + protected function signMessage(IUser $user, string $message): string { |
|
688 | + $privateKey = $this->keyManager->getKey($user)->getPrivate(); |
|
689 | + openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512); |
|
690 | + return base64_encode($signature); |
|
691 | + } |
|
692 | + |
|
693 | + /** |
|
694 | + * @NoAdminRequired |
|
695 | + * @NoSubadminRequired |
|
696 | + * @PasswordConfirmationRequired |
|
697 | + * |
|
698 | + * @param string $avatarScope |
|
699 | + * @param string $displayname |
|
700 | + * @param string $displaynameScope |
|
701 | + * @param string $phone |
|
702 | + * @param string $phoneScope |
|
703 | + * @param string $email |
|
704 | + * @param string $emailScope |
|
705 | + * @param string $website |
|
706 | + * @param string $websiteScope |
|
707 | + * @param string $address |
|
708 | + * @param string $addressScope |
|
709 | + * @param string $twitter |
|
710 | + * @param string $twitterScope |
|
711 | + * @return DataResponse |
|
712 | + */ |
|
713 | + public function setUserSettings($avatarScope, |
|
714 | + $displayname, |
|
715 | + $displaynameScope, |
|
716 | + $phone, |
|
717 | + $phoneScope, |
|
718 | + $email, |
|
719 | + $emailScope, |
|
720 | + $website, |
|
721 | + $websiteScope, |
|
722 | + $address, |
|
723 | + $addressScope, |
|
724 | + $twitter, |
|
725 | + $twitterScope |
|
726 | + ) { |
|
727 | + |
|
728 | + if (!empty($email) && !$this->mailer->validateMailAddress($email)) { |
|
729 | + return new DataResponse( |
|
730 | + [ |
|
731 | + 'status' => 'error', |
|
732 | + 'data' => [ |
|
733 | + 'message' => $this->l10n->t('Invalid mail address') |
|
734 | + ] |
|
735 | + ], |
|
736 | + Http::STATUS_UNPROCESSABLE_ENTITY |
|
737 | + ); |
|
738 | + } |
|
739 | + |
|
740 | + $user = $this->userSession->getUser(); |
|
741 | + |
|
742 | + $data = $this->accountManager->getUser($user); |
|
743 | + |
|
744 | + $data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope]; |
|
745 | + if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) { |
|
746 | + $data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope]; |
|
747 | + $data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope]; |
|
748 | + } |
|
749 | + |
|
750 | + if ($this->appManager->isEnabledForUser('federatedfilesharing')) { |
|
751 | + $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application(); |
|
752 | + $shareProvider = $federatedFileSharing->getFederatedShareProvider(); |
|
753 | + if ($shareProvider->isLookupServerUploadEnabled()) { |
|
754 | + $data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope]; |
|
755 | + $data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope]; |
|
756 | + $data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope]; |
|
757 | + $data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope]; |
|
758 | + } |
|
759 | + } |
|
760 | + |
|
761 | + try { |
|
762 | + $this->saveUserSettings($user, $data); |
|
763 | + return new DataResponse( |
|
764 | + [ |
|
765 | + 'status' => 'success', |
|
766 | + 'data' => [ |
|
767 | + 'userId' => $user->getUID(), |
|
768 | + 'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'], |
|
769 | + 'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'], |
|
770 | + 'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'], |
|
771 | + 'email' => $data[AccountManager::PROPERTY_EMAIL]['value'], |
|
772 | + 'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'], |
|
773 | + 'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'], |
|
774 | + 'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'], |
|
775 | + 'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'], |
|
776 | + 'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'], |
|
777 | + 'message' => $this->l10n->t('Settings saved') |
|
778 | + ] |
|
779 | + ], |
|
780 | + Http::STATUS_OK |
|
781 | + ); |
|
782 | + } catch (ForbiddenException $e) { |
|
783 | + return new DataResponse([ |
|
784 | + 'status' => 'error', |
|
785 | + 'data' => [ |
|
786 | + 'message' => $e->getMessage() |
|
787 | + ], |
|
788 | + ]); |
|
789 | + } |
|
790 | + |
|
791 | + } |
|
792 | + |
|
793 | + |
|
794 | + /** |
|
795 | + * update account manager with new user data |
|
796 | + * |
|
797 | + * @param IUser $user |
|
798 | + * @param array $data |
|
799 | + * @throws ForbiddenException |
|
800 | + */ |
|
801 | + protected function saveUserSettings(IUser $user, array $data) { |
|
802 | + |
|
803 | + // keep the user back-end up-to-date with the latest display name and email |
|
804 | + // address |
|
805 | + $oldDisplayName = $user->getDisplayName(); |
|
806 | + $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName; |
|
807 | + if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value']) |
|
808 | + && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value'] |
|
809 | + ) { |
|
810 | + $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']); |
|
811 | + if ($result === false) { |
|
812 | + throw new ForbiddenException($this->l10n->t('Unable to change full name')); |
|
813 | + } |
|
814 | + } |
|
815 | + |
|
816 | + $oldEmailAddress = $user->getEMailAddress(); |
|
817 | + $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress; |
|
818 | + if (isset($data[AccountManager::PROPERTY_EMAIL]['value']) |
|
819 | + && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value'] |
|
820 | + ) { |
|
821 | + // this is the only permission a backend provides and is also used |
|
822 | + // for the permission of setting a email address |
|
823 | + if (!$user->canChangeDisplayName()) { |
|
824 | + throw new ForbiddenException($this->l10n->t('Unable to change email address')); |
|
825 | + } |
|
826 | + $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']); |
|
827 | + } |
|
828 | + |
|
829 | + $this->accountManager->updateUser($user, $data); |
|
830 | + } |
|
831 | + |
|
832 | + /** |
|
833 | + * Count all unique users visible for the current admin/subadmin. |
|
834 | + * |
|
835 | + * @NoAdminRequired |
|
836 | + * |
|
837 | + * @return DataResponse |
|
838 | + */ |
|
839 | + public function stats(): DataResponse { |
|
840 | + $userCount = 0; |
|
841 | + if ($this->isAdmin) { |
|
842 | + $countByBackend = $this->userManager->countUsers(); |
|
843 | + |
|
844 | + if (!empty($countByBackend)) { |
|
845 | + foreach ($countByBackend as $count) { |
|
846 | + $userCount += $count; |
|
847 | + } |
|
848 | + } |
|
849 | + } else { |
|
850 | + $groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser()); |
|
851 | + |
|
852 | + $uniqueUsers = []; |
|
853 | + foreach ($groups as $group) { |
|
854 | + foreach ($group->getUsers() as $uid => $displayName) { |
|
855 | + $uniqueUsers[$uid] = true; |
|
856 | + } |
|
857 | + } |
|
858 | + |
|
859 | + $userCount = count($uniqueUsers); |
|
860 | + } |
|
861 | + |
|
862 | + return new DataResponse( |
|
863 | + [ |
|
864 | + 'totalUsers' => $userCount |
|
865 | + ] |
|
866 | + ); |
|
867 | + } |
|
868 | + |
|
869 | + |
|
870 | + /** |
|
871 | + * Set the displayName of a user |
|
872 | + * |
|
873 | + * @NoAdminRequired |
|
874 | + * @NoSubadminRequired |
|
875 | + * @PasswordConfirmationRequired |
|
876 | + * @todo merge into saveUserSettings |
|
877 | + * |
|
878 | + * @param string $username |
|
879 | + * @param string $displayName |
|
880 | + * @return DataResponse |
|
881 | + */ |
|
882 | + public function setDisplayName(string $username, string $displayName) { |
|
883 | + $currentUser = $this->userSession->getUser(); |
|
884 | + $user = $this->userManager->get($username); |
|
885 | + |
|
886 | + if ($user === null || |
|
887 | + !$user->canChangeDisplayName() || |
|
888 | + ( |
|
889 | + !$this->groupManager->isAdmin($currentUser->getUID()) && |
|
890 | + !$this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $user) && |
|
891 | + $currentUser->getUID() !== $username |
|
892 | + |
|
893 | + ) |
|
894 | + ) { |
|
895 | + return new DataResponse([ |
|
896 | + 'status' => 'error', |
|
897 | + 'data' => [ |
|
898 | + 'message' => $this->l10n->t('Authentication error'), |
|
899 | + ], |
|
900 | + ]); |
|
901 | + } |
|
902 | + |
|
903 | + $userData = $this->accountManager->getUser($user); |
|
904 | + $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $displayName; |
|
905 | + |
|
906 | + |
|
907 | + try { |
|
908 | + $this->saveUserSettings($user, $userData); |
|
909 | + return new DataResponse([ |
|
910 | + 'status' => 'success', |
|
911 | + 'data' => [ |
|
912 | + 'message' => $this->l10n->t('Your full name has been changed.'), |
|
913 | + 'username' => $username, |
|
914 | + 'displayName' => $displayName, |
|
915 | + ], |
|
916 | + ]); |
|
917 | + } catch (ForbiddenException $e) { |
|
918 | + return new DataResponse([ |
|
919 | + 'status' => 'error', |
|
920 | + 'data' => [ |
|
921 | + 'message' => $e->getMessage(), |
|
922 | + 'displayName' => $user->getDisplayName(), |
|
923 | + ], |
|
924 | + ]); |
|
925 | + } |
|
926 | + } |
|
927 | + |
|
928 | + /** |
|
929 | + * Set the mail address of a user |
|
930 | + * |
|
931 | + * @NoAdminRequired |
|
932 | + * @NoSubadminRequired |
|
933 | + * @PasswordConfirmationRequired |
|
934 | + * |
|
935 | + * @param string $id |
|
936 | + * @param string $mailAddress |
|
937 | + * @return DataResponse |
|
938 | + */ |
|
939 | + public function setEMailAddress(string $id, string $mailAddress) { |
|
940 | + $user = $this->userManager->get($id); |
|
941 | + if (!$this->isAdmin |
|
942 | + && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user) |
|
943 | + ) { |
|
944 | + return new DataResponse( |
|
945 | + [ |
|
946 | + 'status' => 'error', |
|
947 | + 'data' => [ |
|
948 | + 'message' => $this->l10n->t('Forbidden') |
|
949 | + ] |
|
950 | + ], |
|
951 | + Http::STATUS_FORBIDDEN |
|
952 | + ); |
|
953 | + } |
|
954 | + |
|
955 | + if ($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) { |
|
956 | + return new DataResponse( |
|
957 | + [ |
|
958 | + 'status' => 'error', |
|
959 | + 'data' => [ |
|
960 | + 'message' => $this->l10n->t('Invalid mail address') |
|
961 | + ] |
|
962 | + ], |
|
963 | + Http::STATUS_UNPROCESSABLE_ENTITY |
|
964 | + ); |
|
965 | + } |
|
966 | + |
|
967 | + if (!$user) { |
|
968 | + return new DataResponse( |
|
969 | + [ |
|
970 | + 'status' => 'error', |
|
971 | + 'data' => [ |
|
972 | + 'message' => $this->l10n->t('Invalid user') |
|
973 | + ] |
|
974 | + ], |
|
975 | + Http::STATUS_UNPROCESSABLE_ENTITY |
|
976 | + ); |
|
977 | + } |
|
978 | + // this is the only permission a backend provides and is also used |
|
979 | + // for the permission of setting a email address |
|
980 | + if (!$user->canChangeDisplayName()) { |
|
981 | + return new DataResponse( |
|
982 | + [ |
|
983 | + 'status' => 'error', |
|
984 | + 'data' => [ |
|
985 | + 'message' => $this->l10n->t('Unable to change mail address') |
|
986 | + ] |
|
987 | + ], |
|
988 | + Http::STATUS_FORBIDDEN |
|
989 | + ); |
|
990 | + } |
|
991 | + |
|
992 | + $userData = $this->accountManager->getUser($user); |
|
993 | + $userData[AccountManager::PROPERTY_EMAIL]['value'] = $mailAddress; |
|
994 | + |
|
995 | + try { |
|
996 | + $this->saveUserSettings($user, $userData); |
|
997 | + return new DataResponse( |
|
998 | + [ |
|
999 | + 'status' => 'success', |
|
1000 | + 'data' => [ |
|
1001 | + 'username' => $id, |
|
1002 | + 'mailAddress' => $mailAddress, |
|
1003 | + 'message' => $this->l10n->t('Email saved') |
|
1004 | + ] |
|
1005 | + ], |
|
1006 | + Http::STATUS_OK |
|
1007 | + ); |
|
1008 | + } catch (ForbiddenException $e) { |
|
1009 | + return new DataResponse([ |
|
1010 | + 'status' => 'error', |
|
1011 | + 'data' => [ |
|
1012 | + 'message' => $e->getMessage() |
|
1013 | + ], |
|
1014 | + ]); |
|
1015 | + } |
|
1016 | + } |
|
1017 | 1017 | |
1018 | 1018 | } |
@@ -48,159 +48,159 @@ |
||
48 | 48 | */ |
49 | 49 | |
50 | 50 | class File implements IWriter, IFileBased { |
51 | - /** @var string */ |
|
52 | - protected $logFile; |
|
53 | - /** @var IConfig */ |
|
54 | - private $config; |
|
51 | + /** @var string */ |
|
52 | + protected $logFile; |
|
53 | + /** @var IConfig */ |
|
54 | + private $config; |
|
55 | 55 | |
56 | - public function __construct(string $path, string $fallbackPath = '', IConfig $config) { |
|
57 | - $this->logFile = $path; |
|
58 | - if (!file_exists($this->logFile)) { |
|
59 | - if( |
|
60 | - ( |
|
61 | - !is_writable(dirname($this->logFile)) |
|
62 | - || !touch($this->logFile) |
|
63 | - ) |
|
64 | - && $fallbackPath !== '' |
|
65 | - ) { |
|
66 | - $this->logFile = $fallbackPath; |
|
67 | - } |
|
68 | - } |
|
69 | - $this->config = $config; |
|
70 | - } |
|
56 | + public function __construct(string $path, string $fallbackPath = '', IConfig $config) { |
|
57 | + $this->logFile = $path; |
|
58 | + if (!file_exists($this->logFile)) { |
|
59 | + if( |
|
60 | + ( |
|
61 | + !is_writable(dirname($this->logFile)) |
|
62 | + || !touch($this->logFile) |
|
63 | + ) |
|
64 | + && $fallbackPath !== '' |
|
65 | + ) { |
|
66 | + $this->logFile = $fallbackPath; |
|
67 | + } |
|
68 | + } |
|
69 | + $this->config = $config; |
|
70 | + } |
|
71 | 71 | |
72 | - /** |
|
73 | - * write a message in the log |
|
74 | - * @param string $app |
|
75 | - * @param string|array $message |
|
76 | - * @param int $level |
|
77 | - */ |
|
78 | - public function write(string $app, $message, int $level) { |
|
79 | - // default to ISO8601 |
|
80 | - $format = $this->config->getSystemValue('logdateformat', \DateTime::ATOM); |
|
81 | - $logTimeZone = $this->config->getSystemValue('logtimezone', 'UTC'); |
|
82 | - try { |
|
83 | - $timezone = new \DateTimeZone($logTimeZone); |
|
84 | - } catch (\Exception $e) { |
|
85 | - $timezone = new \DateTimeZone('UTC'); |
|
86 | - } |
|
87 | - $time = \DateTime::createFromFormat("U.u", number_format(microtime(true), 4, ".", "")); |
|
88 | - if ($time === false) { |
|
89 | - $time = new \DateTime(null, $timezone); |
|
90 | - } else { |
|
91 | - // apply timezone if $time is created from UNIX timestamp |
|
92 | - $time->setTimezone($timezone); |
|
93 | - } |
|
94 | - $request = \OC::$server->getRequest(); |
|
95 | - $reqId = $request->getId(); |
|
96 | - $remoteAddr = $request->getRemoteAddress(); |
|
97 | - // remove username/passwords from URLs before writing the to the log file |
|
98 | - $time = $time->format($format); |
|
99 | - $url = ($request->getRequestUri() !== '') ? $request->getRequestUri() : '--'; |
|
100 | - $method = is_string($request->getMethod()) ? $request->getMethod() : '--'; |
|
101 | - if($this->config->getSystemValue('installed', false)) { |
|
102 | - $user = \OC_User::getUser() ? \OC_User::getUser() : '--'; |
|
103 | - } else { |
|
104 | - $user = '--'; |
|
105 | - } |
|
106 | - $userAgent = $request->getHeader('User-Agent'); |
|
107 | - if ($userAgent === '') { |
|
108 | - $userAgent = '--'; |
|
109 | - } |
|
110 | - $version = $this->config->getSystemValue('version', ''); |
|
111 | - $entry = compact( |
|
112 | - 'reqId', |
|
113 | - 'level', |
|
114 | - 'time', |
|
115 | - 'remoteAddr', |
|
116 | - 'user', |
|
117 | - 'app', |
|
118 | - 'method', |
|
119 | - 'url', |
|
120 | - 'message', |
|
121 | - 'userAgent', |
|
122 | - 'version' |
|
123 | - ); |
|
124 | - // PHP's json_encode only accept proper UTF-8 strings, loop over all |
|
125 | - // elements to ensure that they are properly UTF-8 compliant or convert |
|
126 | - // them manually. |
|
127 | - foreach($entry as $key => $value) { |
|
128 | - if(is_string($value)) { |
|
129 | - $testEncode = json_encode($value); |
|
130 | - if($testEncode === false) { |
|
131 | - $entry[$key] = utf8_encode($value); |
|
132 | - } |
|
133 | - } |
|
134 | - } |
|
135 | - $entry = json_encode($entry, JSON_PARTIAL_OUTPUT_ON_ERROR); |
|
136 | - $handle = @fopen($this->logFile, 'a'); |
|
137 | - if ((fileperms($this->logFile) & 0777) != 0640) { |
|
138 | - @chmod($this->logFile, 0640); |
|
139 | - } |
|
140 | - if ($handle) { |
|
141 | - fwrite($handle, $entry."\n"); |
|
142 | - fclose($handle); |
|
143 | - } else { |
|
144 | - // Fall back to error_log |
|
145 | - error_log($entry); |
|
146 | - } |
|
147 | - if (php_sapi_name() === 'cli-server') { |
|
148 | - error_log($message, 4); |
|
149 | - } |
|
150 | - } |
|
72 | + /** |
|
73 | + * write a message in the log |
|
74 | + * @param string $app |
|
75 | + * @param string|array $message |
|
76 | + * @param int $level |
|
77 | + */ |
|
78 | + public function write(string $app, $message, int $level) { |
|
79 | + // default to ISO8601 |
|
80 | + $format = $this->config->getSystemValue('logdateformat', \DateTime::ATOM); |
|
81 | + $logTimeZone = $this->config->getSystemValue('logtimezone', 'UTC'); |
|
82 | + try { |
|
83 | + $timezone = new \DateTimeZone($logTimeZone); |
|
84 | + } catch (\Exception $e) { |
|
85 | + $timezone = new \DateTimeZone('UTC'); |
|
86 | + } |
|
87 | + $time = \DateTime::createFromFormat("U.u", number_format(microtime(true), 4, ".", "")); |
|
88 | + if ($time === false) { |
|
89 | + $time = new \DateTime(null, $timezone); |
|
90 | + } else { |
|
91 | + // apply timezone if $time is created from UNIX timestamp |
|
92 | + $time->setTimezone($timezone); |
|
93 | + } |
|
94 | + $request = \OC::$server->getRequest(); |
|
95 | + $reqId = $request->getId(); |
|
96 | + $remoteAddr = $request->getRemoteAddress(); |
|
97 | + // remove username/passwords from URLs before writing the to the log file |
|
98 | + $time = $time->format($format); |
|
99 | + $url = ($request->getRequestUri() !== '') ? $request->getRequestUri() : '--'; |
|
100 | + $method = is_string($request->getMethod()) ? $request->getMethod() : '--'; |
|
101 | + if($this->config->getSystemValue('installed', false)) { |
|
102 | + $user = \OC_User::getUser() ? \OC_User::getUser() : '--'; |
|
103 | + } else { |
|
104 | + $user = '--'; |
|
105 | + } |
|
106 | + $userAgent = $request->getHeader('User-Agent'); |
|
107 | + if ($userAgent === '') { |
|
108 | + $userAgent = '--'; |
|
109 | + } |
|
110 | + $version = $this->config->getSystemValue('version', ''); |
|
111 | + $entry = compact( |
|
112 | + 'reqId', |
|
113 | + 'level', |
|
114 | + 'time', |
|
115 | + 'remoteAddr', |
|
116 | + 'user', |
|
117 | + 'app', |
|
118 | + 'method', |
|
119 | + 'url', |
|
120 | + 'message', |
|
121 | + 'userAgent', |
|
122 | + 'version' |
|
123 | + ); |
|
124 | + // PHP's json_encode only accept proper UTF-8 strings, loop over all |
|
125 | + // elements to ensure that they are properly UTF-8 compliant or convert |
|
126 | + // them manually. |
|
127 | + foreach($entry as $key => $value) { |
|
128 | + if(is_string($value)) { |
|
129 | + $testEncode = json_encode($value); |
|
130 | + if($testEncode === false) { |
|
131 | + $entry[$key] = utf8_encode($value); |
|
132 | + } |
|
133 | + } |
|
134 | + } |
|
135 | + $entry = json_encode($entry, JSON_PARTIAL_OUTPUT_ON_ERROR); |
|
136 | + $handle = @fopen($this->logFile, 'a'); |
|
137 | + if ((fileperms($this->logFile) & 0777) != 0640) { |
|
138 | + @chmod($this->logFile, 0640); |
|
139 | + } |
|
140 | + if ($handle) { |
|
141 | + fwrite($handle, $entry."\n"); |
|
142 | + fclose($handle); |
|
143 | + } else { |
|
144 | + // Fall back to error_log |
|
145 | + error_log($entry); |
|
146 | + } |
|
147 | + if (php_sapi_name() === 'cli-server') { |
|
148 | + error_log($message, 4); |
|
149 | + } |
|
150 | + } |
|
151 | 151 | |
152 | - /** |
|
153 | - * get entries from the log in reverse chronological order |
|
154 | - * @param int $limit |
|
155 | - * @param int $offset |
|
156 | - * @return array |
|
157 | - */ |
|
158 | - public function getEntries(int $limit=50, int $offset=0):array { |
|
159 | - $minLevel = $this->config->getSystemValue("loglevel", ILogger::WARN); |
|
160 | - $entries = array(); |
|
161 | - $handle = @fopen($this->logFile, 'rb'); |
|
162 | - if ($handle) { |
|
163 | - fseek($handle, 0, SEEK_END); |
|
164 | - $pos = ftell($handle); |
|
165 | - $line = ''; |
|
166 | - $entriesCount = 0; |
|
167 | - $lines = 0; |
|
168 | - // Loop through each character of the file looking for new lines |
|
169 | - while ($pos >= 0 && ($limit === null ||$entriesCount < $limit)) { |
|
170 | - fseek($handle, $pos); |
|
171 | - $ch = fgetc($handle); |
|
172 | - if ($ch == "\n" || $pos == 0) { |
|
173 | - if ($line != '') { |
|
174 | - // Add the first character if at the start of the file, |
|
175 | - // because it doesn't hit the else in the loop |
|
176 | - if ($pos == 0) { |
|
177 | - $line = $ch.$line; |
|
178 | - } |
|
179 | - $entry = json_decode($line); |
|
180 | - // Add the line as an entry if it is passed the offset and is equal or above the log level |
|
181 | - if ($entry->level >= $minLevel) { |
|
182 | - $lines++; |
|
183 | - if ($lines > $offset) { |
|
184 | - $entries[] = $entry; |
|
185 | - $entriesCount++; |
|
186 | - } |
|
187 | - } |
|
188 | - $line = ''; |
|
189 | - } |
|
190 | - } else { |
|
191 | - $line = $ch.$line; |
|
192 | - } |
|
193 | - $pos--; |
|
194 | - } |
|
195 | - fclose($handle); |
|
196 | - } |
|
197 | - return $entries; |
|
198 | - } |
|
152 | + /** |
|
153 | + * get entries from the log in reverse chronological order |
|
154 | + * @param int $limit |
|
155 | + * @param int $offset |
|
156 | + * @return array |
|
157 | + */ |
|
158 | + public function getEntries(int $limit=50, int $offset=0):array { |
|
159 | + $minLevel = $this->config->getSystemValue("loglevel", ILogger::WARN); |
|
160 | + $entries = array(); |
|
161 | + $handle = @fopen($this->logFile, 'rb'); |
|
162 | + if ($handle) { |
|
163 | + fseek($handle, 0, SEEK_END); |
|
164 | + $pos = ftell($handle); |
|
165 | + $line = ''; |
|
166 | + $entriesCount = 0; |
|
167 | + $lines = 0; |
|
168 | + // Loop through each character of the file looking for new lines |
|
169 | + while ($pos >= 0 && ($limit === null ||$entriesCount < $limit)) { |
|
170 | + fseek($handle, $pos); |
|
171 | + $ch = fgetc($handle); |
|
172 | + if ($ch == "\n" || $pos == 0) { |
|
173 | + if ($line != '') { |
|
174 | + // Add the first character if at the start of the file, |
|
175 | + // because it doesn't hit the else in the loop |
|
176 | + if ($pos == 0) { |
|
177 | + $line = $ch.$line; |
|
178 | + } |
|
179 | + $entry = json_decode($line); |
|
180 | + // Add the line as an entry if it is passed the offset and is equal or above the log level |
|
181 | + if ($entry->level >= $minLevel) { |
|
182 | + $lines++; |
|
183 | + if ($lines > $offset) { |
|
184 | + $entries[] = $entry; |
|
185 | + $entriesCount++; |
|
186 | + } |
|
187 | + } |
|
188 | + $line = ''; |
|
189 | + } |
|
190 | + } else { |
|
191 | + $line = $ch.$line; |
|
192 | + } |
|
193 | + $pos--; |
|
194 | + } |
|
195 | + fclose($handle); |
|
196 | + } |
|
197 | + return $entries; |
|
198 | + } |
|
199 | 199 | |
200 | - /** |
|
201 | - * @return string |
|
202 | - */ |
|
203 | - public function getLogFilePath():string { |
|
204 | - return $this->logFile; |
|
205 | - } |
|
200 | + /** |
|
201 | + * @return string |
|
202 | + */ |
|
203 | + public function getLogFilePath():string { |
|
204 | + return $this->logFile; |
|
205 | + } |
|
206 | 206 | } |
@@ -31,13 +31,13 @@ |
||
31 | 31 | * @since 14.0.0 |
32 | 32 | */ |
33 | 33 | interface IFileBased { |
34 | - /** |
|
35 | - * @since 14.0.0 |
|
36 | - */ |
|
37 | - public function getLogFilePath():string; |
|
34 | + /** |
|
35 | + * @since 14.0.0 |
|
36 | + */ |
|
37 | + public function getLogFilePath():string; |
|
38 | 38 | |
39 | - /** |
|
40 | - * @since 14.0.0 |
|
41 | - */ |
|
42 | - public function getEntries(int $limit=50, int $offset=0): array; |
|
39 | + /** |
|
40 | + * @since 14.0.0 |
|
41 | + */ |
|
42 | + public function getEntries(int $limit=50, int $offset=0): array; |
|
43 | 43 | } |
@@ -55,203 +55,203 @@ |
||
55 | 55 | */ |
56 | 56 | class GetSharedSecret extends Job { |
57 | 57 | |
58 | - /** @var IClient */ |
|
59 | - private $httpClient; |
|
58 | + /** @var IClient */ |
|
59 | + private $httpClient; |
|
60 | 60 | |
61 | - /** @var IJobList */ |
|
62 | - private $jobList; |
|
61 | + /** @var IJobList */ |
|
62 | + private $jobList; |
|
63 | 63 | |
64 | - /** @var IURLGenerator */ |
|
65 | - private $urlGenerator; |
|
64 | + /** @var IURLGenerator */ |
|
65 | + private $urlGenerator; |
|
66 | 66 | |
67 | - /** @var TrustedServers */ |
|
68 | - private $trustedServers; |
|
67 | + /** @var TrustedServers */ |
|
68 | + private $trustedServers; |
|
69 | 69 | |
70 | - /** @var IDiscoveryService */ |
|
71 | - private $ocsDiscoveryService; |
|
70 | + /** @var IDiscoveryService */ |
|
71 | + private $ocsDiscoveryService; |
|
72 | 72 | |
73 | - /** @var ILogger */ |
|
74 | - private $logger; |
|
73 | + /** @var ILogger */ |
|
74 | + private $logger; |
|
75 | 75 | |
76 | - /** @var ITimeFactory */ |
|
77 | - private $timeFactory; |
|
76 | + /** @var ITimeFactory */ |
|
77 | + private $timeFactory; |
|
78 | 78 | |
79 | - /** @var bool */ |
|
80 | - protected $retainJob = false; |
|
79 | + /** @var bool */ |
|
80 | + protected $retainJob = false; |
|
81 | 81 | |
82 | - private $defaultEndPoint = '/ocs/v2.php/apps/federation/api/v1/shared-secret'; |
|
82 | + private $defaultEndPoint = '/ocs/v2.php/apps/federation/api/v1/shared-secret'; |
|
83 | 83 | |
84 | - /** @var int 30 day = 2592000sec */ |
|
85 | - private $maxLifespan = 2592000; |
|
84 | + /** @var int 30 day = 2592000sec */ |
|
85 | + private $maxLifespan = 2592000; |
|
86 | 86 | |
87 | - /** |
|
88 | - * RequestSharedSecret constructor. |
|
89 | - * |
|
90 | - * @param IClientService $httpClientService |
|
91 | - * @param IURLGenerator $urlGenerator |
|
92 | - * @param IJobList $jobList |
|
93 | - * @param TrustedServers $trustedServers |
|
94 | - * @param ILogger $logger |
|
95 | - * @param IDiscoveryService $ocsDiscoveryService |
|
96 | - * @param ITimeFactory $timeFactory |
|
97 | - */ |
|
98 | - public function __construct( |
|
99 | - IClientService $httpClientService, |
|
100 | - IURLGenerator $urlGenerator, |
|
101 | - IJobList $jobList, |
|
102 | - TrustedServers $trustedServers, |
|
103 | - ILogger $logger, |
|
104 | - IDiscoveryService $ocsDiscoveryService, |
|
105 | - ITimeFactory $timeFactory |
|
106 | - ) { |
|
107 | - $this->logger = $logger; |
|
108 | - $this->httpClient = $httpClientService->newClient(); |
|
109 | - $this->jobList = $jobList; |
|
110 | - $this->urlGenerator = $urlGenerator; |
|
111 | - $this->ocsDiscoveryService = $ocsDiscoveryService; |
|
112 | - $this->trustedServers = $trustedServers; |
|
113 | - $this->timeFactory = $timeFactory; |
|
114 | - } |
|
87 | + /** |
|
88 | + * RequestSharedSecret constructor. |
|
89 | + * |
|
90 | + * @param IClientService $httpClientService |
|
91 | + * @param IURLGenerator $urlGenerator |
|
92 | + * @param IJobList $jobList |
|
93 | + * @param TrustedServers $trustedServers |
|
94 | + * @param ILogger $logger |
|
95 | + * @param IDiscoveryService $ocsDiscoveryService |
|
96 | + * @param ITimeFactory $timeFactory |
|
97 | + */ |
|
98 | + public function __construct( |
|
99 | + IClientService $httpClientService, |
|
100 | + IURLGenerator $urlGenerator, |
|
101 | + IJobList $jobList, |
|
102 | + TrustedServers $trustedServers, |
|
103 | + ILogger $logger, |
|
104 | + IDiscoveryService $ocsDiscoveryService, |
|
105 | + ITimeFactory $timeFactory |
|
106 | + ) { |
|
107 | + $this->logger = $logger; |
|
108 | + $this->httpClient = $httpClientService->newClient(); |
|
109 | + $this->jobList = $jobList; |
|
110 | + $this->urlGenerator = $urlGenerator; |
|
111 | + $this->ocsDiscoveryService = $ocsDiscoveryService; |
|
112 | + $this->trustedServers = $trustedServers; |
|
113 | + $this->timeFactory = $timeFactory; |
|
114 | + } |
|
115 | 115 | |
116 | - /** |
|
117 | - * run the job, then remove it from the joblist |
|
118 | - * |
|
119 | - * @param JobList $jobList |
|
120 | - * @param ILogger|null $logger |
|
121 | - */ |
|
122 | - public function execute($jobList, ILogger $logger = null) { |
|
123 | - $target = $this->argument['url']; |
|
124 | - // only execute if target is still in the list of trusted domains |
|
125 | - if ($this->trustedServers->isTrustedServer($target)) { |
|
126 | - $this->parentExecute($jobList, $logger); |
|
127 | - } |
|
116 | + /** |
|
117 | + * run the job, then remove it from the joblist |
|
118 | + * |
|
119 | + * @param JobList $jobList |
|
120 | + * @param ILogger|null $logger |
|
121 | + */ |
|
122 | + public function execute($jobList, ILogger $logger = null) { |
|
123 | + $target = $this->argument['url']; |
|
124 | + // only execute if target is still in the list of trusted domains |
|
125 | + if ($this->trustedServers->isTrustedServer($target)) { |
|
126 | + $this->parentExecute($jobList, $logger); |
|
127 | + } |
|
128 | 128 | |
129 | - $jobList->remove($this, $this->argument); |
|
129 | + $jobList->remove($this, $this->argument); |
|
130 | 130 | |
131 | - if ($this->retainJob) { |
|
132 | - $this->reAddJob($this->argument); |
|
133 | - } |
|
134 | - } |
|
131 | + if ($this->retainJob) { |
|
132 | + $this->reAddJob($this->argument); |
|
133 | + } |
|
134 | + } |
|
135 | 135 | |
136 | - /** |
|
137 | - * call execute() method of parent |
|
138 | - * |
|
139 | - * @param JobList $jobList |
|
140 | - * @param ILogger $logger |
|
141 | - */ |
|
142 | - protected function parentExecute($jobList, $logger = null) { |
|
143 | - parent::execute($jobList, $logger); |
|
144 | - } |
|
136 | + /** |
|
137 | + * call execute() method of parent |
|
138 | + * |
|
139 | + * @param JobList $jobList |
|
140 | + * @param ILogger $logger |
|
141 | + */ |
|
142 | + protected function parentExecute($jobList, $logger = null) { |
|
143 | + parent::execute($jobList, $logger); |
|
144 | + } |
|
145 | 145 | |
146 | - protected function run($argument) { |
|
147 | - $target = $argument['url']; |
|
148 | - $created = isset($argument['created']) ? (int)$argument['created'] : $this->timeFactory->getTime(); |
|
149 | - $currentTime = $this->timeFactory->getTime(); |
|
150 | - $source = $this->urlGenerator->getAbsoluteURL('/'); |
|
151 | - $source = rtrim($source, '/'); |
|
152 | - $token = $argument['token']; |
|
146 | + protected function run($argument) { |
|
147 | + $target = $argument['url']; |
|
148 | + $created = isset($argument['created']) ? (int)$argument['created'] : $this->timeFactory->getTime(); |
|
149 | + $currentTime = $this->timeFactory->getTime(); |
|
150 | + $source = $this->urlGenerator->getAbsoluteURL('/'); |
|
151 | + $source = rtrim($source, '/'); |
|
152 | + $token = $argument['token']; |
|
153 | 153 | |
154 | - // kill job after 30 days of trying |
|
155 | - $deadline = $currentTime - $this->maxLifespan; |
|
156 | - if ($created < $deadline) { |
|
157 | - $this->retainJob = false; |
|
158 | - $this->trustedServers->setServerStatus($target,TrustedServers::STATUS_FAILURE); |
|
159 | - return; |
|
160 | - } |
|
154 | + // kill job after 30 days of trying |
|
155 | + $deadline = $currentTime - $this->maxLifespan; |
|
156 | + if ($created < $deadline) { |
|
157 | + $this->retainJob = false; |
|
158 | + $this->trustedServers->setServerStatus($target,TrustedServers::STATUS_FAILURE); |
|
159 | + return; |
|
160 | + } |
|
161 | 161 | |
162 | - $endPoints = $this->ocsDiscoveryService->discover($target, 'FEDERATED_SHARING'); |
|
163 | - $endPoint = isset($endPoints['shared-secret']) ? $endPoints['shared-secret'] : $this->defaultEndPoint; |
|
162 | + $endPoints = $this->ocsDiscoveryService->discover($target, 'FEDERATED_SHARING'); |
|
163 | + $endPoint = isset($endPoints['shared-secret']) ? $endPoints['shared-secret'] : $this->defaultEndPoint; |
|
164 | 164 | |
165 | - // make sure that we have a well formatted url |
|
166 | - $url = rtrim($target, '/') . '/' . trim($endPoint, '/'); |
|
165 | + // make sure that we have a well formatted url |
|
166 | + $url = rtrim($target, '/') . '/' . trim($endPoint, '/'); |
|
167 | 167 | |
168 | - $result = null; |
|
169 | - try { |
|
170 | - $result = $this->httpClient->get( |
|
171 | - $url, |
|
172 | - [ |
|
173 | - 'query' => |
|
174 | - [ |
|
175 | - 'url' => $source, |
|
176 | - 'token' => $token, |
|
177 | - 'format' => 'json', |
|
178 | - ], |
|
179 | - 'timeout' => 3, |
|
180 | - 'connect_timeout' => 3, |
|
181 | - ] |
|
182 | - ); |
|
168 | + $result = null; |
|
169 | + try { |
|
170 | + $result = $this->httpClient->get( |
|
171 | + $url, |
|
172 | + [ |
|
173 | + 'query' => |
|
174 | + [ |
|
175 | + 'url' => $source, |
|
176 | + 'token' => $token, |
|
177 | + 'format' => 'json', |
|
178 | + ], |
|
179 | + 'timeout' => 3, |
|
180 | + 'connect_timeout' => 3, |
|
181 | + ] |
|
182 | + ); |
|
183 | 183 | |
184 | - $status = $result->getStatusCode(); |
|
184 | + $status = $result->getStatusCode(); |
|
185 | 185 | |
186 | - } catch (ClientException $e) { |
|
187 | - $status = $e->getCode(); |
|
188 | - if ($status === Http::STATUS_FORBIDDEN) { |
|
189 | - $this->logger->info($target . ' refused to exchange a shared secret with you.', ['app' => 'federation']); |
|
190 | - } else { |
|
191 | - $this->logger->info($target . ' responded with a ' . $status . ' containing: ' . $e->getMessage(), ['app' => 'federation']); |
|
192 | - } |
|
193 | - } catch (RequestException $e) { |
|
194 | - $status = -1; // There is no status code if we could not connect |
|
195 | - $this->logger->logException($e, [ |
|
196 | - 'message' => 'Could not connect to ' . $target, |
|
197 | - 'level' => ILogger::INFO, |
|
198 | - 'app' => 'federation', |
|
199 | - ]); |
|
200 | - } catch (RingException $e) { |
|
201 | - $status = -1; // There is no status code if we could not connect |
|
202 | - $this->logger->logException($e, [ |
|
203 | - 'message' => 'Could not connect to ' . $target, |
|
204 | - 'level' => ILogger::INFO, |
|
205 | - 'app' => 'federation', |
|
206 | - ]); |
|
207 | - } catch (\Exception $e) { |
|
208 | - $status = Http::STATUS_INTERNAL_SERVER_ERROR; |
|
209 | - $this->logger->logException($e, ['app' => 'federation']); |
|
210 | - } |
|
186 | + } catch (ClientException $e) { |
|
187 | + $status = $e->getCode(); |
|
188 | + if ($status === Http::STATUS_FORBIDDEN) { |
|
189 | + $this->logger->info($target . ' refused to exchange a shared secret with you.', ['app' => 'federation']); |
|
190 | + } else { |
|
191 | + $this->logger->info($target . ' responded with a ' . $status . ' containing: ' . $e->getMessage(), ['app' => 'federation']); |
|
192 | + } |
|
193 | + } catch (RequestException $e) { |
|
194 | + $status = -1; // There is no status code if we could not connect |
|
195 | + $this->logger->logException($e, [ |
|
196 | + 'message' => 'Could not connect to ' . $target, |
|
197 | + 'level' => ILogger::INFO, |
|
198 | + 'app' => 'federation', |
|
199 | + ]); |
|
200 | + } catch (RingException $e) { |
|
201 | + $status = -1; // There is no status code if we could not connect |
|
202 | + $this->logger->logException($e, [ |
|
203 | + 'message' => 'Could not connect to ' . $target, |
|
204 | + 'level' => ILogger::INFO, |
|
205 | + 'app' => 'federation', |
|
206 | + ]); |
|
207 | + } catch (\Exception $e) { |
|
208 | + $status = Http::STATUS_INTERNAL_SERVER_ERROR; |
|
209 | + $this->logger->logException($e, ['app' => 'federation']); |
|
210 | + } |
|
211 | 211 | |
212 | - // if we received a unexpected response we try again later |
|
213 | - if ( |
|
214 | - $status !== Http::STATUS_OK |
|
215 | - && $status !== Http::STATUS_FORBIDDEN |
|
216 | - ) { |
|
217 | - $this->retainJob = true; |
|
218 | - } |
|
212 | + // if we received a unexpected response we try again later |
|
213 | + if ( |
|
214 | + $status !== Http::STATUS_OK |
|
215 | + && $status !== Http::STATUS_FORBIDDEN |
|
216 | + ) { |
|
217 | + $this->retainJob = true; |
|
218 | + } |
|
219 | 219 | |
220 | - if ($status === Http::STATUS_OK && $result instanceof IResponse) { |
|
221 | - $body = $result->getBody(); |
|
222 | - $result = json_decode($body, true); |
|
223 | - if (isset($result['ocs']['data']['sharedSecret'])) { |
|
224 | - $this->trustedServers->addSharedSecret( |
|
225 | - $target, |
|
226 | - $result['ocs']['data']['sharedSecret'] |
|
227 | - ); |
|
228 | - } else { |
|
229 | - $this->logger->error( |
|
230 | - 'remote server "' . $target . '"" does not return a valid shared secret. Received data: ' . $body, |
|
231 | - ['app' => 'federation'] |
|
232 | - ); |
|
233 | - $this->trustedServers->setServerStatus($target, TrustedServers::STATUS_FAILURE); |
|
234 | - } |
|
235 | - } |
|
220 | + if ($status === Http::STATUS_OK && $result instanceof IResponse) { |
|
221 | + $body = $result->getBody(); |
|
222 | + $result = json_decode($body, true); |
|
223 | + if (isset($result['ocs']['data']['sharedSecret'])) { |
|
224 | + $this->trustedServers->addSharedSecret( |
|
225 | + $target, |
|
226 | + $result['ocs']['data']['sharedSecret'] |
|
227 | + ); |
|
228 | + } else { |
|
229 | + $this->logger->error( |
|
230 | + 'remote server "' . $target . '"" does not return a valid shared secret. Received data: ' . $body, |
|
231 | + ['app' => 'federation'] |
|
232 | + ); |
|
233 | + $this->trustedServers->setServerStatus($target, TrustedServers::STATUS_FAILURE); |
|
234 | + } |
|
235 | + } |
|
236 | 236 | |
237 | - } |
|
237 | + } |
|
238 | 238 | |
239 | - /** |
|
240 | - * re-add background job |
|
241 | - * |
|
242 | - * @param array $argument |
|
243 | - */ |
|
244 | - protected function reAddJob(array $argument) { |
|
245 | - $url = $argument['url']; |
|
246 | - $created = isset($argument['created']) ? (int)$argument['created'] : $this->timeFactory->getTime(); |
|
247 | - $token = $argument['token']; |
|
248 | - $this->jobList->add( |
|
249 | - GetSharedSecret::class, |
|
250 | - [ |
|
251 | - 'url' => $url, |
|
252 | - 'token' => $token, |
|
253 | - 'created' => $created |
|
254 | - ] |
|
255 | - ); |
|
256 | - } |
|
239 | + /** |
|
240 | + * re-add background job |
|
241 | + * |
|
242 | + * @param array $argument |
|
243 | + */ |
|
244 | + protected function reAddJob(array $argument) { |
|
245 | + $url = $argument['url']; |
|
246 | + $created = isset($argument['created']) ? (int)$argument['created'] : $this->timeFactory->getTime(); |
|
247 | + $token = $argument['token']; |
|
248 | + $this->jobList->add( |
|
249 | + GetSharedSecret::class, |
|
250 | + [ |
|
251 | + 'url' => $url, |
|
252 | + 'token' => $token, |
|
253 | + 'created' => $created |
|
254 | + ] |
|
255 | + ); |
|
256 | + } |
|
257 | 257 | } |
@@ -39,28 +39,28 @@ |
||
39 | 39 | */ |
40 | 40 | class LogSettingsController extends Controller { |
41 | 41 | |
42 | - /** @var ILogger */ |
|
43 | - private $log; |
|
42 | + /** @var ILogger */ |
|
43 | + private $log; |
|
44 | 44 | |
45 | - public function __construct(string $appName, IRequest $request, ILogger $logger) { |
|
46 | - parent::__construct($appName, $request); |
|
47 | - $this->log = $logger; |
|
48 | - } |
|
45 | + public function __construct(string $appName, IRequest $request, ILogger $logger) { |
|
46 | + parent::__construct($appName, $request); |
|
47 | + $this->log = $logger; |
|
48 | + } |
|
49 | 49 | |
50 | - /** |
|
51 | - * download logfile |
|
52 | - * |
|
53 | - * @NoCSRFRequired |
|
54 | - * |
|
55 | - * @return StreamResponse |
|
56 | - */ |
|
57 | - public function download() { |
|
58 | - if(!$this->log instanceof Log) { |
|
59 | - throw new \UnexpectedValueException('Log file not available'); |
|
60 | - } |
|
61 | - $resp = new StreamResponse($this->log->getLogPath()); |
|
62 | - $resp->addHeader('Content-Type', 'application/octet-stream'); |
|
63 | - $resp->addHeader('Content-Disposition', 'attachment; filename="nextcloud.log"'); |
|
64 | - return $resp; |
|
65 | - } |
|
50 | + /** |
|
51 | + * download logfile |
|
52 | + * |
|
53 | + * @NoCSRFRequired |
|
54 | + * |
|
55 | + * @return StreamResponse |
|
56 | + */ |
|
57 | + public function download() { |
|
58 | + if(!$this->log instanceof Log) { |
|
59 | + throw new \UnexpectedValueException('Log file not available'); |
|
60 | + } |
|
61 | + $resp = new StreamResponse($this->log->getLogPath()); |
|
62 | + $resp->addHeader('Content-Type', 'application/octet-stream'); |
|
63 | + $resp->addHeader('Content-Disposition', 'attachment; filename="nextcloud.log"'); |
|
64 | + return $resp; |
|
65 | + } |
|
66 | 66 | } |
@@ -33,17 +33,17 @@ |
||
33 | 33 | * location and manage that with your own tools. |
34 | 34 | */ |
35 | 35 | class Rotate extends \OC\BackgroundJob\Job { |
36 | - use RotationTrait; |
|
36 | + use RotationTrait; |
|
37 | 37 | |
38 | - public function run($dummy) { |
|
39 | - $systemConfig = \OC::$server->getSystemConfig(); |
|
40 | - $this->filePath = $systemConfig->getValue('logfile', $systemConfig->getValue('datadirectory', \OC::$SERVERROOT . '/data') . '/nextcloud.log'); |
|
38 | + public function run($dummy) { |
|
39 | + $systemConfig = \OC::$server->getSystemConfig(); |
|
40 | + $this->filePath = $systemConfig->getValue('logfile', $systemConfig->getValue('datadirectory', \OC::$SERVERROOT . '/data') . '/nextcloud.log'); |
|
41 | 41 | |
42 | - $this->maxSize = \OC::$server->getConfig()->getSystemValue('log_rotate_size', 100 * 1024 * 1024); |
|
43 | - if($this->shouldRotateBySize()) { |
|
44 | - $rotatedFile = $this->rotate(); |
|
45 | - $msg = 'Log file "'.$this->filePath.'" was over '.$this->maxSize.' bytes, moved to "'.$rotatedFile.'"'; |
|
46 | - \OC::$server->getLogger()->warning($msg, ['app' => Rotate::class]); |
|
47 | - } |
|
48 | - } |
|
42 | + $this->maxSize = \OC::$server->getConfig()->getSystemValue('log_rotate_size', 100 * 1024 * 1024); |
|
43 | + if($this->shouldRotateBySize()) { |
|
44 | + $rotatedFile = $this->rotate(); |
|
45 | + $msg = 'Log file "'.$this->filePath.'" was over '.$this->maxSize.' bytes, moved to "'.$rotatedFile.'"'; |
|
46 | + \OC::$server->getLogger()->warning($msg, ['app' => Rotate::class]); |
|
47 | + } |
|
48 | + } |
|
49 | 49 | } |