Passed
Push — master ( 3d1c78...1b4788 )
by Blizzz
20:40 queued 05:15
created
apps/settings/lib/Controller/UsersController.php 2 patches
Indentation   +513 added lines, -513 removed lines patch added patch discarded remove patch
@@ -72,517 +72,517 @@
 block discarded – undo
72 72
 use function in_array;
73 73
 
74 74
 class UsersController extends Controller {
75
-	/** @var UserManager */
76
-	private $userManager;
77
-	/** @var GroupManager */
78
-	private $groupManager;
79
-	/** @var IUserSession */
80
-	private $userSession;
81
-	/** @var IConfig */
82
-	private $config;
83
-	/** @var bool */
84
-	private $isAdmin;
85
-	/** @var IL10N */
86
-	private $l10n;
87
-	/** @var IMailer */
88
-	private $mailer;
89
-	/** @var Factory */
90
-	private $l10nFactory;
91
-	/** @var IAppManager */
92
-	private $appManager;
93
-	/** @var IAccountManager */
94
-	private $accountManager;
95
-	/** @var Manager */
96
-	private $keyManager;
97
-	/** @var IJobList */
98
-	private $jobList;
99
-	/** @var IManager */
100
-	private $encryptionManager;
101
-	/** @var KnownUserService */
102
-	private $knownUserService;
103
-	/** @var IEventDispatcher */
104
-	private $dispatcher;
105
-
106
-
107
-	public function __construct(
108
-		string $appName,
109
-		IRequest $request,
110
-		IUserManager $userManager,
111
-		IGroupManager $groupManager,
112
-		IUserSession $userSession,
113
-		IConfig $config,
114
-		bool $isAdmin,
115
-		IL10N $l10n,
116
-		IMailer $mailer,
117
-		IFactory $l10nFactory,
118
-		IAppManager $appManager,
119
-		IAccountManager $accountManager,
120
-		Manager $keyManager,
121
-		IJobList $jobList,
122
-		IManager $encryptionManager,
123
-		KnownUserService $knownUserService,
124
-		IEventDispatcher $dispatcher
125
-	) {
126
-		parent::__construct($appName, $request);
127
-		$this->userManager = $userManager;
128
-		$this->groupManager = $groupManager;
129
-		$this->userSession = $userSession;
130
-		$this->config = $config;
131
-		$this->isAdmin = $isAdmin;
132
-		$this->l10n = $l10n;
133
-		$this->mailer = $mailer;
134
-		$this->l10nFactory = $l10nFactory;
135
-		$this->appManager = $appManager;
136
-		$this->accountManager = $accountManager;
137
-		$this->keyManager = $keyManager;
138
-		$this->jobList = $jobList;
139
-		$this->encryptionManager = $encryptionManager;
140
-		$this->knownUserService = $knownUserService;
141
-		$this->dispatcher = $dispatcher;
142
-	}
143
-
144
-
145
-	/**
146
-	 * @NoCSRFRequired
147
-	 * @NoAdminRequired
148
-	 *
149
-	 * Display users list template
150
-	 *
151
-	 * @return TemplateResponse
152
-	 */
153
-	public function usersListByGroup(): TemplateResponse {
154
-		return $this->usersList();
155
-	}
156
-
157
-	/**
158
-	 * @NoCSRFRequired
159
-	 * @NoAdminRequired
160
-	 *
161
-	 * Display users list template
162
-	 *
163
-	 * @return TemplateResponse
164
-	 */
165
-	public function usersList(): TemplateResponse {
166
-		$user = $this->userSession->getUser();
167
-		$uid = $user->getUID();
168
-
169
-		\OC::$server->getNavigationManager()->setActiveEntry('core_users');
170
-
171
-		/* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
172
-		$sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
173
-		$isLDAPUsed = false;
174
-		if ($this->config->getSystemValue('sort_groups_by_name', false)) {
175
-			$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
176
-		} else {
177
-			if ($this->appManager->isEnabledForUser('user_ldap')) {
178
-				$isLDAPUsed =
179
-					$this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
180
-				if ($isLDAPUsed) {
181
-					// LDAP user count can be slow, so we sort by group name here
182
-					$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
183
-				}
184
-			}
185
-		}
186
-
187
-		$canChangePassword = $this->canAdminChangeUserPasswords();
188
-
189
-		/* GROUPS */
190
-		$groupsInfo = new \OC\Group\MetaData(
191
-			$uid,
192
-			$this->isAdmin,
193
-			$this->groupManager,
194
-			$this->userSession
195
-		);
196
-
197
-		$groupsInfo->setSorting($sortGroupsBy);
198
-		[$adminGroup, $groups] = $groupsInfo->get();
199
-
200
-		if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
201
-			$isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
202
-				return $ldapFound || $backend instanceof User_Proxy;
203
-			});
204
-		}
205
-
206
-		$disabledUsers = -1;
207
-		$userCount = 0;
208
-
209
-		if (!$isLDAPUsed) {
210
-			if ($this->isAdmin) {
211
-				$disabledUsers = $this->userManager->countDisabledUsers();
212
-				$userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
213
-					return $v + (int)$w;
214
-				}, 0);
215
-			} else {
216
-				// User is subadmin !
217
-				// Map group list to names to retrieve the countDisabledUsersOfGroups
218
-				$userGroups = $this->groupManager->getUserGroups($user);
219
-				$groupsNames = [];
220
-
221
-				foreach ($groups as $key => $group) {
222
-					// $userCount += (int)$group['usercount'];
223
-					array_push($groupsNames, $group['name']);
224
-					// we prevent subadmins from looking up themselves
225
-					// so we lower the count of the groups he belongs to
226
-					if (array_key_exists($group['id'], $userGroups)) {
227
-						$groups[$key]['usercount']--;
228
-						$userCount -= 1; // we also lower from one the total count
229
-					}
230
-				}
231
-				$userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
232
-				$disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
233
-			}
234
-
235
-			$userCount -= $disabledUsers;
236
-		}
237
-
238
-		$disabledUsersGroup = [
239
-			'id' => 'disabled',
240
-			'name' => 'Disabled users',
241
-			'usercount' => $disabledUsers
242
-		];
243
-
244
-		/* QUOTAS PRESETS */
245
-		$quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
246
-		$defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
247
-
248
-		$event = new BeforeTemplateRenderedEvent();
249
-		$this->dispatcher->dispatch('OC\Settings\Users::loadAdditionalScripts', $event);
250
-		$this->dispatcher->dispatchTyped($event);
251
-
252
-		/* LANGUAGES */
253
-		$languages = $this->l10nFactory->getLanguages();
254
-
255
-		/* FINAL DATA */
256
-		$serverData = [];
257
-		// groups
258
-		$serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
259
-		// Various data
260
-		$serverData['isAdmin'] = $this->isAdmin;
261
-		$serverData['sortGroups'] = $sortGroupsBy;
262
-		$serverData['quotaPreset'] = $quotaPreset;
263
-		$serverData['userCount'] = $userCount;
264
-		$serverData['languages'] = $languages;
265
-		$serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
266
-		$serverData['forceLanguage'] = $this->config->getSystemValue('force_language', false);
267
-		// Settings
268
-		$serverData['defaultQuota'] = $defaultQuota;
269
-		$serverData['canChangePassword'] = $canChangePassword;
270
-		$serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
271
-		$serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
272
-		$serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
273
-
274
-		return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
275
-	}
276
-
277
-	/**
278
-	 * @param string $key
279
-	 * @param string $value
280
-	 *
281
-	 * @return JSONResponse
282
-	 */
283
-	public function setPreference(string $key, string $value): JSONResponse {
284
-		$allowed = ['newUser.sendEmail'];
285
-		if (!in_array($key, $allowed, true)) {
286
-			return new JSONResponse([], Http::STATUS_FORBIDDEN);
287
-		}
288
-
289
-		$this->config->setAppValue('core', $key, $value);
290
-
291
-		return new JSONResponse([]);
292
-	}
293
-
294
-	/**
295
-	 * Parse the app value for quota_present
296
-	 *
297
-	 * @param string $quotaPreset
298
-	 * @return array
299
-	 */
300
-	protected function parseQuotaPreset(string $quotaPreset): array {
301
-		// 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
302
-		$presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
303
-		// Drop default and none, Make array indexes numerically
304
-		return array_values(array_diff($presets, ['default', 'none']));
305
-	}
306
-
307
-	/**
308
-	 * check if the admin can change the users password
309
-	 *
310
-	 * The admin can change the passwords if:
311
-	 *
312
-	 *   - no encryption module is loaded and encryption is disabled
313
-	 *   - encryption module is loaded but it doesn't require per user keys
314
-	 *
315
-	 * The admin can not change the passwords if:
316
-	 *
317
-	 *   - an encryption module is loaded and it uses per-user keys
318
-	 *   - encryption is enabled but no encryption modules are loaded
319
-	 *
320
-	 * @return bool
321
-	 */
322
-	protected function canAdminChangeUserPasswords(): bool {
323
-		$isEncryptionEnabled = $this->encryptionManager->isEnabled();
324
-		try {
325
-			$noUserSpecificEncryptionKeys = !$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
326
-			$isEncryptionModuleLoaded = true;
327
-		} catch (ModuleDoesNotExistsException $e) {
328
-			$noUserSpecificEncryptionKeys = true;
329
-			$isEncryptionModuleLoaded = false;
330
-		}
331
-		$canChangePassword = ($isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys)
332
-			|| (!$isEncryptionModuleLoaded && !$isEncryptionEnabled);
333
-
334
-		return $canChangePassword;
335
-	}
336
-
337
-	/**
338
-	 * @NoAdminRequired
339
-	 * @NoSubAdminRequired
340
-	 * @PasswordConfirmationRequired
341
-	 *
342
-	 * @param string|null $avatarScope
343
-	 * @param string|null $displayname
344
-	 * @param string|null $displaynameScope
345
-	 * @param string|null $phone
346
-	 * @param string|null $phoneScope
347
-	 * @param string|null $email
348
-	 * @param string|null $emailScope
349
-	 * @param string|null $website
350
-	 * @param string|null $websiteScope
351
-	 * @param string|null $address
352
-	 * @param string|null $addressScope
353
-	 * @param string|null $twitter
354
-	 * @param string|null $twitterScope
355
-	 *
356
-	 * @return DataResponse
357
-	 */
358
-	public function setUserSettings(?string $avatarScope = null,
359
-									?string $displayname = null,
360
-									?string $displaynameScope = null,
361
-									?string $phone = null,
362
-									?string $phoneScope = null,
363
-									?string $email = null,
364
-									?string $emailScope = null,
365
-									?string $website = null,
366
-									?string $websiteScope = null,
367
-									?string $address = null,
368
-									?string $addressScope = null,
369
-									?string $twitter = null,
370
-									?string $twitterScope = null
371
-	) {
372
-		$user = $this->userSession->getUser();
373
-		if (!$user instanceof IUser) {
374
-			return new DataResponse(
375
-				[
376
-					'status' => 'error',
377
-					'data' => [
378
-						'message' => $this->l10n->t('Invalid user')
379
-					]
380
-				],
381
-				Http::STATUS_UNAUTHORIZED
382
-			);
383
-		}
384
-
385
-		$email = !is_null($email) ? strtolower($email) : $email;
386
-		if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
387
-			return new DataResponse(
388
-				[
389
-					'status' => 'error',
390
-					'data' => [
391
-						'message' => $this->l10n->t('Invalid mail address')
392
-					]
393
-				],
394
-				Http::STATUS_UNPROCESSABLE_ENTITY
395
-			);
396
-		}
397
-
398
-		$userAccount = $this->accountManager->getAccount($user);
399
-		$oldPhoneValue = $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getValue();
400
-
401
-		$updatable = [
402
-			IAccountManager::PROPERTY_AVATAR => ['value' => null, 'scope' => $avatarScope],
403
-			IAccountManager::PROPERTY_DISPLAYNAME => ['value' => $displayname, 'scope' => $displaynameScope],
404
-			IAccountManager::PROPERTY_EMAIL => ['value' => $email, 'scope' => $emailScope],
405
-			IAccountManager::PROPERTY_WEBSITE => ['value' => $website, 'scope' => $websiteScope],
406
-			IAccountManager::PROPERTY_ADDRESS => ['value' => $address, 'scope' => $addressScope],
407
-			IAccountManager::PROPERTY_PHONE => ['value' => $phone, 'scope' => $phoneScope],
408
-			IAccountManager::PROPERTY_TWITTER => ['value' => $twitter, 'scope' => $twitterScope],
409
-		];
410
-		$allowUserToChangeDisplayName = $this->config->getSystemValueBool('allow_user_to_change_display_name', true);
411
-		foreach ($updatable as $property => $data) {
412
-			if ($allowUserToChangeDisplayName === false
413
-				&& in_array($property, [IAccountManager::PROPERTY_DISPLAYNAME, IAccountManager::PROPERTY_EMAIL], true)) {
414
-				continue;
415
-			}
416
-			$property = $userAccount->getProperty($property);
417
-			if (null !== $data['value']) {
418
-				$property->setValue($data['value']);
419
-			}
420
-			if (null !== $data['scope']) {
421
-				$property->setScope($data['scope']);
422
-			}
423
-		}
424
-
425
-		try {
426
-			$this->saveUserSettings($userAccount);
427
-			if ($oldPhoneValue !== $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getValue()) {
428
-				$this->knownUserService->deleteByContactUserId($user->getUID());
429
-			}
430
-			return new DataResponse(
431
-				[
432
-					'status' => 'success',
433
-					'data' => [
434
-						'userId' => $user->getUID(),
435
-						'avatarScope' => $userAccount->getProperty(IAccountManager::PROPERTY_AVATAR)->getScope(),
436
-						'displayname' => $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getValue(),
437
-						'displaynameScope' => $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getScope(),
438
-						'phone' => $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getValue(),
439
-						'phoneScope' => $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getScope(),
440
-						'email' => $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue(),
441
-						'emailScope' => $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getScope(),
442
-						'website' => $userAccount->getProperty(IAccountManager::PROPERTY_WEBSITE)->getValue(),
443
-						'websiteScope' => $userAccount->getProperty(IAccountManager::PROPERTY_WEBSITE)->getScope(),
444
-						'address' => $userAccount->getProperty(IAccountManager::PROPERTY_ADDRESS)->getValue(),
445
-						'addressScope' => $userAccount->getProperty(IAccountManager::PROPERTY_ADDRESS)->getScope(),
446
-						'twitter' => $userAccount->getProperty(IAccountManager::PROPERTY_TWITTER)->getValue(),
447
-						'twitterScope' => $userAccount->getProperty(IAccountManager::PROPERTY_TWITTER)->getScope(),
448
-						'message' => $this->l10n->t('Settings saved'),
449
-					],
450
-				],
451
-				Http::STATUS_OK
452
-			);
453
-		} catch (ForbiddenException | InvalidArgumentException | PropertyDoesNotExistException $e) {
454
-			return new DataResponse([
455
-				'status' => 'error',
456
-				'data' => [
457
-					'message' => $e->getMessage()
458
-				],
459
-			]);
460
-		}
461
-	}
462
-	/**
463
-	 * update account manager with new user data
464
-	 *
465
-	 * @throws ForbiddenException
466
-	 * @throws InvalidArgumentException
467
-	 */
468
-	protected function saveUserSettings(IAccount $userAccount): void {
469
-		// keep the user back-end up-to-date with the latest display name and email
470
-		// address
471
-		$oldDisplayName = $userAccount->getUser()->getDisplayName();
472
-		if ($oldDisplayName !== $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getValue()) {
473
-			$result = $userAccount->getUser()->setDisplayName($userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getValue());
474
-			if ($result === false) {
475
-				throw new ForbiddenException($this->l10n->t('Unable to change full name'));
476
-			}
477
-		}
478
-
479
-		$oldEmailAddress = $userAccount->getUser()->getEMailAddress();
480
-		$oldEmailAddress = strtolower((string)$oldEmailAddress);
481
-		if ($oldEmailAddress !== $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue()) {
482
-			// this is the only permission a backend provides and is also used
483
-			// for the permission of setting a email address
484
-			if (!$userAccount->getUser()->canChangeDisplayName()) {
485
-				throw new ForbiddenException($this->l10n->t('Unable to change email address'));
486
-			}
487
-			$userAccount->getUser()->setEMailAddress($userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue());
488
-		}
489
-
490
-		try {
491
-			$this->accountManager->updateAccount($userAccount);
492
-		} catch (InvalidArgumentException $e) {
493
-			if ($e->getMessage() === IAccountManager::PROPERTY_PHONE) {
494
-				throw new InvalidArgumentException($this->l10n->t('Unable to set invalid phone number'));
495
-			}
496
-			if ($e->getMessage() === IAccountManager::PROPERTY_WEBSITE) {
497
-				throw new InvalidArgumentException($this->l10n->t('Unable to set invalid website'));
498
-			}
499
-			throw new InvalidArgumentException($this->l10n->t('Some account data was invalid'));
500
-		}
501
-	}
502
-
503
-	/**
504
-	 * Set the mail address of a user
505
-	 *
506
-	 * @NoAdminRequired
507
-	 * @NoSubAdminRequired
508
-	 * @PasswordConfirmationRequired
509
-	 *
510
-	 * @param string $account
511
-	 * @param bool $onlyVerificationCode only return verification code without updating the data
512
-	 * @return DataResponse
513
-	 */
514
-	public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
515
-		$user = $this->userSession->getUser();
516
-
517
-		if ($user === null) {
518
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
519
-		}
520
-
521
-		$userAccount = $this->accountManager->getAccount($user);
522
-		$cloudId = $user->getCloudId();
523
-		$message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
524
-		$signature = $this->signMessage($user, $message);
525
-
526
-		$code = $message . ' ' . $signature;
527
-		$codeMd5 = $message . ' ' . md5($signature);
528
-
529
-		switch ($account) {
530
-			case 'verify-twitter':
531
-				$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):');
532
-				$code = $codeMd5;
533
-				$type = IAccountManager::PROPERTY_TWITTER;
534
-				break;
535
-			case 'verify-website':
536
-				$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):');
537
-				$type = IAccountManager::PROPERTY_WEBSITE;
538
-				break;
539
-			default:
540
-				return new DataResponse([], Http::STATUS_BAD_REQUEST);
541
-		}
542
-
543
-		$userProperty = $userAccount->getProperty($type);
544
-		$userProperty
545
-			->setVerified(IAccountManager::VERIFICATION_IN_PROGRESS)
546
-			->setVerificationData($signature);
547
-
548
-		if ($onlyVerificationCode === false) {
549
-			$this->accountManager->updateAccount($userAccount);
550
-
551
-			$this->jobList->add(VerifyUserData::class,
552
-				[
553
-					'verificationCode' => $code,
554
-					'data' => $userProperty->getValue(),
555
-					'type' => $type,
556
-					'uid' => $user->getUID(),
557
-					'try' => 0,
558
-					'lastRun' => $this->getCurrentTime()
559
-				]
560
-			);
561
-		}
562
-
563
-		return new DataResponse(['msg' => $msg, 'code' => $code]);
564
-	}
565
-
566
-	/**
567
-	 * get current timestamp
568
-	 *
569
-	 * @return int
570
-	 */
571
-	protected function getCurrentTime(): int {
572
-		return time();
573
-	}
574
-
575
-	/**
576
-	 * sign message with users private key
577
-	 *
578
-	 * @param IUser $user
579
-	 * @param string $message
580
-	 *
581
-	 * @return string base64 encoded signature
582
-	 */
583
-	protected function signMessage(IUser $user, string $message): string {
584
-		$privateKey = $this->keyManager->getKey($user)->getPrivate();
585
-		openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
586
-		return base64_encode($signature);
587
-	}
75
+    /** @var UserManager */
76
+    private $userManager;
77
+    /** @var GroupManager */
78
+    private $groupManager;
79
+    /** @var IUserSession */
80
+    private $userSession;
81
+    /** @var IConfig */
82
+    private $config;
83
+    /** @var bool */
84
+    private $isAdmin;
85
+    /** @var IL10N */
86
+    private $l10n;
87
+    /** @var IMailer */
88
+    private $mailer;
89
+    /** @var Factory */
90
+    private $l10nFactory;
91
+    /** @var IAppManager */
92
+    private $appManager;
93
+    /** @var IAccountManager */
94
+    private $accountManager;
95
+    /** @var Manager */
96
+    private $keyManager;
97
+    /** @var IJobList */
98
+    private $jobList;
99
+    /** @var IManager */
100
+    private $encryptionManager;
101
+    /** @var KnownUserService */
102
+    private $knownUserService;
103
+    /** @var IEventDispatcher */
104
+    private $dispatcher;
105
+
106
+
107
+    public function __construct(
108
+        string $appName,
109
+        IRequest $request,
110
+        IUserManager $userManager,
111
+        IGroupManager $groupManager,
112
+        IUserSession $userSession,
113
+        IConfig $config,
114
+        bool $isAdmin,
115
+        IL10N $l10n,
116
+        IMailer $mailer,
117
+        IFactory $l10nFactory,
118
+        IAppManager $appManager,
119
+        IAccountManager $accountManager,
120
+        Manager $keyManager,
121
+        IJobList $jobList,
122
+        IManager $encryptionManager,
123
+        KnownUserService $knownUserService,
124
+        IEventDispatcher $dispatcher
125
+    ) {
126
+        parent::__construct($appName, $request);
127
+        $this->userManager = $userManager;
128
+        $this->groupManager = $groupManager;
129
+        $this->userSession = $userSession;
130
+        $this->config = $config;
131
+        $this->isAdmin = $isAdmin;
132
+        $this->l10n = $l10n;
133
+        $this->mailer = $mailer;
134
+        $this->l10nFactory = $l10nFactory;
135
+        $this->appManager = $appManager;
136
+        $this->accountManager = $accountManager;
137
+        $this->keyManager = $keyManager;
138
+        $this->jobList = $jobList;
139
+        $this->encryptionManager = $encryptionManager;
140
+        $this->knownUserService = $knownUserService;
141
+        $this->dispatcher = $dispatcher;
142
+    }
143
+
144
+
145
+    /**
146
+     * @NoCSRFRequired
147
+     * @NoAdminRequired
148
+     *
149
+     * Display users list template
150
+     *
151
+     * @return TemplateResponse
152
+     */
153
+    public function usersListByGroup(): TemplateResponse {
154
+        return $this->usersList();
155
+    }
156
+
157
+    /**
158
+     * @NoCSRFRequired
159
+     * @NoAdminRequired
160
+     *
161
+     * Display users list template
162
+     *
163
+     * @return TemplateResponse
164
+     */
165
+    public function usersList(): TemplateResponse {
166
+        $user = $this->userSession->getUser();
167
+        $uid = $user->getUID();
168
+
169
+        \OC::$server->getNavigationManager()->setActiveEntry('core_users');
170
+
171
+        /* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
172
+        $sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
173
+        $isLDAPUsed = false;
174
+        if ($this->config->getSystemValue('sort_groups_by_name', false)) {
175
+            $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
176
+        } else {
177
+            if ($this->appManager->isEnabledForUser('user_ldap')) {
178
+                $isLDAPUsed =
179
+                    $this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
180
+                if ($isLDAPUsed) {
181
+                    // LDAP user count can be slow, so we sort by group name here
182
+                    $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
183
+                }
184
+            }
185
+        }
186
+
187
+        $canChangePassword = $this->canAdminChangeUserPasswords();
188
+
189
+        /* GROUPS */
190
+        $groupsInfo = new \OC\Group\MetaData(
191
+            $uid,
192
+            $this->isAdmin,
193
+            $this->groupManager,
194
+            $this->userSession
195
+        );
196
+
197
+        $groupsInfo->setSorting($sortGroupsBy);
198
+        [$adminGroup, $groups] = $groupsInfo->get();
199
+
200
+        if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
201
+            $isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
202
+                return $ldapFound || $backend instanceof User_Proxy;
203
+            });
204
+        }
205
+
206
+        $disabledUsers = -1;
207
+        $userCount = 0;
208
+
209
+        if (!$isLDAPUsed) {
210
+            if ($this->isAdmin) {
211
+                $disabledUsers = $this->userManager->countDisabledUsers();
212
+                $userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
213
+                    return $v + (int)$w;
214
+                }, 0);
215
+            } else {
216
+                // User is subadmin !
217
+                // Map group list to names to retrieve the countDisabledUsersOfGroups
218
+                $userGroups = $this->groupManager->getUserGroups($user);
219
+                $groupsNames = [];
220
+
221
+                foreach ($groups as $key => $group) {
222
+                    // $userCount += (int)$group['usercount'];
223
+                    array_push($groupsNames, $group['name']);
224
+                    // we prevent subadmins from looking up themselves
225
+                    // so we lower the count of the groups he belongs to
226
+                    if (array_key_exists($group['id'], $userGroups)) {
227
+                        $groups[$key]['usercount']--;
228
+                        $userCount -= 1; // we also lower from one the total count
229
+                    }
230
+                }
231
+                $userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
232
+                $disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
233
+            }
234
+
235
+            $userCount -= $disabledUsers;
236
+        }
237
+
238
+        $disabledUsersGroup = [
239
+            'id' => 'disabled',
240
+            'name' => 'Disabled users',
241
+            'usercount' => $disabledUsers
242
+        ];
243
+
244
+        /* QUOTAS PRESETS */
245
+        $quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
246
+        $defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
247
+
248
+        $event = new BeforeTemplateRenderedEvent();
249
+        $this->dispatcher->dispatch('OC\Settings\Users::loadAdditionalScripts', $event);
250
+        $this->dispatcher->dispatchTyped($event);
251
+
252
+        /* LANGUAGES */
253
+        $languages = $this->l10nFactory->getLanguages();
254
+
255
+        /* FINAL DATA */
256
+        $serverData = [];
257
+        // groups
258
+        $serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
259
+        // Various data
260
+        $serverData['isAdmin'] = $this->isAdmin;
261
+        $serverData['sortGroups'] = $sortGroupsBy;
262
+        $serverData['quotaPreset'] = $quotaPreset;
263
+        $serverData['userCount'] = $userCount;
264
+        $serverData['languages'] = $languages;
265
+        $serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
266
+        $serverData['forceLanguage'] = $this->config->getSystemValue('force_language', false);
267
+        // Settings
268
+        $serverData['defaultQuota'] = $defaultQuota;
269
+        $serverData['canChangePassword'] = $canChangePassword;
270
+        $serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
271
+        $serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
272
+        $serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
273
+
274
+        return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
275
+    }
276
+
277
+    /**
278
+     * @param string $key
279
+     * @param string $value
280
+     *
281
+     * @return JSONResponse
282
+     */
283
+    public function setPreference(string $key, string $value): JSONResponse {
284
+        $allowed = ['newUser.sendEmail'];
285
+        if (!in_array($key, $allowed, true)) {
286
+            return new JSONResponse([], Http::STATUS_FORBIDDEN);
287
+        }
288
+
289
+        $this->config->setAppValue('core', $key, $value);
290
+
291
+        return new JSONResponse([]);
292
+    }
293
+
294
+    /**
295
+     * Parse the app value for quota_present
296
+     *
297
+     * @param string $quotaPreset
298
+     * @return array
299
+     */
300
+    protected function parseQuotaPreset(string $quotaPreset): array {
301
+        // 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
302
+        $presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
303
+        // Drop default and none, Make array indexes numerically
304
+        return array_values(array_diff($presets, ['default', 'none']));
305
+    }
306
+
307
+    /**
308
+     * check if the admin can change the users password
309
+     *
310
+     * The admin can change the passwords if:
311
+     *
312
+     *   - no encryption module is loaded and encryption is disabled
313
+     *   - encryption module is loaded but it doesn't require per user keys
314
+     *
315
+     * The admin can not change the passwords if:
316
+     *
317
+     *   - an encryption module is loaded and it uses per-user keys
318
+     *   - encryption is enabled but no encryption modules are loaded
319
+     *
320
+     * @return bool
321
+     */
322
+    protected function canAdminChangeUserPasswords(): bool {
323
+        $isEncryptionEnabled = $this->encryptionManager->isEnabled();
324
+        try {
325
+            $noUserSpecificEncryptionKeys = !$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
326
+            $isEncryptionModuleLoaded = true;
327
+        } catch (ModuleDoesNotExistsException $e) {
328
+            $noUserSpecificEncryptionKeys = true;
329
+            $isEncryptionModuleLoaded = false;
330
+        }
331
+        $canChangePassword = ($isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys)
332
+            || (!$isEncryptionModuleLoaded && !$isEncryptionEnabled);
333
+
334
+        return $canChangePassword;
335
+    }
336
+
337
+    /**
338
+     * @NoAdminRequired
339
+     * @NoSubAdminRequired
340
+     * @PasswordConfirmationRequired
341
+     *
342
+     * @param string|null $avatarScope
343
+     * @param string|null $displayname
344
+     * @param string|null $displaynameScope
345
+     * @param string|null $phone
346
+     * @param string|null $phoneScope
347
+     * @param string|null $email
348
+     * @param string|null $emailScope
349
+     * @param string|null $website
350
+     * @param string|null $websiteScope
351
+     * @param string|null $address
352
+     * @param string|null $addressScope
353
+     * @param string|null $twitter
354
+     * @param string|null $twitterScope
355
+     *
356
+     * @return DataResponse
357
+     */
358
+    public function setUserSettings(?string $avatarScope = null,
359
+                                    ?string $displayname = null,
360
+                                    ?string $displaynameScope = null,
361
+                                    ?string $phone = null,
362
+                                    ?string $phoneScope = null,
363
+                                    ?string $email = null,
364
+                                    ?string $emailScope = null,
365
+                                    ?string $website = null,
366
+                                    ?string $websiteScope = null,
367
+                                    ?string $address = null,
368
+                                    ?string $addressScope = null,
369
+                                    ?string $twitter = null,
370
+                                    ?string $twitterScope = null
371
+    ) {
372
+        $user = $this->userSession->getUser();
373
+        if (!$user instanceof IUser) {
374
+            return new DataResponse(
375
+                [
376
+                    'status' => 'error',
377
+                    'data' => [
378
+                        'message' => $this->l10n->t('Invalid user')
379
+                    ]
380
+                ],
381
+                Http::STATUS_UNAUTHORIZED
382
+            );
383
+        }
384
+
385
+        $email = !is_null($email) ? strtolower($email) : $email;
386
+        if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
387
+            return new DataResponse(
388
+                [
389
+                    'status' => 'error',
390
+                    'data' => [
391
+                        'message' => $this->l10n->t('Invalid mail address')
392
+                    ]
393
+                ],
394
+                Http::STATUS_UNPROCESSABLE_ENTITY
395
+            );
396
+        }
397
+
398
+        $userAccount = $this->accountManager->getAccount($user);
399
+        $oldPhoneValue = $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getValue();
400
+
401
+        $updatable = [
402
+            IAccountManager::PROPERTY_AVATAR => ['value' => null, 'scope' => $avatarScope],
403
+            IAccountManager::PROPERTY_DISPLAYNAME => ['value' => $displayname, 'scope' => $displaynameScope],
404
+            IAccountManager::PROPERTY_EMAIL => ['value' => $email, 'scope' => $emailScope],
405
+            IAccountManager::PROPERTY_WEBSITE => ['value' => $website, 'scope' => $websiteScope],
406
+            IAccountManager::PROPERTY_ADDRESS => ['value' => $address, 'scope' => $addressScope],
407
+            IAccountManager::PROPERTY_PHONE => ['value' => $phone, 'scope' => $phoneScope],
408
+            IAccountManager::PROPERTY_TWITTER => ['value' => $twitter, 'scope' => $twitterScope],
409
+        ];
410
+        $allowUserToChangeDisplayName = $this->config->getSystemValueBool('allow_user_to_change_display_name', true);
411
+        foreach ($updatable as $property => $data) {
412
+            if ($allowUserToChangeDisplayName === false
413
+                && in_array($property, [IAccountManager::PROPERTY_DISPLAYNAME, IAccountManager::PROPERTY_EMAIL], true)) {
414
+                continue;
415
+            }
416
+            $property = $userAccount->getProperty($property);
417
+            if (null !== $data['value']) {
418
+                $property->setValue($data['value']);
419
+            }
420
+            if (null !== $data['scope']) {
421
+                $property->setScope($data['scope']);
422
+            }
423
+        }
424
+
425
+        try {
426
+            $this->saveUserSettings($userAccount);
427
+            if ($oldPhoneValue !== $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getValue()) {
428
+                $this->knownUserService->deleteByContactUserId($user->getUID());
429
+            }
430
+            return new DataResponse(
431
+                [
432
+                    'status' => 'success',
433
+                    'data' => [
434
+                        'userId' => $user->getUID(),
435
+                        'avatarScope' => $userAccount->getProperty(IAccountManager::PROPERTY_AVATAR)->getScope(),
436
+                        'displayname' => $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getValue(),
437
+                        'displaynameScope' => $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getScope(),
438
+                        'phone' => $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getValue(),
439
+                        'phoneScope' => $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getScope(),
440
+                        'email' => $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue(),
441
+                        'emailScope' => $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getScope(),
442
+                        'website' => $userAccount->getProperty(IAccountManager::PROPERTY_WEBSITE)->getValue(),
443
+                        'websiteScope' => $userAccount->getProperty(IAccountManager::PROPERTY_WEBSITE)->getScope(),
444
+                        'address' => $userAccount->getProperty(IAccountManager::PROPERTY_ADDRESS)->getValue(),
445
+                        'addressScope' => $userAccount->getProperty(IAccountManager::PROPERTY_ADDRESS)->getScope(),
446
+                        'twitter' => $userAccount->getProperty(IAccountManager::PROPERTY_TWITTER)->getValue(),
447
+                        'twitterScope' => $userAccount->getProperty(IAccountManager::PROPERTY_TWITTER)->getScope(),
448
+                        'message' => $this->l10n->t('Settings saved'),
449
+                    ],
450
+                ],
451
+                Http::STATUS_OK
452
+            );
453
+        } catch (ForbiddenException | InvalidArgumentException | PropertyDoesNotExistException $e) {
454
+            return new DataResponse([
455
+                'status' => 'error',
456
+                'data' => [
457
+                    'message' => $e->getMessage()
458
+                ],
459
+            ]);
460
+        }
461
+    }
462
+    /**
463
+     * update account manager with new user data
464
+     *
465
+     * @throws ForbiddenException
466
+     * @throws InvalidArgumentException
467
+     */
468
+    protected function saveUserSettings(IAccount $userAccount): void {
469
+        // keep the user back-end up-to-date with the latest display name and email
470
+        // address
471
+        $oldDisplayName = $userAccount->getUser()->getDisplayName();
472
+        if ($oldDisplayName !== $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getValue()) {
473
+            $result = $userAccount->getUser()->setDisplayName($userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getValue());
474
+            if ($result === false) {
475
+                throw new ForbiddenException($this->l10n->t('Unable to change full name'));
476
+            }
477
+        }
478
+
479
+        $oldEmailAddress = $userAccount->getUser()->getEMailAddress();
480
+        $oldEmailAddress = strtolower((string)$oldEmailAddress);
481
+        if ($oldEmailAddress !== $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue()) {
482
+            // this is the only permission a backend provides and is also used
483
+            // for the permission of setting a email address
484
+            if (!$userAccount->getUser()->canChangeDisplayName()) {
485
+                throw new ForbiddenException($this->l10n->t('Unable to change email address'));
486
+            }
487
+            $userAccount->getUser()->setEMailAddress($userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue());
488
+        }
489
+
490
+        try {
491
+            $this->accountManager->updateAccount($userAccount);
492
+        } catch (InvalidArgumentException $e) {
493
+            if ($e->getMessage() === IAccountManager::PROPERTY_PHONE) {
494
+                throw new InvalidArgumentException($this->l10n->t('Unable to set invalid phone number'));
495
+            }
496
+            if ($e->getMessage() === IAccountManager::PROPERTY_WEBSITE) {
497
+                throw new InvalidArgumentException($this->l10n->t('Unable to set invalid website'));
498
+            }
499
+            throw new InvalidArgumentException($this->l10n->t('Some account data was invalid'));
500
+        }
501
+    }
502
+
503
+    /**
504
+     * Set the mail address of a user
505
+     *
506
+     * @NoAdminRequired
507
+     * @NoSubAdminRequired
508
+     * @PasswordConfirmationRequired
509
+     *
510
+     * @param string $account
511
+     * @param bool $onlyVerificationCode only return verification code without updating the data
512
+     * @return DataResponse
513
+     */
514
+    public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
515
+        $user = $this->userSession->getUser();
516
+
517
+        if ($user === null) {
518
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
519
+        }
520
+
521
+        $userAccount = $this->accountManager->getAccount($user);
522
+        $cloudId = $user->getCloudId();
523
+        $message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
524
+        $signature = $this->signMessage($user, $message);
525
+
526
+        $code = $message . ' ' . $signature;
527
+        $codeMd5 = $message . ' ' . md5($signature);
528
+
529
+        switch ($account) {
530
+            case 'verify-twitter':
531
+                $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):');
532
+                $code = $codeMd5;
533
+                $type = IAccountManager::PROPERTY_TWITTER;
534
+                break;
535
+            case 'verify-website':
536
+                $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):');
537
+                $type = IAccountManager::PROPERTY_WEBSITE;
538
+                break;
539
+            default:
540
+                return new DataResponse([], Http::STATUS_BAD_REQUEST);
541
+        }
542
+
543
+        $userProperty = $userAccount->getProperty($type);
544
+        $userProperty
545
+            ->setVerified(IAccountManager::VERIFICATION_IN_PROGRESS)
546
+            ->setVerificationData($signature);
547
+
548
+        if ($onlyVerificationCode === false) {
549
+            $this->accountManager->updateAccount($userAccount);
550
+
551
+            $this->jobList->add(VerifyUserData::class,
552
+                [
553
+                    'verificationCode' => $code,
554
+                    'data' => $userProperty->getValue(),
555
+                    'type' => $type,
556
+                    'uid' => $user->getUID(),
557
+                    'try' => 0,
558
+                    'lastRun' => $this->getCurrentTime()
559
+                ]
560
+            );
561
+        }
562
+
563
+        return new DataResponse(['msg' => $msg, 'code' => $code]);
564
+    }
565
+
566
+    /**
567
+     * get current timestamp
568
+     *
569
+     * @return int
570
+     */
571
+    protected function getCurrentTime(): int {
572
+        return time();
573
+    }
574
+
575
+    /**
576
+     * sign message with users private key
577
+     *
578
+     * @param IUser $user
579
+     * @param string $message
580
+     *
581
+     * @return string base64 encoded signature
582
+     */
583
+    protected function signMessage(IUser $user, string $message): string {
584
+        $privateKey = $this->keyManager->getKey($user)->getPrivate();
585
+        openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
586
+        return base64_encode($signature);
587
+    }
588 588
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -198,7 +198,7 @@  discard block
 block discarded – undo
198 198
 		[$adminGroup, $groups] = $groupsInfo->get();
199 199
 
200 200
 		if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
201
-			$isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
201
+			$isLDAPUsed = (bool) array_reduce($this->userManager->getBackends(), function($ldapFound, $backend) {
202 202
 				return $ldapFound || $backend instanceof User_Proxy;
203 203
 			});
204 204
 		}
@@ -209,8 +209,8 @@  discard block
 block discarded – undo
209 209
 		if (!$isLDAPUsed) {
210 210
 			if ($this->isAdmin) {
211 211
 				$disabledUsers = $this->userManager->countDisabledUsers();
212
-				$userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
213
-					return $v + (int)$w;
212
+				$userCount = array_reduce($this->userManager->countUsers(), function($v, $w) {
213
+					return $v + (int) $w;
214 214
 				}, 0);
215 215
 			} else {
216 216
 				// User is subadmin !
@@ -477,7 +477,7 @@  discard block
 block discarded – undo
477 477
 		}
478 478
 
479 479
 		$oldEmailAddress = $userAccount->getUser()->getEMailAddress();
480
-		$oldEmailAddress = strtolower((string)$oldEmailAddress);
480
+		$oldEmailAddress = strtolower((string) $oldEmailAddress);
481 481
 		if ($oldEmailAddress !== $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue()) {
482 482
 			// this is the only permission a backend provides and is also used
483 483
 			// for the permission of setting a email address
@@ -520,11 +520,11 @@  discard block
 block discarded – undo
520 520
 
521 521
 		$userAccount = $this->accountManager->getAccount($user);
522 522
 		$cloudId = $user->getCloudId();
523
-		$message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
523
+		$message = 'Use my Federated Cloud ID to share with me: '.$cloudId;
524 524
 		$signature = $this->signMessage($user, $message);
525 525
 
526
-		$code = $message . ' ' . $signature;
527
-		$codeMd5 = $message . ' ' . md5($signature);
526
+		$code = $message.' '.$signature;
527
+		$codeMd5 = $message.' '.md5($signature);
528 528
 
529 529
 		switch ($account) {
530 530
 			case 'verify-twitter':
Please login to merge, or discard this patch.
lib/public/Accounts/IAccountProperty.php 1 patch
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -35,84 +35,84 @@
 block discarded – undo
35 35
  */
36 36
 interface IAccountProperty extends \JsonSerializable {
37 37
 
38
-	/**
39
-	 * Set the value of a property
40
-	 *
41
-	 * @since 15.0.0
42
-	 *
43
-	 * @param string $value
44
-	 * @return IAccountProperty
45
-	 */
46
-	public function setValue(string $value): IAccountProperty;
38
+    /**
39
+     * Set the value of a property
40
+     *
41
+     * @since 15.0.0
42
+     *
43
+     * @param string $value
44
+     * @return IAccountProperty
45
+     */
46
+    public function setValue(string $value): IAccountProperty;
47 47
 
48
-	/**
49
-	 * Set the scope of a property
50
-	 *
51
-	 * @since 15.0.0
52
-	 *
53
-	 * @param string $scope
54
-	 * @return IAccountProperty
55
-	 * @throws InvalidArgumentException (since 22.0.0)
56
-	 */
57
-	public function setScope(string $scope): IAccountProperty;
48
+    /**
49
+     * Set the scope of a property
50
+     *
51
+     * @since 15.0.0
52
+     *
53
+     * @param string $scope
54
+     * @return IAccountProperty
55
+     * @throws InvalidArgumentException (since 22.0.0)
56
+     */
57
+    public function setScope(string $scope): IAccountProperty;
58 58
 
59
-	/**
60
-	 * Set the verification status of a property
61
-	 *
62
-	 * @since 15.0.0
63
-	 *
64
-	 * @param string $verified
65
-	 * @return IAccountProperty
66
-	 */
67
-	public function setVerified(string $verified): IAccountProperty;
59
+    /**
60
+     * Set the verification status of a property
61
+     *
62
+     * @since 15.0.0
63
+     *
64
+     * @param string $verified
65
+     * @return IAccountProperty
66
+     */
67
+    public function setVerified(string $verified): IAccountProperty;
68 68
 
69
-	/**
70
-	 * Get the name of a property
71
-	 *
72
-	 * @since 15.0.0
73
-	 *
74
-	 * @return string
75
-	 */
76
-	public function getName(): string;
69
+    /**
70
+     * Get the name of a property
71
+     *
72
+     * @since 15.0.0
73
+     *
74
+     * @return string
75
+     */
76
+    public function getName(): string;
77 77
 
78
-	/**
79
-	 * Get the value of a property
80
-	 *
81
-	 * @since 15.0.0
82
-	 *
83
-	 * @return string
84
-	 */
85
-	public function getValue(): string;
78
+    /**
79
+     * Get the value of a property
80
+     *
81
+     * @since 15.0.0
82
+     *
83
+     * @return string
84
+     */
85
+    public function getValue(): string;
86 86
 
87
-	/**
88
-	 * Get the scope of a property
89
-	 *
90
-	 * @since 15.0.0
91
-	 *
92
-	 * @return string
93
-	 */
94
-	public function getScope(): string;
87
+    /**
88
+     * Get the scope of a property
89
+     *
90
+     * @since 15.0.0
91
+     *
92
+     * @return string
93
+     */
94
+    public function getScope(): string;
95 95
 
96
-	/**
97
-	 * Get the verification status of a property
98
-	 *
99
-	 * @since 15.0.0
100
-	 *
101
-	 * @return string
102
-	 */
103
-	public function getVerified(): string;
96
+    /**
97
+     * Get the verification status of a property
98
+     *
99
+     * @since 15.0.0
100
+     *
101
+     * @return string
102
+     */
103
+    public function getVerified(): string;
104 104
 
105
-	/**
106
-	 * Sets data for verification purposes.
107
-	 *
108
-	 * @since 22.0.0
109
-	 */
110
-	public function setVerificationData(string $verificationData): IAccountProperty;
105
+    /**
106
+     * Sets data for verification purposes.
107
+     *
108
+     * @since 22.0.0
109
+     */
110
+    public function setVerificationData(string $verificationData): IAccountProperty;
111 111
 
112
-	/**
113
-	 * Retrieves data for verification purposes.
114
-	 *
115
-	 * @since 22.0.0
116
-	 */
117
-	public function getVerificationData(): string;
112
+    /**
113
+     * Retrieves data for verification purposes.
114
+     *
115
+     * @since 22.0.0
116
+     */
117
+    public function getVerificationData(): string;
118 118
 }
Please login to merge, or discard this patch.
lib/public/Accounts/IAccount.php 1 patch
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -35,57 +35,57 @@
 block discarded – undo
35 35
  */
36 36
 interface IAccount extends \JsonSerializable {
37 37
 
38
-	/**
39
-	 * Set a property with data
40
-	 *
41
-	 * @since 15.0.0
42
-	 *
43
-	 * @param string $property  Must be one of the PROPERTY_ prefixed constants of \OCP\Accounts\IAccountManager
44
-	 * @param string $value
45
-	 * @param string $scope Must be one of the VISIBILITY_ prefixed constants of \OCP\Accounts\IAccountManager
46
-	 * @param string $verified \OCP\Accounts\IAccountManager::NOT_VERIFIED | \OCP\Accounts\IAccountManager::VERIFICATION_IN_PROGRESS | \OCP\Accounts\IAccountManager::VERIFIED
47
-	 * @param string $verificationData Optional, defaults to empty string. Since @22.0.0.
48
-	 * @return IAccount
49
-	 */
50
-	public function setProperty(string $property, string $value, string $scope, string $verified, string $verificationData = ''): IAccount;
38
+    /**
39
+     * Set a property with data
40
+     *
41
+     * @since 15.0.0
42
+     *
43
+     * @param string $property  Must be one of the PROPERTY_ prefixed constants of \OCP\Accounts\IAccountManager
44
+     * @param string $value
45
+     * @param string $scope Must be one of the VISIBILITY_ prefixed constants of \OCP\Accounts\IAccountManager
46
+     * @param string $verified \OCP\Accounts\IAccountManager::NOT_VERIFIED | \OCP\Accounts\IAccountManager::VERIFICATION_IN_PROGRESS | \OCP\Accounts\IAccountManager::VERIFIED
47
+     * @param string $verificationData Optional, defaults to empty string. Since @22.0.0.
48
+     * @return IAccount
49
+     */
50
+    public function setProperty(string $property, string $value, string $scope, string $verified, string $verificationData = ''): IAccount;
51 51
 
52
-	/**
53
-	 * Get a property by its key
54
-	 *
55
-	 * @since 15.0.0
56
-	 *
57
-	 * @param string $property Must be one of the PROPERTY_ prefixed constants of \OCP\Accounts\IAccountManager
58
-	 * @return IAccountProperty
59
-	 * @throws PropertyDoesNotExistException
60
-	 */
61
-	public function getProperty(string $property): IAccountProperty;
52
+    /**
53
+     * Get a property by its key
54
+     *
55
+     * @since 15.0.0
56
+     *
57
+     * @param string $property Must be one of the PROPERTY_ prefixed constants of \OCP\Accounts\IAccountManager
58
+     * @return IAccountProperty
59
+     * @throws PropertyDoesNotExistException
60
+     */
61
+    public function getProperty(string $property): IAccountProperty;
62 62
 
63
-	/**
64
-	 * Get all properties of an account. Array indices are property names.
65
-	 *
66
-	 * @since 15.0.0
67
-	 *
68
-	 * @return IAccountProperty[]
69
-	 */
70
-	public function getProperties(): array;
63
+    /**
64
+     * Get all properties of an account. Array indices are property names.
65
+     *
66
+     * @since 15.0.0
67
+     *
68
+     * @return IAccountProperty[]
69
+     */
70
+    public function getProperties(): array;
71 71
 
72
-	/**
73
-	 * Get all properties that match the provided filters for scope and verification status
74
-	 *
75
-	 * @since 15.0.0
76
-	 *
77
-	 * @param string $scope Must be one of the VISIBILITY_ prefixed constants of \OCP\Accounts\IAccountManager
78
-	 * @param string $verified \OCP\Accounts\IAccountManager::NOT_VERIFIED | \OCP\Accounts\IAccountManager::VERIFICATION_IN_PROGRESS | \OCP\Accounts\IAccountManager::VERIFIED
79
-	 * @return IAccountProperty[]
80
-	 */
81
-	public function getFilteredProperties(string $scope = null, string $verified = null): array;
72
+    /**
73
+     * Get all properties that match the provided filters for scope and verification status
74
+     *
75
+     * @since 15.0.0
76
+     *
77
+     * @param string $scope Must be one of the VISIBILITY_ prefixed constants of \OCP\Accounts\IAccountManager
78
+     * @param string $verified \OCP\Accounts\IAccountManager::NOT_VERIFIED | \OCP\Accounts\IAccountManager::VERIFICATION_IN_PROGRESS | \OCP\Accounts\IAccountManager::VERIFIED
79
+     * @return IAccountProperty[]
80
+     */
81
+    public function getFilteredProperties(string $scope = null, string $verified = null): array;
82 82
 
83
-	/**
84
-	 * Get the related user for the account data
85
-	 *
86
-	 * @since 15.0.0
87
-	 *
88
-	 * @return IUser
89
-	 */
90
-	public function getUser(): IUser;
83
+    /**
84
+     * Get the related user for the account data
85
+     *
86
+     * @since 15.0.0
87
+     *
88
+     * @return IUser
89
+     */
90
+    public function getUser(): IUser;
91 91
 }
Please login to merge, or discard this patch.
lib/private/Accounts/AccountProperty.php 1 patch
Indentation   +146 added lines, -146 removed lines patch added patch discarded remove patch
@@ -31,150 +31,150 @@
 block discarded – undo
31 31
 
32 32
 class AccountProperty implements IAccountProperty {
33 33
 
34
-	/** @var string */
35
-	private $name;
36
-	/** @var string */
37
-	private $value;
38
-	/** @var string */
39
-	private $scope;
40
-	/** @var string */
41
-	private $verified;
42
-	/** @var string */
43
-	private $verificationData;
44
-
45
-	public function __construct(string $name, string $value, string $scope, string $verified, string $verificationData) {
46
-		$this->name = $name;
47
-		$this->value = $value;
48
-		$this->setScope($scope);
49
-		$this->verified = $verified;
50
-		$this->verificationData = $verificationData;
51
-	}
52
-
53
-	public function jsonSerialize() {
54
-		return [
55
-			'name' => $this->getName(),
56
-			'value' => $this->getValue(),
57
-			'scope' => $this->getScope(),
58
-			'verified' => $this->getVerified(),
59
-			'verificationData' => $this->getVerificationData(),
60
-		];
61
-	}
62
-
63
-	/**
64
-	 * Set the value of a property
65
-	 *
66
-	 * @since 15.0.0
67
-	 *
68
-	 * @param string $value
69
-	 * @return IAccountProperty
70
-	 */
71
-	public function setValue(string $value): IAccountProperty {
72
-		$this->value = $value;
73
-		return $this;
74
-	}
75
-
76
-	/**
77
-	 * Set the scope of a property
78
-	 *
79
-	 * @since 15.0.0
80
-	 *
81
-	 * @param string $scope
82
-	 * @return IAccountProperty
83
-	 */
84
-	public function setScope(string $scope): IAccountProperty {
85
-		$newScope = $this->mapScopeToV2($scope);
86
-		if (!in_array($newScope, [
87
-			IAccountManager::SCOPE_LOCAL,
88
-			IAccountManager::SCOPE_FEDERATED,
89
-			IAccountManager::SCOPE_PRIVATE,
90
-			IAccountManager::SCOPE_PUBLISHED
91
-		])) {
92
-			throw new \InvalidArgumentException('Invalid scope');
93
-		}
94
-		$this->scope = $newScope;
95
-		return $this;
96
-	}
97
-
98
-	/**
99
-	 * Set the verification status of a property
100
-	 *
101
-	 * @since 15.0.0
102
-	 *
103
-	 * @param string $verified
104
-	 * @return IAccountProperty
105
-	 */
106
-	public function setVerified(string $verified): IAccountProperty {
107
-		$this->verified = $verified;
108
-		return $this;
109
-	}
110
-
111
-	/**
112
-	 * Get the name of a property
113
-	 *
114
-	 * @since 15.0.0
115
-	 *
116
-	 * @return string
117
-	 */
118
-	public function getName(): string {
119
-		return $this->name;
120
-	}
121
-
122
-	/**
123
-	 * Get the value of a property
124
-	 *
125
-	 * @since 15.0.0
126
-	 *
127
-	 * @return string
128
-	 */
129
-	public function getValue(): string {
130
-		return $this->value;
131
-	}
132
-
133
-	/**
134
-	 * Get the scope of a property
135
-	 *
136
-	 * @since 15.0.0
137
-	 *
138
-	 * @return string
139
-	 */
140
-	public function getScope(): string {
141
-		return $this->scope;
142
-	}
143
-
144
-	public static function mapScopeToV2(string $scope): string {
145
-		if (strpos($scope, 'v2-') === 0) {
146
-			return $scope;
147
-		}
148
-
149
-		switch ($scope) {
150
-			case IAccountManager::VISIBILITY_PRIVATE:
151
-				return IAccountManager::SCOPE_LOCAL;
152
-			case IAccountManager::VISIBILITY_CONTACTS_ONLY:
153
-				return IAccountManager::SCOPE_FEDERATED;
154
-			case IAccountManager::VISIBILITY_PUBLIC:
155
-				return IAccountManager::SCOPE_PUBLISHED;
156
-			default:
157
-				return $scope;
158
-		}
159
-	}
160
-
161
-	/**
162
-	 * Get the verification status of a property
163
-	 *
164
-	 * @since 15.0.0
165
-	 *
166
-	 * @return string
167
-	 */
168
-	public function getVerified(): string {
169
-		return $this->verified;
170
-	}
171
-
172
-	public function setVerificationData(string $verificationData): IAccountProperty {
173
-		$this->verificationData = $verificationData;
174
-		return $this;
175
-	}
176
-
177
-	public function getVerificationData(): string {
178
-		return $this->verificationData;
179
-	}
34
+    /** @var string */
35
+    private $name;
36
+    /** @var string */
37
+    private $value;
38
+    /** @var string */
39
+    private $scope;
40
+    /** @var string */
41
+    private $verified;
42
+    /** @var string */
43
+    private $verificationData;
44
+
45
+    public function __construct(string $name, string $value, string $scope, string $verified, string $verificationData) {
46
+        $this->name = $name;
47
+        $this->value = $value;
48
+        $this->setScope($scope);
49
+        $this->verified = $verified;
50
+        $this->verificationData = $verificationData;
51
+    }
52
+
53
+    public function jsonSerialize() {
54
+        return [
55
+            'name' => $this->getName(),
56
+            'value' => $this->getValue(),
57
+            'scope' => $this->getScope(),
58
+            'verified' => $this->getVerified(),
59
+            'verificationData' => $this->getVerificationData(),
60
+        ];
61
+    }
62
+
63
+    /**
64
+     * Set the value of a property
65
+     *
66
+     * @since 15.0.0
67
+     *
68
+     * @param string $value
69
+     * @return IAccountProperty
70
+     */
71
+    public function setValue(string $value): IAccountProperty {
72
+        $this->value = $value;
73
+        return $this;
74
+    }
75
+
76
+    /**
77
+     * Set the scope of a property
78
+     *
79
+     * @since 15.0.0
80
+     *
81
+     * @param string $scope
82
+     * @return IAccountProperty
83
+     */
84
+    public function setScope(string $scope): IAccountProperty {
85
+        $newScope = $this->mapScopeToV2($scope);
86
+        if (!in_array($newScope, [
87
+            IAccountManager::SCOPE_LOCAL,
88
+            IAccountManager::SCOPE_FEDERATED,
89
+            IAccountManager::SCOPE_PRIVATE,
90
+            IAccountManager::SCOPE_PUBLISHED
91
+        ])) {
92
+            throw new \InvalidArgumentException('Invalid scope');
93
+        }
94
+        $this->scope = $newScope;
95
+        return $this;
96
+    }
97
+
98
+    /**
99
+     * Set the verification status of a property
100
+     *
101
+     * @since 15.0.0
102
+     *
103
+     * @param string $verified
104
+     * @return IAccountProperty
105
+     */
106
+    public function setVerified(string $verified): IAccountProperty {
107
+        $this->verified = $verified;
108
+        return $this;
109
+    }
110
+
111
+    /**
112
+     * Get the name of a property
113
+     *
114
+     * @since 15.0.0
115
+     *
116
+     * @return string
117
+     */
118
+    public function getName(): string {
119
+        return $this->name;
120
+    }
121
+
122
+    /**
123
+     * Get the value of a property
124
+     *
125
+     * @since 15.0.0
126
+     *
127
+     * @return string
128
+     */
129
+    public function getValue(): string {
130
+        return $this->value;
131
+    }
132
+
133
+    /**
134
+     * Get the scope of a property
135
+     *
136
+     * @since 15.0.0
137
+     *
138
+     * @return string
139
+     */
140
+    public function getScope(): string {
141
+        return $this->scope;
142
+    }
143
+
144
+    public static function mapScopeToV2(string $scope): string {
145
+        if (strpos($scope, 'v2-') === 0) {
146
+            return $scope;
147
+        }
148
+
149
+        switch ($scope) {
150
+            case IAccountManager::VISIBILITY_PRIVATE:
151
+                return IAccountManager::SCOPE_LOCAL;
152
+            case IAccountManager::VISIBILITY_CONTACTS_ONLY:
153
+                return IAccountManager::SCOPE_FEDERATED;
154
+            case IAccountManager::VISIBILITY_PUBLIC:
155
+                return IAccountManager::SCOPE_PUBLISHED;
156
+            default:
157
+                return $scope;
158
+        }
159
+    }
160
+
161
+    /**
162
+     * Get the verification status of a property
163
+     *
164
+     * @since 15.0.0
165
+     *
166
+     * @return string
167
+     */
168
+    public function getVerified(): string {
169
+        return $this->verified;
170
+    }
171
+
172
+    public function setVerificationData(string $verificationData): IAccountProperty {
173
+        $this->verificationData = $verificationData;
174
+        return $this;
175
+    }
176
+
177
+    public function getVerificationData(): string {
178
+        return $this->verificationData;
179
+    }
180 180
 }
Please login to merge, or discard this patch.
lib/private/Accounts/Account.php 1 patch
Indentation   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -34,49 +34,49 @@
 block discarded – undo
34 34
 
35 35
 class Account implements IAccount {
36 36
 
37
-	/** @var IAccountProperty[] */
38
-	private $properties = [];
37
+    /** @var IAccountProperty[] */
38
+    private $properties = [];
39 39
 
40
-	/** @var IUser */
41
-	private $user;
40
+    /** @var IUser */
41
+    private $user;
42 42
 
43
-	public function __construct(IUser $user) {
44
-		$this->user = $user;
45
-	}
43
+    public function __construct(IUser $user) {
44
+        $this->user = $user;
45
+    }
46 46
 
47
-	public function setProperty(string $property, string $value, string $scope, string $verified, string $verificationData = ''): IAccount {
48
-		$this->properties[$property] = new AccountProperty($property, $value, $scope, $verified, $verificationData);
49
-		return $this;
50
-	}
47
+    public function setProperty(string $property, string $value, string $scope, string $verified, string $verificationData = ''): IAccount {
48
+        $this->properties[$property] = new AccountProperty($property, $value, $scope, $verified, $verificationData);
49
+        return $this;
50
+    }
51 51
 
52
-	public function getProperty(string $property): IAccountProperty {
53
-		if (!array_key_exists($property, $this->properties)) {
54
-			throw new PropertyDoesNotExistException($property);
55
-		}
56
-		return $this->properties[$property];
57
-	}
52
+    public function getProperty(string $property): IAccountProperty {
53
+        if (!array_key_exists($property, $this->properties)) {
54
+            throw new PropertyDoesNotExistException($property);
55
+        }
56
+        return $this->properties[$property];
57
+    }
58 58
 
59
-	public function getProperties(): array {
60
-		return $this->properties;
61
-	}
59
+    public function getProperties(): array {
60
+        return $this->properties;
61
+    }
62 62
 
63
-	public function getFilteredProperties(string $scope = null, string $verified = null): array {
64
-		return \array_filter($this->properties, function (IAccountProperty $obj) use ($scope, $verified) {
65
-			if ($scope !== null && $scope !== $obj->getScope()) {
66
-				return false;
67
-			}
68
-			if ($verified !== null && $verified !== $obj->getVerified()) {
69
-				return false;
70
-			}
71
-			return true;
72
-		});
73
-	}
63
+    public function getFilteredProperties(string $scope = null, string $verified = null): array {
64
+        return \array_filter($this->properties, function (IAccountProperty $obj) use ($scope, $verified) {
65
+            if ($scope !== null && $scope !== $obj->getScope()) {
66
+                return false;
67
+            }
68
+            if ($verified !== null && $verified !== $obj->getVerified()) {
69
+                return false;
70
+            }
71
+            return true;
72
+        });
73
+    }
74 74
 
75
-	public function jsonSerialize() {
76
-		return $this->properties;
77
-	}
75
+    public function jsonSerialize() {
76
+        return $this->properties;
77
+    }
78 78
 
79
-	public function getUser(): IUser {
80
-		return $this->user;
81
-	}
79
+    public function getUser(): IUser {
80
+        return $this->user;
81
+    }
82 82
 }
Please login to merge, or discard this patch.