Passed
Push — master ( 6c7417...7e1c84 )
by Blizzz
15:57 queued 11s
created
apps/provisioning_api/lib/Controller/UsersController.php 2 patches
Indentation   +1081 added lines, -1081 removed lines patch added patch discarded remove patch
@@ -75,1085 +75,1085 @@
 block discarded – undo
75 75
 
76 76
 class UsersController extends AUserData {
77 77
 
78
-	/** @var IAppManager */
79
-	private $appManager;
80
-	/** @var IURLGenerator */
81
-	protected $urlGenerator;
82
-	/** @var LoggerInterface */
83
-	private $logger;
84
-	/** @var IFactory */
85
-	protected $l10nFactory;
86
-	/** @var NewUserMailHelper */
87
-	private $newUserMailHelper;
88
-	/** @var ISecureRandom */
89
-	private $secureRandom;
90
-	/** @var RemoteWipe */
91
-	private $remoteWipe;
92
-	/** @var KnownUserService */
93
-	private $knownUserService;
94
-	/** @var IEventDispatcher */
95
-	private $eventDispatcher;
96
-
97
-	public function __construct(string $appName,
98
-								IRequest $request,
99
-								IUserManager $userManager,
100
-								IConfig $config,
101
-								IAppManager $appManager,
102
-								IGroupManager $groupManager,
103
-								IUserSession $userSession,
104
-								IAccountManager $accountManager,
105
-								IURLGenerator $urlGenerator,
106
-								LoggerInterface $logger,
107
-								IFactory $l10nFactory,
108
-								NewUserMailHelper $newUserMailHelper,
109
-								ISecureRandom $secureRandom,
110
-								RemoteWipe $remoteWipe,
111
-								KnownUserService $knownUserService,
112
-								IEventDispatcher $eventDispatcher) {
113
-		parent::__construct($appName,
114
-							$request,
115
-							$userManager,
116
-							$config,
117
-							$groupManager,
118
-							$userSession,
119
-							$accountManager,
120
-							$l10nFactory);
121
-
122
-		$this->appManager = $appManager;
123
-		$this->urlGenerator = $urlGenerator;
124
-		$this->logger = $logger;
125
-		$this->l10nFactory = $l10nFactory;
126
-		$this->newUserMailHelper = $newUserMailHelper;
127
-		$this->secureRandom = $secureRandom;
128
-		$this->remoteWipe = $remoteWipe;
129
-		$this->knownUserService = $knownUserService;
130
-		$this->eventDispatcher = $eventDispatcher;
131
-	}
132
-
133
-	/**
134
-	 * @NoAdminRequired
135
-	 *
136
-	 * returns a list of users
137
-	 *
138
-	 * @param string $search
139
-	 * @param int $limit
140
-	 * @param int $offset
141
-	 * @return DataResponse
142
-	 */
143
-	public function getUsers(string $search = '', int $limit = null, int $offset = 0): DataResponse {
144
-		$user = $this->userSession->getUser();
145
-		$users = [];
146
-
147
-		// Admin? Or SubAdmin?
148
-		$uid = $user->getUID();
149
-		$subAdminManager = $this->groupManager->getSubAdmin();
150
-		if ($this->groupManager->isAdmin($uid)) {
151
-			$users = $this->userManager->search($search, $limit, $offset);
152
-		} elseif ($subAdminManager->isSubAdmin($user)) {
153
-			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
154
-			foreach ($subAdminOfGroups as $key => $group) {
155
-				$subAdminOfGroups[$key] = $group->getGID();
156
-			}
157
-
158
-			$users = [];
159
-			foreach ($subAdminOfGroups as $group) {
160
-				$users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
161
-			}
162
-		}
163
-
164
-		$users = array_keys($users);
165
-
166
-		return new DataResponse([
167
-			'users' => $users
168
-		]);
169
-	}
170
-
171
-	/**
172
-	 * @NoAdminRequired
173
-	 *
174
-	 * returns a list of users and their data
175
-	 */
176
-	public function getUsersDetails(string $search = '', int $limit = null, int $offset = 0): DataResponse {
177
-		$currentUser = $this->userSession->getUser();
178
-		$users = [];
179
-
180
-		// Admin? Or SubAdmin?
181
-		$uid = $currentUser->getUID();
182
-		$subAdminManager = $this->groupManager->getSubAdmin();
183
-		if ($this->groupManager->isAdmin($uid)) {
184
-			$users = $this->userManager->search($search, $limit, $offset);
185
-			$users = array_keys($users);
186
-		} elseif ($subAdminManager->isSubAdmin($currentUser)) {
187
-			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser);
188
-			foreach ($subAdminOfGroups as $key => $group) {
189
-				$subAdminOfGroups[$key] = $group->getGID();
190
-			}
191
-
192
-			$users = [];
193
-			foreach ($subAdminOfGroups as $group) {
194
-				$users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
195
-			}
196
-			$users = array_merge(...$users);
197
-		}
198
-
199
-		$usersDetails = [];
200
-		foreach ($users as $userId) {
201
-			$userId = (string) $userId;
202
-			$userData = $this->getUserData($userId);
203
-			// Do not insert empty entry
204
-			if (!empty($userData)) {
205
-				$usersDetails[$userId] = $userData;
206
-			} else {
207
-				// Logged user does not have permissions to see this user
208
-				// only showing its id
209
-				$usersDetails[$userId] = ['id' => $userId];
210
-			}
211
-		}
212
-
213
-		return new DataResponse([
214
-			'users' => $usersDetails
215
-		]);
216
-	}
217
-
218
-
219
-	/**
220
-	 * @NoAdminRequired
221
-	 * @NoSubAdminRequired
222
-	 *
223
-	 * @param string $location
224
-	 * @param array $search
225
-	 * @return DataResponse
226
-	 */
227
-	public function searchByPhoneNumbers(string $location, array $search): DataResponse {
228
-		$phoneUtil = PhoneNumberUtil::getInstance();
229
-
230
-		if ($phoneUtil->getCountryCodeForRegion($location) === 0) {
231
-			// Not a valid region code
232
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
233
-		}
234
-
235
-		/** @var IUser $user */
236
-		$user = $this->userSession->getUser();
237
-		$knownTo = $user->getUID();
238
-		$defaultPhoneRegion = $this->config->getSystemValueString('default_phone_region');
239
-
240
-		$normalizedNumberToKey = [];
241
-		foreach ($search as $key => $phoneNumbers) {
242
-			foreach ($phoneNumbers as $phone) {
243
-				try {
244
-					$phoneNumber = $phoneUtil->parse($phone, $location);
245
-					if ($phoneNumber instanceof PhoneNumber && $phoneUtil->isValidNumber($phoneNumber)) {
246
-						$normalizedNumber = $phoneUtil->format($phoneNumber, PhoneNumberFormat::E164);
247
-						$normalizedNumberToKey[$normalizedNumber] = (string) $key;
248
-					}
249
-				} catch (NumberParseException $e) {
250
-				}
251
-
252
-				if ($defaultPhoneRegion !== '' && $defaultPhoneRegion !== $location && strpos($phone, '0') === 0) {
253
-					// If the number has a leading zero (no country code),
254
-					// we also check the default phone region of the instance,
255
-					// when it's different to the user's given region.
256
-					try {
257
-						$phoneNumber = $phoneUtil->parse($phone, $defaultPhoneRegion);
258
-						if ($phoneNumber instanceof PhoneNumber && $phoneUtil->isValidNumber($phoneNumber)) {
259
-							$normalizedNumber = $phoneUtil->format($phoneNumber, PhoneNumberFormat::E164);
260
-							$normalizedNumberToKey[$normalizedNumber] = (string) $key;
261
-						}
262
-					} catch (NumberParseException $e) {
263
-					}
264
-				}
265
-			}
266
-		}
267
-
268
-		$phoneNumbers = array_keys($normalizedNumberToKey);
269
-
270
-		if (empty($phoneNumbers)) {
271
-			return new DataResponse();
272
-		}
273
-
274
-		// Cleanup all previous entries and only allow new matches
275
-		$this->knownUserService->deleteKnownTo($knownTo);
276
-
277
-		$userMatches = $this->accountManager->searchUsers(IAccountManager::PROPERTY_PHONE, $phoneNumbers);
278
-
279
-		if (empty($userMatches)) {
280
-			return new DataResponse();
281
-		}
282
-
283
-		$cloudUrl = rtrim($this->urlGenerator->getAbsoluteURL('/'), '/');
284
-		if (strpos($cloudUrl, 'http://') === 0) {
285
-			$cloudUrl = substr($cloudUrl, strlen('http://'));
286
-		} elseif (strpos($cloudUrl, 'https://') === 0) {
287
-			$cloudUrl = substr($cloudUrl, strlen('https://'));
288
-		}
289
-
290
-		$matches = [];
291
-		foreach ($userMatches as $phone => $userId) {
292
-			// Not using the ICloudIdManager as that would run a search for each contact to find the display name in the address book
293
-			$matches[$normalizedNumberToKey[$phone]] = $userId . '@' . $cloudUrl;
294
-			$this->knownUserService->storeIsKnownToUser($knownTo, $userId);
295
-		}
296
-
297
-		return new DataResponse($matches);
298
-	}
299
-
300
-	/**
301
-	 * @throws OCSException
302
-	 */
303
-	private function createNewUserId(): string {
304
-		$attempts = 0;
305
-		do {
306
-			$uidCandidate = $this->secureRandom->generate(10, ISecureRandom::CHAR_HUMAN_READABLE);
307
-			if (!$this->userManager->userExists($uidCandidate)) {
308
-				return $uidCandidate;
309
-			}
310
-			$attempts++;
311
-		} while ($attempts < 10);
312
-		throw new OCSException('Could not create non-existing user id', 111);
313
-	}
314
-
315
-	/**
316
-	 * @PasswordConfirmationRequired
317
-	 * @NoAdminRequired
318
-	 *
319
-	 * @param string $userid
320
-	 * @param string $password
321
-	 * @param string $displayName
322
-	 * @param string $email
323
-	 * @param array $groups
324
-	 * @param array $subadmin
325
-	 * @param string $quota
326
-	 * @param string $language
327
-	 * @return DataResponse
328
-	 * @throws OCSException
329
-	 */
330
-	public function addUser(string $userid,
331
-							string $password = '',
332
-							string $displayName = '',
333
-							string $email = '',
334
-							array $groups = [],
335
-							array $subadmin = [],
336
-							string $quota = '',
337
-							string $language = ''): DataResponse {
338
-		$user = $this->userSession->getUser();
339
-		$isAdmin = $this->groupManager->isAdmin($user->getUID());
340
-		$subAdminManager = $this->groupManager->getSubAdmin();
341
-
342
-		if (empty($userid) && $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes') {
343
-			$userid = $this->createNewUserId();
344
-		}
345
-
346
-		if ($this->userManager->userExists($userid)) {
347
-			$this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
348
-			throw new OCSException('User already exists', 102);
349
-		}
350
-
351
-		if ($groups !== []) {
352
-			foreach ($groups as $group) {
353
-				if (!$this->groupManager->groupExists($group)) {
354
-					throw new OCSException('group '.$group.' does not exist', 104);
355
-				}
356
-				if (!$isAdmin && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
357
-					throw new OCSException('insufficient privileges for group '. $group, 105);
358
-				}
359
-			}
360
-		} else {
361
-			if (!$isAdmin) {
362
-				throw new OCSException('no group specified (required for subadmins)', 106);
363
-			}
364
-		}
365
-
366
-		$subadminGroups = [];
367
-		if ($subadmin !== []) {
368
-			foreach ($subadmin as $groupid) {
369
-				$group = $this->groupManager->get($groupid);
370
-				// Check if group exists
371
-				if ($group === null) {
372
-					throw new OCSException('Subadmin group does not exist',  102);
373
-				}
374
-				// Check if trying to make subadmin of admin group
375
-				if ($group->getGID() === 'admin') {
376
-					throw new OCSException('Cannot create subadmins for admin group', 103);
377
-				}
378
-				// Check if has permission to promote subadmins
379
-				if (!$subAdminManager->isSubAdminOfGroup($user, $group) && !$isAdmin) {
380
-					throw new OCSForbiddenException('No permissions to promote subadmins');
381
-				}
382
-				$subadminGroups[] = $group;
383
-			}
384
-		}
385
-
386
-		$generatePasswordResetToken = false;
387
-		if ($password === '') {
388
-			if ($email === '') {
389
-				throw new OCSException('To send a password link to the user an email address is required.', 108);
390
-			}
391
-
392
-			$passwordEvent = new GenerateSecurePasswordEvent();
393
-			$this->eventDispatcher->dispatchTyped($passwordEvent);
394
-
395
-			$password = $passwordEvent->getPassword();
396
-			if ($password === null) {
397
-				// Fallback: ensure to pass password_policy in any case
398
-				$password = $this->secureRandom->generate(10)
399
-					. $this->secureRandom->generate(1, ISecureRandom::CHAR_UPPER)
400
-					. $this->secureRandom->generate(1, ISecureRandom::CHAR_LOWER)
401
-					. $this->secureRandom->generate(1, ISecureRandom::CHAR_DIGITS)
402
-					. $this->secureRandom->generate(1, ISecureRandom::CHAR_SYMBOLS);
403
-			}
404
-			$generatePasswordResetToken = true;
405
-		}
406
-
407
-		if ($email === '' && $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes') {
408
-			throw new OCSException('Required email address was not provided', 110);
409
-		}
410
-
411
-		try {
412
-			$newUser = $this->userManager->createUser($userid, $password);
413
-			$this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']);
414
-
415
-			foreach ($groups as $group) {
416
-				$this->groupManager->get($group)->addUser($newUser);
417
-				$this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']);
418
-			}
419
-			foreach ($subadminGroups as $group) {
420
-				$subAdminManager->createSubAdmin($newUser, $group);
421
-			}
422
-
423
-			if ($displayName !== '') {
424
-				$this->editUser($userid, 'display', $displayName);
425
-			}
426
-
427
-			if ($quota !== '') {
428
-				$this->editUser($userid, 'quota', $quota);
429
-			}
430
-
431
-			if ($language !== '') {
432
-				$this->editUser($userid, 'language', $language);
433
-			}
434
-
435
-			// Send new user mail only if a mail is set
436
-			if ($email !== '') {
437
-				$newUser->setEMailAddress($email);
438
-				if ($this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
439
-					try {
440
-						$emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
441
-						$this->newUserMailHelper->sendMail($newUser, $emailTemplate);
442
-					} catch (\Exception $e) {
443
-						// Mail could be failing hard or just be plain not configured
444
-						// Logging error as it is the hardest of the two
445
-						$this->logger->error("Unable to send the invitation mail to $email",
446
-							[
447
-								'app' => 'ocs_api',
448
-								'exception' => $e,
449
-							]
450
-						);
451
-					}
452
-				}
453
-			}
454
-
455
-			return new DataResponse(['id' => $userid]);
456
-		} catch (HintException $e) {
457
-			$this->logger->warning('Failed addUser attempt with hint exception.',
458
-				[
459
-					'app' => 'ocs_api',
460
-					'exception' => $e,
461
-				]
462
-			);
463
-			throw new OCSException($e->getHint(), 107);
464
-		} catch (OCSException $e) {
465
-			$this->logger->warning('Failed addUser attempt with ocs exeption.',
466
-				[
467
-					'app' => 'ocs_api',
468
-					'exception' => $e,
469
-				]
470
-			);
471
-			throw $e;
472
-		} catch (\InvalidArgumentException $e) {
473
-			$this->logger->error('Failed addUser attempt with invalid argument exeption.',
474
-				[
475
-					'app' => 'ocs_api',
476
-					'exception' => $e,
477
-				]
478
-			);
479
-			throw new OCSException($e->getMessage(), 101);
480
-		} catch (\Exception $e) {
481
-			$this->logger->error('Failed addUser attempt with exception.',
482
-				[
483
-					'app' => 'ocs_api',
484
-					'exception' => $e
485
-				]
486
-			);
487
-			throw new OCSException('Bad request', 101);
488
-		}
489
-	}
490
-
491
-	/**
492
-	 * @NoAdminRequired
493
-	 * @NoSubAdminRequired
494
-	 *
495
-	 * gets user info
496
-	 *
497
-	 * @param string $userId
498
-	 * @return DataResponse
499
-	 * @throws OCSException
500
-	 */
501
-	public function getUser(string $userId): DataResponse {
502
-		$includeScopes = false;
503
-		$currentUser = $this->userSession->getUser();
504
-		if ($currentUser && $currentUser->getUID() === $userId) {
505
-			$includeScopes = true;
506
-		}
507
-
508
-		$data = $this->getUserData($userId, $includeScopes);
509
-		// getUserData returns empty array if not enough permissions
510
-		if (empty($data)) {
511
-			throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
512
-		}
513
-		return new DataResponse($data);
514
-	}
515
-
516
-	/**
517
-	 * @NoAdminRequired
518
-	 * @NoSubAdminRequired
519
-	 *
520
-	 * gets user info from the currently logged in user
521
-	 *
522
-	 * @return DataResponse
523
-	 * @throws OCSException
524
-	 */
525
-	public function getCurrentUser(): DataResponse {
526
-		$user = $this->userSession->getUser();
527
-		if ($user) {
528
-			$data = $this->getUserData($user->getUID(), true);
529
-			// rename "displayname" to "display-name" only for this call to keep
530
-			// the API stable.
531
-			$data['display-name'] = $data['displayname'];
532
-			unset($data['displayname']);
533
-			return new DataResponse($data);
534
-		}
535
-
536
-		throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
537
-	}
538
-
539
-	/**
540
-	 * @NoAdminRequired
541
-	 * @NoSubAdminRequired
542
-	 *
543
-	 * @return DataResponse
544
-	 * @throws OCSException
545
-	 */
546
-	public function getEditableFields(?string $userId = null): DataResponse {
547
-		$currentLoggedInUser = $this->userSession->getUser();
548
-		if (!$currentLoggedInUser instanceof IUser) {
549
-			throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
550
-		}
551
-
552
-		$permittedFields = [];
553
-
554
-		if ($userId !== $currentLoggedInUser->getUID()) {
555
-			$targetUser = $this->userManager->get($userId);
556
-			if (!$targetUser instanceof IUser) {
557
-				throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
558
-			}
559
-
560
-			$subAdminManager = $this->groupManager->getSubAdmin();
561
-			if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID())
562
-				&& !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
563
-				throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
564
-			}
565
-		} else {
566
-			$targetUser = $currentLoggedInUser;
567
-		}
568
-
569
-		// Editing self (display, email)
570
-		if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
571
-			if ($targetUser->getBackend() instanceof ISetDisplayNameBackend
572
-				|| $targetUser->getBackend()->implementsActions(Backend::SET_DISPLAYNAME)) {
573
-				$permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME;
574
-			}
575
-			$permittedFields[] = IAccountManager::PROPERTY_EMAIL;
576
-		}
577
-
578
-		$permittedFields[] = IAccountManager::PROPERTY_PHONE;
579
-		$permittedFields[] = IAccountManager::PROPERTY_ADDRESS;
580
-		$permittedFields[] = IAccountManager::PROPERTY_WEBSITE;
581
-		$permittedFields[] = IAccountManager::PROPERTY_TWITTER;
582
-
583
-		return new DataResponse($permittedFields);
584
-	}
585
-
586
-	/**
587
-	 * @NoAdminRequired
588
-	 * @NoSubAdminRequired
589
-	 * @PasswordConfirmationRequired
590
-	 *
591
-	 * edit users
592
-	 *
593
-	 * @param string $userId
594
-	 * @param string $key
595
-	 * @param string $value
596
-	 * @return DataResponse
597
-	 * @throws OCSException
598
-	 */
599
-	public function editUser(string $userId, string $key, string $value): DataResponse {
600
-		$currentLoggedInUser = $this->userSession->getUser();
601
-
602
-		$targetUser = $this->userManager->get($userId);
603
-		if ($targetUser === null) {
604
-			throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
605
-		}
606
-
607
-		$permittedFields = [];
608
-		if ($targetUser->getUID() === $currentLoggedInUser->getUID()) {
609
-			// Editing self (display, email)
610
-			if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
611
-				if ($targetUser->getBackend() instanceof ISetDisplayNameBackend
612
-					|| $targetUser->getBackend()->implementsActions(Backend::SET_DISPLAYNAME)) {
613
-					$permittedFields[] = 'display';
614
-					$permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME;
615
-				}
616
-				$permittedFields[] = IAccountManager::PROPERTY_EMAIL;
617
-			}
618
-
619
-			$permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX;
620
-			$permittedFields[] = IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX;
621
-
622
-			$permittedFields[] = 'password';
623
-			if ($this->config->getSystemValue('force_language', false) === false ||
624
-				$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
625
-				$permittedFields[] = 'language';
626
-			}
627
-
628
-			if ($this->config->getSystemValue('force_locale', false) === false ||
629
-				$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
630
-				$permittedFields[] = 'locale';
631
-			}
632
-
633
-			$permittedFields[] = IAccountManager::PROPERTY_PHONE;
634
-			$permittedFields[] = IAccountManager::PROPERTY_ADDRESS;
635
-			$permittedFields[] = IAccountManager::PROPERTY_WEBSITE;
636
-			$permittedFields[] = IAccountManager::PROPERTY_TWITTER;
637
-			$permittedFields[] = IAccountManager::PROPERTY_PHONE . self::SCOPE_SUFFIX;
638
-			$permittedFields[] = IAccountManager::PROPERTY_ADDRESS . self::SCOPE_SUFFIX;
639
-			$permittedFields[] = IAccountManager::PROPERTY_WEBSITE . self::SCOPE_SUFFIX;
640
-			$permittedFields[] = IAccountManager::PROPERTY_TWITTER . self::SCOPE_SUFFIX;
641
-
642
-			$permittedFields[] = IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX;
643
-
644
-			// If admin they can edit their own quota
645
-			if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
646
-				$permittedFields[] = 'quota';
647
-			}
648
-		} else {
649
-			// Check if admin / subadmin
650
-			$subAdminManager = $this->groupManager->getSubAdmin();
651
-			if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
652
-			|| $subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
653
-				// They have permissions over the user
654
-				if ($targetUser->getBackend() instanceof ISetDisplayNameBackend
655
-					|| $targetUser->getBackend()->implementsActions(Backend::SET_DISPLAYNAME)) {
656
-					$permittedFields[] = 'display';
657
-					$permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME;
658
-				}
659
-				$permittedFields[] = IAccountManager::PROPERTY_EMAIL;
660
-				$permittedFields[] = 'password';
661
-				$permittedFields[] = 'language';
662
-				$permittedFields[] = 'locale';
663
-				$permittedFields[] = IAccountManager::PROPERTY_PHONE;
664
-				$permittedFields[] = IAccountManager::PROPERTY_ADDRESS;
665
-				$permittedFields[] = IAccountManager::PROPERTY_WEBSITE;
666
-				$permittedFields[] = IAccountManager::PROPERTY_TWITTER;
667
-				$permittedFields[] = 'quota';
668
-			} else {
669
-				// No rights
670
-				throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
671
-			}
672
-		}
673
-		// Check if permitted to edit this field
674
-		if (!in_array($key, $permittedFields)) {
675
-			throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
676
-		}
677
-		// Process the edit
678
-		switch ($key) {
679
-			case 'display':
680
-			case IAccountManager::PROPERTY_DISPLAYNAME:
681
-				$targetUser->setDisplayName($value);
682
-				break;
683
-			case 'quota':
684
-				$quota = $value;
685
-				if ($quota !== 'none' && $quota !== 'default') {
686
-					if (is_numeric($quota)) {
687
-						$quota = (float) $quota;
688
-					} else {
689
-						$quota = \OCP\Util::computerFileSize($quota);
690
-					}
691
-					if ($quota === false) {
692
-						throw new OCSException('Invalid quota value '.$value, 103);
693
-					}
694
-					if ($quota === -1) {
695
-						$quota = 'none';
696
-					} else {
697
-						$quota = \OCP\Util::humanFileSize($quota);
698
-					}
699
-				}
700
-				$targetUser->setQuota($quota);
701
-				break;
702
-			case 'password':
703
-				try {
704
-					if (!$targetUser->canChangePassword()) {
705
-						throw new OCSException('Setting the password is not supported by the users backend', 103);
706
-					}
707
-					$targetUser->setPassword($value);
708
-				} catch (HintException $e) { // password policy error
709
-					throw new OCSException($e->getMessage(), 103);
710
-				}
711
-				break;
712
-			case 'language':
713
-				$languagesCodes = $this->l10nFactory->findAvailableLanguages();
714
-				if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
715
-					throw new OCSException('Invalid language', 102);
716
-				}
717
-				$this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
718
-				break;
719
-			case 'locale':
720
-				if (!$this->l10nFactory->localeExists($value)) {
721
-					throw new OCSException('Invalid locale', 102);
722
-				}
723
-				$this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
724
-				break;
725
-			case IAccountManager::PROPERTY_EMAIL:
726
-				if (filter_var($value, FILTER_VALIDATE_EMAIL) || $value === '') {
727
-					$targetUser->setEMailAddress($value);
728
-				} else {
729
-					throw new OCSException('', 102);
730
-				}
731
-				break;
732
-			case IAccountManager::PROPERTY_PHONE:
733
-			case IAccountManager::PROPERTY_ADDRESS:
734
-			case IAccountManager::PROPERTY_WEBSITE:
735
-			case IAccountManager::PROPERTY_TWITTER:
736
-				$userAccount = $this->accountManager->getAccount($targetUser);
737
-				$userProperty = $userAccount->getProperty($key);
738
-				if ($userProperty->getValue() !== $value) {
739
-					try {
740
-						$userProperty->setValue($value);
741
-						$this->accountManager->updateAccount($userAccount);
742
-
743
-						if ($userProperty->getName() === IAccountManager::PROPERTY_PHONE) {
744
-							$this->knownUserService->deleteByContactUserId($targetUser->getUID());
745
-						}
746
-					} catch (\InvalidArgumentException $e) {
747
-						throw new OCSException('Invalid ' . $e->getMessage(), 102);
748
-					}
749
-				}
750
-				break;
751
-			case IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX:
752
-			case IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX:
753
-			case IAccountManager::PROPERTY_PHONE . self::SCOPE_SUFFIX:
754
-			case IAccountManager::PROPERTY_ADDRESS . self::SCOPE_SUFFIX:
755
-			case IAccountManager::PROPERTY_WEBSITE . self::SCOPE_SUFFIX:
756
-			case IAccountManager::PROPERTY_TWITTER . self::SCOPE_SUFFIX:
757
-			case IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX:
758
-				$propertyName = substr($key, 0, strlen($key) - strlen(self::SCOPE_SUFFIX));
759
-				$userAccount = $this->accountManager->getAccount($targetUser);
760
-				$userProperty = $userAccount->getProperty($propertyName);
761
-				if ($userProperty->getScope() !== $value) {
762
-					try {
763
-						$userProperty->setScope($value);
764
-						$this->accountManager->updateAccount($userAccount);
765
-					} catch (\InvalidArgumentException $e) {
766
-						throw new OCSException('Invalid ' . $e->getMessage(), 102);
767
-					}
768
-				}
769
-				break;
770
-			default:
771
-				throw new OCSException('', 103);
772
-		}
773
-		return new DataResponse();
774
-	}
775
-
776
-	/**
777
-	 * @PasswordConfirmationRequired
778
-	 * @NoAdminRequired
779
-	 *
780
-	 * @param string $userId
781
-	 *
782
-	 * @return DataResponse
783
-	 *
784
-	 * @throws OCSException
785
-	 */
786
-	public function wipeUserDevices(string $userId): DataResponse {
787
-		/** @var IUser $currentLoggedInUser */
788
-		$currentLoggedInUser = $this->userSession->getUser();
789
-
790
-		$targetUser = $this->userManager->get($userId);
791
-
792
-		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
793
-			throw new OCSException('', 101);
794
-		}
795
-
796
-		// If not permitted
797
-		$subAdminManager = $this->groupManager->getSubAdmin();
798
-		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
799
-			throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
800
-		}
801
-
802
-		$this->remoteWipe->markAllTokensForWipe($targetUser);
803
-
804
-		return new DataResponse();
805
-	}
806
-
807
-	/**
808
-	 * @PasswordConfirmationRequired
809
-	 * @NoAdminRequired
810
-	 *
811
-	 * @param string $userId
812
-	 * @return DataResponse
813
-	 * @throws OCSException
814
-	 */
815
-	public function deleteUser(string $userId): DataResponse {
816
-		$currentLoggedInUser = $this->userSession->getUser();
817
-
818
-		$targetUser = $this->userManager->get($userId);
819
-
820
-		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
821
-			throw new OCSException('', 101);
822
-		}
823
-
824
-		// If not permitted
825
-		$subAdminManager = $this->groupManager->getSubAdmin();
826
-		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
827
-			throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
828
-		}
829
-
830
-		// Go ahead with the delete
831
-		if ($targetUser->delete()) {
832
-			return new DataResponse();
833
-		} else {
834
-			throw new OCSException('', 101);
835
-		}
836
-	}
837
-
838
-	/**
839
-	 * @PasswordConfirmationRequired
840
-	 * @NoAdminRequired
841
-	 *
842
-	 * @param string $userId
843
-	 * @return DataResponse
844
-	 * @throws OCSException
845
-	 * @throws OCSForbiddenException
846
-	 */
847
-	public function disableUser(string $userId): DataResponse {
848
-		return $this->setEnabled($userId, false);
849
-	}
850
-
851
-	/**
852
-	 * @PasswordConfirmationRequired
853
-	 * @NoAdminRequired
854
-	 *
855
-	 * @param string $userId
856
-	 * @return DataResponse
857
-	 * @throws OCSException
858
-	 * @throws OCSForbiddenException
859
-	 */
860
-	public function enableUser(string $userId): DataResponse {
861
-		return $this->setEnabled($userId, true);
862
-	}
863
-
864
-	/**
865
-	 * @param string $userId
866
-	 * @param bool $value
867
-	 * @return DataResponse
868
-	 * @throws OCSException
869
-	 */
870
-	private function setEnabled(string $userId, bool $value): DataResponse {
871
-		$currentLoggedInUser = $this->userSession->getUser();
872
-
873
-		$targetUser = $this->userManager->get($userId);
874
-		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
875
-			throw new OCSException('', 101);
876
-		}
877
-
878
-		// If not permitted
879
-		$subAdminManager = $this->groupManager->getSubAdmin();
880
-		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
881
-			throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
882
-		}
883
-
884
-		// enable/disable the user now
885
-		$targetUser->setEnabled($value);
886
-		return new DataResponse();
887
-	}
888
-
889
-	/**
890
-	 * @NoAdminRequired
891
-	 * @NoSubAdminRequired
892
-	 *
893
-	 * @param string $userId
894
-	 * @return DataResponse
895
-	 * @throws OCSException
896
-	 */
897
-	public function getUsersGroups(string $userId): DataResponse {
898
-		$loggedInUser = $this->userSession->getUser();
899
-
900
-		$targetUser = $this->userManager->get($userId);
901
-		if ($targetUser === null) {
902
-			throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
903
-		}
904
-
905
-		if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
906
-			// Self lookup or admin lookup
907
-			return new DataResponse([
908
-				'groups' => $this->groupManager->getUserGroupIds($targetUser)
909
-			]);
910
-		} else {
911
-			$subAdminManager = $this->groupManager->getSubAdmin();
912
-
913
-			// Looking up someone else
914
-			if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
915
-				// Return the group that the method caller is subadmin of for the user in question
916
-				/** @var IGroup[] $getSubAdminsGroups */
917
-				$getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
918
-				foreach ($getSubAdminsGroups as $key => $group) {
919
-					$getSubAdminsGroups[$key] = $group->getGID();
920
-				}
921
-				$groups = array_intersect(
922
-					$getSubAdminsGroups,
923
-					$this->groupManager->getUserGroupIds($targetUser)
924
-				);
925
-				return new DataResponse(['groups' => $groups]);
926
-			} else {
927
-				// Not permitted
928
-				throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
929
-			}
930
-		}
931
-	}
932
-
933
-	/**
934
-	 * @PasswordConfirmationRequired
935
-	 * @NoAdminRequired
936
-	 *
937
-	 * @param string $userId
938
-	 * @param string $groupid
939
-	 * @return DataResponse
940
-	 * @throws OCSException
941
-	 */
942
-	public function addToGroup(string $userId, string $groupid = ''): DataResponse {
943
-		if ($groupid === '') {
944
-			throw new OCSException('', 101);
945
-		}
946
-
947
-		$group = $this->groupManager->get($groupid);
948
-		$targetUser = $this->userManager->get($userId);
949
-		if ($group === null) {
950
-			throw new OCSException('', 102);
951
-		}
952
-		if ($targetUser === null) {
953
-			throw new OCSException('', 103);
954
-		}
955
-
956
-		// If they're not an admin, check they are a subadmin of the group in question
957
-		$loggedInUser = $this->userSession->getUser();
958
-		$subAdminManager = $this->groupManager->getSubAdmin();
959
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
960
-			throw new OCSException('', 104);
961
-		}
962
-
963
-		// Add user to group
964
-		$group->addUser($targetUser);
965
-		return new DataResponse();
966
-	}
967
-
968
-	/**
969
-	 * @PasswordConfirmationRequired
970
-	 * @NoAdminRequired
971
-	 *
972
-	 * @param string $userId
973
-	 * @param string $groupid
974
-	 * @return DataResponse
975
-	 * @throws OCSException
976
-	 */
977
-	public function removeFromGroup(string $userId, string $groupid): DataResponse {
978
-		$loggedInUser = $this->userSession->getUser();
979
-
980
-		if ($groupid === null || trim($groupid) === '') {
981
-			throw new OCSException('', 101);
982
-		}
983
-
984
-		$group = $this->groupManager->get($groupid);
985
-		if ($group === null) {
986
-			throw new OCSException('', 102);
987
-		}
988
-
989
-		$targetUser = $this->userManager->get($userId);
990
-		if ($targetUser === null) {
991
-			throw new OCSException('', 103);
992
-		}
993
-
994
-		// If they're not an admin, check they are a subadmin of the group in question
995
-		$subAdminManager = $this->groupManager->getSubAdmin();
996
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
997
-			throw new OCSException('', 104);
998
-		}
999
-
1000
-		// Check they aren't removing themselves from 'admin' or their 'subadmin; group
1001
-		if ($targetUser->getUID() === $loggedInUser->getUID()) {
1002
-			if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
1003
-				if ($group->getGID() === 'admin') {
1004
-					throw new OCSException('Cannot remove yourself from the admin group', 105);
1005
-				}
1006
-			} else {
1007
-				// Not an admin, so the user must be a subadmin of this group, but that is not allowed.
1008
-				throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
1009
-			}
1010
-		} elseif (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
1011
-			/** @var IGroup[] $subAdminGroups */
1012
-			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
1013
-			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
1014
-				return $subAdminGroup->getGID();
1015
-			}, $subAdminGroups);
1016
-			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
1017
-			$userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
1018
-
1019
-			if (count($userSubAdminGroups) <= 1) {
1020
-				// Subadmin must not be able to remove a user from all their subadmin groups.
1021
-				throw new OCSException('Not viable to remove user from the last group you are SubAdmin of', 105);
1022
-			}
1023
-		}
1024
-
1025
-		// Remove user from group
1026
-		$group->removeUser($targetUser);
1027
-		return new DataResponse();
1028
-	}
1029
-
1030
-	/**
1031
-	 * Creates a subadmin
1032
-	 *
1033
-	 * @PasswordConfirmationRequired
1034
-	 *
1035
-	 * @param string $userId
1036
-	 * @param string $groupid
1037
-	 * @return DataResponse
1038
-	 * @throws OCSException
1039
-	 */
1040
-	public function addSubAdmin(string $userId, string $groupid): DataResponse {
1041
-		$group = $this->groupManager->get($groupid);
1042
-		$user = $this->userManager->get($userId);
1043
-
1044
-		// Check if the user exists
1045
-		if ($user === null) {
1046
-			throw new OCSException('User does not exist', 101);
1047
-		}
1048
-		// Check if group exists
1049
-		if ($group === null) {
1050
-			throw new OCSException('Group does not exist',  102);
1051
-		}
1052
-		// Check if trying to make subadmin of admin group
1053
-		if ($group->getGID() === 'admin') {
1054
-			throw new OCSException('Cannot create subadmins for admin group', 103);
1055
-		}
1056
-
1057
-		$subAdminManager = $this->groupManager->getSubAdmin();
1058
-
1059
-		// We cannot be subadmin twice
1060
-		if ($subAdminManager->isSubAdminOfGroup($user, $group)) {
1061
-			return new DataResponse();
1062
-		}
1063
-		// Go
1064
-		$subAdminManager->createSubAdmin($user, $group);
1065
-		return new DataResponse();
1066
-	}
1067
-
1068
-	/**
1069
-	 * Removes a subadmin from a group
1070
-	 *
1071
-	 * @PasswordConfirmationRequired
1072
-	 *
1073
-	 * @param string $userId
1074
-	 * @param string $groupid
1075
-	 * @return DataResponse
1076
-	 * @throws OCSException
1077
-	 */
1078
-	public function removeSubAdmin(string $userId, string $groupid): DataResponse {
1079
-		$group = $this->groupManager->get($groupid);
1080
-		$user = $this->userManager->get($userId);
1081
-		$subAdminManager = $this->groupManager->getSubAdmin();
1082
-
1083
-		// Check if the user exists
1084
-		if ($user === null) {
1085
-			throw new OCSException('User does not exist', 101);
1086
-		}
1087
-		// Check if the group exists
1088
-		if ($group === null) {
1089
-			throw new OCSException('Group does not exist', 101);
1090
-		}
1091
-		// Check if they are a subadmin of this said group
1092
-		if (!$subAdminManager->isSubAdminOfGroup($user, $group)) {
1093
-			throw new OCSException('User is not a subadmin of this group', 102);
1094
-		}
1095
-
1096
-		// Go
1097
-		$subAdminManager->deleteSubAdmin($user, $group);
1098
-		return new DataResponse();
1099
-	}
1100
-
1101
-	/**
1102
-	 * Get the groups a user is a subadmin of
1103
-	 *
1104
-	 * @param string $userId
1105
-	 * @return DataResponse
1106
-	 * @throws OCSException
1107
-	 */
1108
-	public function getUserSubAdminGroups(string $userId): DataResponse {
1109
-		$groups = $this->getUserSubAdminGroupsData($userId);
1110
-		return new DataResponse($groups);
1111
-	}
1112
-
1113
-	/**
1114
-	 * @NoAdminRequired
1115
-	 * @PasswordConfirmationRequired
1116
-	 *
1117
-	 * resend welcome message
1118
-	 *
1119
-	 * @param string $userId
1120
-	 * @return DataResponse
1121
-	 * @throws OCSException
1122
-	 */
1123
-	public function resendWelcomeMessage(string $userId): DataResponse {
1124
-		$currentLoggedInUser = $this->userSession->getUser();
1125
-
1126
-		$targetUser = $this->userManager->get($userId);
1127
-		if ($targetUser === null) {
1128
-			throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
1129
-		}
1130
-
1131
-		// Check if admin / subadmin
1132
-		$subAdminManager = $this->groupManager->getSubAdmin();
1133
-		if (!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
1134
-			&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
1135
-			// No rights
1136
-			throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
1137
-		}
1138
-
1139
-		$email = $targetUser->getEMailAddress();
1140
-		if ($email === '' || $email === null) {
1141
-			throw new OCSException('Email address not available', 101);
1142
-		}
1143
-
1144
-		try {
1145
-			$emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
1146
-			$this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
1147
-		} catch (\Exception $e) {
1148
-			$this->logger->error("Can't send new user mail to $email",
1149
-				[
1150
-					'app' => 'settings',
1151
-					'exception' => $e,
1152
-				]
1153
-			);
1154
-			throw new OCSException('Sending email failed', 102);
1155
-		}
1156
-
1157
-		return new DataResponse();
1158
-	}
78
+    /** @var IAppManager */
79
+    private $appManager;
80
+    /** @var IURLGenerator */
81
+    protected $urlGenerator;
82
+    /** @var LoggerInterface */
83
+    private $logger;
84
+    /** @var IFactory */
85
+    protected $l10nFactory;
86
+    /** @var NewUserMailHelper */
87
+    private $newUserMailHelper;
88
+    /** @var ISecureRandom */
89
+    private $secureRandom;
90
+    /** @var RemoteWipe */
91
+    private $remoteWipe;
92
+    /** @var KnownUserService */
93
+    private $knownUserService;
94
+    /** @var IEventDispatcher */
95
+    private $eventDispatcher;
96
+
97
+    public function __construct(string $appName,
98
+                                IRequest $request,
99
+                                IUserManager $userManager,
100
+                                IConfig $config,
101
+                                IAppManager $appManager,
102
+                                IGroupManager $groupManager,
103
+                                IUserSession $userSession,
104
+                                IAccountManager $accountManager,
105
+                                IURLGenerator $urlGenerator,
106
+                                LoggerInterface $logger,
107
+                                IFactory $l10nFactory,
108
+                                NewUserMailHelper $newUserMailHelper,
109
+                                ISecureRandom $secureRandom,
110
+                                RemoteWipe $remoteWipe,
111
+                                KnownUserService $knownUserService,
112
+                                IEventDispatcher $eventDispatcher) {
113
+        parent::__construct($appName,
114
+                            $request,
115
+                            $userManager,
116
+                            $config,
117
+                            $groupManager,
118
+                            $userSession,
119
+                            $accountManager,
120
+                            $l10nFactory);
121
+
122
+        $this->appManager = $appManager;
123
+        $this->urlGenerator = $urlGenerator;
124
+        $this->logger = $logger;
125
+        $this->l10nFactory = $l10nFactory;
126
+        $this->newUserMailHelper = $newUserMailHelper;
127
+        $this->secureRandom = $secureRandom;
128
+        $this->remoteWipe = $remoteWipe;
129
+        $this->knownUserService = $knownUserService;
130
+        $this->eventDispatcher = $eventDispatcher;
131
+    }
132
+
133
+    /**
134
+     * @NoAdminRequired
135
+     *
136
+     * returns a list of users
137
+     *
138
+     * @param string $search
139
+     * @param int $limit
140
+     * @param int $offset
141
+     * @return DataResponse
142
+     */
143
+    public function getUsers(string $search = '', int $limit = null, int $offset = 0): DataResponse {
144
+        $user = $this->userSession->getUser();
145
+        $users = [];
146
+
147
+        // Admin? Or SubAdmin?
148
+        $uid = $user->getUID();
149
+        $subAdminManager = $this->groupManager->getSubAdmin();
150
+        if ($this->groupManager->isAdmin($uid)) {
151
+            $users = $this->userManager->search($search, $limit, $offset);
152
+        } elseif ($subAdminManager->isSubAdmin($user)) {
153
+            $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
154
+            foreach ($subAdminOfGroups as $key => $group) {
155
+                $subAdminOfGroups[$key] = $group->getGID();
156
+            }
157
+
158
+            $users = [];
159
+            foreach ($subAdminOfGroups as $group) {
160
+                $users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
161
+            }
162
+        }
163
+
164
+        $users = array_keys($users);
165
+
166
+        return new DataResponse([
167
+            'users' => $users
168
+        ]);
169
+    }
170
+
171
+    /**
172
+     * @NoAdminRequired
173
+     *
174
+     * returns a list of users and their data
175
+     */
176
+    public function getUsersDetails(string $search = '', int $limit = null, int $offset = 0): DataResponse {
177
+        $currentUser = $this->userSession->getUser();
178
+        $users = [];
179
+
180
+        // Admin? Or SubAdmin?
181
+        $uid = $currentUser->getUID();
182
+        $subAdminManager = $this->groupManager->getSubAdmin();
183
+        if ($this->groupManager->isAdmin($uid)) {
184
+            $users = $this->userManager->search($search, $limit, $offset);
185
+            $users = array_keys($users);
186
+        } elseif ($subAdminManager->isSubAdmin($currentUser)) {
187
+            $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser);
188
+            foreach ($subAdminOfGroups as $key => $group) {
189
+                $subAdminOfGroups[$key] = $group->getGID();
190
+            }
191
+
192
+            $users = [];
193
+            foreach ($subAdminOfGroups as $group) {
194
+                $users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
195
+            }
196
+            $users = array_merge(...$users);
197
+        }
198
+
199
+        $usersDetails = [];
200
+        foreach ($users as $userId) {
201
+            $userId = (string) $userId;
202
+            $userData = $this->getUserData($userId);
203
+            // Do not insert empty entry
204
+            if (!empty($userData)) {
205
+                $usersDetails[$userId] = $userData;
206
+            } else {
207
+                // Logged user does not have permissions to see this user
208
+                // only showing its id
209
+                $usersDetails[$userId] = ['id' => $userId];
210
+            }
211
+        }
212
+
213
+        return new DataResponse([
214
+            'users' => $usersDetails
215
+        ]);
216
+    }
217
+
218
+
219
+    /**
220
+     * @NoAdminRequired
221
+     * @NoSubAdminRequired
222
+     *
223
+     * @param string $location
224
+     * @param array $search
225
+     * @return DataResponse
226
+     */
227
+    public function searchByPhoneNumbers(string $location, array $search): DataResponse {
228
+        $phoneUtil = PhoneNumberUtil::getInstance();
229
+
230
+        if ($phoneUtil->getCountryCodeForRegion($location) === 0) {
231
+            // Not a valid region code
232
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
233
+        }
234
+
235
+        /** @var IUser $user */
236
+        $user = $this->userSession->getUser();
237
+        $knownTo = $user->getUID();
238
+        $defaultPhoneRegion = $this->config->getSystemValueString('default_phone_region');
239
+
240
+        $normalizedNumberToKey = [];
241
+        foreach ($search as $key => $phoneNumbers) {
242
+            foreach ($phoneNumbers as $phone) {
243
+                try {
244
+                    $phoneNumber = $phoneUtil->parse($phone, $location);
245
+                    if ($phoneNumber instanceof PhoneNumber && $phoneUtil->isValidNumber($phoneNumber)) {
246
+                        $normalizedNumber = $phoneUtil->format($phoneNumber, PhoneNumberFormat::E164);
247
+                        $normalizedNumberToKey[$normalizedNumber] = (string) $key;
248
+                    }
249
+                } catch (NumberParseException $e) {
250
+                }
251
+
252
+                if ($defaultPhoneRegion !== '' && $defaultPhoneRegion !== $location && strpos($phone, '0') === 0) {
253
+                    // If the number has a leading zero (no country code),
254
+                    // we also check the default phone region of the instance,
255
+                    // when it's different to the user's given region.
256
+                    try {
257
+                        $phoneNumber = $phoneUtil->parse($phone, $defaultPhoneRegion);
258
+                        if ($phoneNumber instanceof PhoneNumber && $phoneUtil->isValidNumber($phoneNumber)) {
259
+                            $normalizedNumber = $phoneUtil->format($phoneNumber, PhoneNumberFormat::E164);
260
+                            $normalizedNumberToKey[$normalizedNumber] = (string) $key;
261
+                        }
262
+                    } catch (NumberParseException $e) {
263
+                    }
264
+                }
265
+            }
266
+        }
267
+
268
+        $phoneNumbers = array_keys($normalizedNumberToKey);
269
+
270
+        if (empty($phoneNumbers)) {
271
+            return new DataResponse();
272
+        }
273
+
274
+        // Cleanup all previous entries and only allow new matches
275
+        $this->knownUserService->deleteKnownTo($knownTo);
276
+
277
+        $userMatches = $this->accountManager->searchUsers(IAccountManager::PROPERTY_PHONE, $phoneNumbers);
278
+
279
+        if (empty($userMatches)) {
280
+            return new DataResponse();
281
+        }
282
+
283
+        $cloudUrl = rtrim($this->urlGenerator->getAbsoluteURL('/'), '/');
284
+        if (strpos($cloudUrl, 'http://') === 0) {
285
+            $cloudUrl = substr($cloudUrl, strlen('http://'));
286
+        } elseif (strpos($cloudUrl, 'https://') === 0) {
287
+            $cloudUrl = substr($cloudUrl, strlen('https://'));
288
+        }
289
+
290
+        $matches = [];
291
+        foreach ($userMatches as $phone => $userId) {
292
+            // Not using the ICloudIdManager as that would run a search for each contact to find the display name in the address book
293
+            $matches[$normalizedNumberToKey[$phone]] = $userId . '@' . $cloudUrl;
294
+            $this->knownUserService->storeIsKnownToUser($knownTo, $userId);
295
+        }
296
+
297
+        return new DataResponse($matches);
298
+    }
299
+
300
+    /**
301
+     * @throws OCSException
302
+     */
303
+    private function createNewUserId(): string {
304
+        $attempts = 0;
305
+        do {
306
+            $uidCandidate = $this->secureRandom->generate(10, ISecureRandom::CHAR_HUMAN_READABLE);
307
+            if (!$this->userManager->userExists($uidCandidate)) {
308
+                return $uidCandidate;
309
+            }
310
+            $attempts++;
311
+        } while ($attempts < 10);
312
+        throw new OCSException('Could not create non-existing user id', 111);
313
+    }
314
+
315
+    /**
316
+     * @PasswordConfirmationRequired
317
+     * @NoAdminRequired
318
+     *
319
+     * @param string $userid
320
+     * @param string $password
321
+     * @param string $displayName
322
+     * @param string $email
323
+     * @param array $groups
324
+     * @param array $subadmin
325
+     * @param string $quota
326
+     * @param string $language
327
+     * @return DataResponse
328
+     * @throws OCSException
329
+     */
330
+    public function addUser(string $userid,
331
+                            string $password = '',
332
+                            string $displayName = '',
333
+                            string $email = '',
334
+                            array $groups = [],
335
+                            array $subadmin = [],
336
+                            string $quota = '',
337
+                            string $language = ''): DataResponse {
338
+        $user = $this->userSession->getUser();
339
+        $isAdmin = $this->groupManager->isAdmin($user->getUID());
340
+        $subAdminManager = $this->groupManager->getSubAdmin();
341
+
342
+        if (empty($userid) && $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes') {
343
+            $userid = $this->createNewUserId();
344
+        }
345
+
346
+        if ($this->userManager->userExists($userid)) {
347
+            $this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
348
+            throw new OCSException('User already exists', 102);
349
+        }
350
+
351
+        if ($groups !== []) {
352
+            foreach ($groups as $group) {
353
+                if (!$this->groupManager->groupExists($group)) {
354
+                    throw new OCSException('group '.$group.' does not exist', 104);
355
+                }
356
+                if (!$isAdmin && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
357
+                    throw new OCSException('insufficient privileges for group '. $group, 105);
358
+                }
359
+            }
360
+        } else {
361
+            if (!$isAdmin) {
362
+                throw new OCSException('no group specified (required for subadmins)', 106);
363
+            }
364
+        }
365
+
366
+        $subadminGroups = [];
367
+        if ($subadmin !== []) {
368
+            foreach ($subadmin as $groupid) {
369
+                $group = $this->groupManager->get($groupid);
370
+                // Check if group exists
371
+                if ($group === null) {
372
+                    throw new OCSException('Subadmin group does not exist',  102);
373
+                }
374
+                // Check if trying to make subadmin of admin group
375
+                if ($group->getGID() === 'admin') {
376
+                    throw new OCSException('Cannot create subadmins for admin group', 103);
377
+                }
378
+                // Check if has permission to promote subadmins
379
+                if (!$subAdminManager->isSubAdminOfGroup($user, $group) && !$isAdmin) {
380
+                    throw new OCSForbiddenException('No permissions to promote subadmins');
381
+                }
382
+                $subadminGroups[] = $group;
383
+            }
384
+        }
385
+
386
+        $generatePasswordResetToken = false;
387
+        if ($password === '') {
388
+            if ($email === '') {
389
+                throw new OCSException('To send a password link to the user an email address is required.', 108);
390
+            }
391
+
392
+            $passwordEvent = new GenerateSecurePasswordEvent();
393
+            $this->eventDispatcher->dispatchTyped($passwordEvent);
394
+
395
+            $password = $passwordEvent->getPassword();
396
+            if ($password === null) {
397
+                // Fallback: ensure to pass password_policy in any case
398
+                $password = $this->secureRandom->generate(10)
399
+                    . $this->secureRandom->generate(1, ISecureRandom::CHAR_UPPER)
400
+                    . $this->secureRandom->generate(1, ISecureRandom::CHAR_LOWER)
401
+                    . $this->secureRandom->generate(1, ISecureRandom::CHAR_DIGITS)
402
+                    . $this->secureRandom->generate(1, ISecureRandom::CHAR_SYMBOLS);
403
+            }
404
+            $generatePasswordResetToken = true;
405
+        }
406
+
407
+        if ($email === '' && $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes') {
408
+            throw new OCSException('Required email address was not provided', 110);
409
+        }
410
+
411
+        try {
412
+            $newUser = $this->userManager->createUser($userid, $password);
413
+            $this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']);
414
+
415
+            foreach ($groups as $group) {
416
+                $this->groupManager->get($group)->addUser($newUser);
417
+                $this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']);
418
+            }
419
+            foreach ($subadminGroups as $group) {
420
+                $subAdminManager->createSubAdmin($newUser, $group);
421
+            }
422
+
423
+            if ($displayName !== '') {
424
+                $this->editUser($userid, 'display', $displayName);
425
+            }
426
+
427
+            if ($quota !== '') {
428
+                $this->editUser($userid, 'quota', $quota);
429
+            }
430
+
431
+            if ($language !== '') {
432
+                $this->editUser($userid, 'language', $language);
433
+            }
434
+
435
+            // Send new user mail only if a mail is set
436
+            if ($email !== '') {
437
+                $newUser->setEMailAddress($email);
438
+                if ($this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
439
+                    try {
440
+                        $emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
441
+                        $this->newUserMailHelper->sendMail($newUser, $emailTemplate);
442
+                    } catch (\Exception $e) {
443
+                        // Mail could be failing hard or just be plain not configured
444
+                        // Logging error as it is the hardest of the two
445
+                        $this->logger->error("Unable to send the invitation mail to $email",
446
+                            [
447
+                                'app' => 'ocs_api',
448
+                                'exception' => $e,
449
+                            ]
450
+                        );
451
+                    }
452
+                }
453
+            }
454
+
455
+            return new DataResponse(['id' => $userid]);
456
+        } catch (HintException $e) {
457
+            $this->logger->warning('Failed addUser attempt with hint exception.',
458
+                [
459
+                    'app' => 'ocs_api',
460
+                    'exception' => $e,
461
+                ]
462
+            );
463
+            throw new OCSException($e->getHint(), 107);
464
+        } catch (OCSException $e) {
465
+            $this->logger->warning('Failed addUser attempt with ocs exeption.',
466
+                [
467
+                    'app' => 'ocs_api',
468
+                    'exception' => $e,
469
+                ]
470
+            );
471
+            throw $e;
472
+        } catch (\InvalidArgumentException $e) {
473
+            $this->logger->error('Failed addUser attempt with invalid argument exeption.',
474
+                [
475
+                    'app' => 'ocs_api',
476
+                    'exception' => $e,
477
+                ]
478
+            );
479
+            throw new OCSException($e->getMessage(), 101);
480
+        } catch (\Exception $e) {
481
+            $this->logger->error('Failed addUser attempt with exception.',
482
+                [
483
+                    'app' => 'ocs_api',
484
+                    'exception' => $e
485
+                ]
486
+            );
487
+            throw new OCSException('Bad request', 101);
488
+        }
489
+    }
490
+
491
+    /**
492
+     * @NoAdminRequired
493
+     * @NoSubAdminRequired
494
+     *
495
+     * gets user info
496
+     *
497
+     * @param string $userId
498
+     * @return DataResponse
499
+     * @throws OCSException
500
+     */
501
+    public function getUser(string $userId): DataResponse {
502
+        $includeScopes = false;
503
+        $currentUser = $this->userSession->getUser();
504
+        if ($currentUser && $currentUser->getUID() === $userId) {
505
+            $includeScopes = true;
506
+        }
507
+
508
+        $data = $this->getUserData($userId, $includeScopes);
509
+        // getUserData returns empty array if not enough permissions
510
+        if (empty($data)) {
511
+            throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
512
+        }
513
+        return new DataResponse($data);
514
+    }
515
+
516
+    /**
517
+     * @NoAdminRequired
518
+     * @NoSubAdminRequired
519
+     *
520
+     * gets user info from the currently logged in user
521
+     *
522
+     * @return DataResponse
523
+     * @throws OCSException
524
+     */
525
+    public function getCurrentUser(): DataResponse {
526
+        $user = $this->userSession->getUser();
527
+        if ($user) {
528
+            $data = $this->getUserData($user->getUID(), true);
529
+            // rename "displayname" to "display-name" only for this call to keep
530
+            // the API stable.
531
+            $data['display-name'] = $data['displayname'];
532
+            unset($data['displayname']);
533
+            return new DataResponse($data);
534
+        }
535
+
536
+        throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
537
+    }
538
+
539
+    /**
540
+     * @NoAdminRequired
541
+     * @NoSubAdminRequired
542
+     *
543
+     * @return DataResponse
544
+     * @throws OCSException
545
+     */
546
+    public function getEditableFields(?string $userId = null): DataResponse {
547
+        $currentLoggedInUser = $this->userSession->getUser();
548
+        if (!$currentLoggedInUser instanceof IUser) {
549
+            throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
550
+        }
551
+
552
+        $permittedFields = [];
553
+
554
+        if ($userId !== $currentLoggedInUser->getUID()) {
555
+            $targetUser = $this->userManager->get($userId);
556
+            if (!$targetUser instanceof IUser) {
557
+                throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
558
+            }
559
+
560
+            $subAdminManager = $this->groupManager->getSubAdmin();
561
+            if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID())
562
+                && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
563
+                throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
564
+            }
565
+        } else {
566
+            $targetUser = $currentLoggedInUser;
567
+        }
568
+
569
+        // Editing self (display, email)
570
+        if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
571
+            if ($targetUser->getBackend() instanceof ISetDisplayNameBackend
572
+                || $targetUser->getBackend()->implementsActions(Backend::SET_DISPLAYNAME)) {
573
+                $permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME;
574
+            }
575
+            $permittedFields[] = IAccountManager::PROPERTY_EMAIL;
576
+        }
577
+
578
+        $permittedFields[] = IAccountManager::PROPERTY_PHONE;
579
+        $permittedFields[] = IAccountManager::PROPERTY_ADDRESS;
580
+        $permittedFields[] = IAccountManager::PROPERTY_WEBSITE;
581
+        $permittedFields[] = IAccountManager::PROPERTY_TWITTER;
582
+
583
+        return new DataResponse($permittedFields);
584
+    }
585
+
586
+    /**
587
+     * @NoAdminRequired
588
+     * @NoSubAdminRequired
589
+     * @PasswordConfirmationRequired
590
+     *
591
+     * edit users
592
+     *
593
+     * @param string $userId
594
+     * @param string $key
595
+     * @param string $value
596
+     * @return DataResponse
597
+     * @throws OCSException
598
+     */
599
+    public function editUser(string $userId, string $key, string $value): DataResponse {
600
+        $currentLoggedInUser = $this->userSession->getUser();
601
+
602
+        $targetUser = $this->userManager->get($userId);
603
+        if ($targetUser === null) {
604
+            throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
605
+        }
606
+
607
+        $permittedFields = [];
608
+        if ($targetUser->getUID() === $currentLoggedInUser->getUID()) {
609
+            // Editing self (display, email)
610
+            if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
611
+                if ($targetUser->getBackend() instanceof ISetDisplayNameBackend
612
+                    || $targetUser->getBackend()->implementsActions(Backend::SET_DISPLAYNAME)) {
613
+                    $permittedFields[] = 'display';
614
+                    $permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME;
615
+                }
616
+                $permittedFields[] = IAccountManager::PROPERTY_EMAIL;
617
+            }
618
+
619
+            $permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX;
620
+            $permittedFields[] = IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX;
621
+
622
+            $permittedFields[] = 'password';
623
+            if ($this->config->getSystemValue('force_language', false) === false ||
624
+                $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
625
+                $permittedFields[] = 'language';
626
+            }
627
+
628
+            if ($this->config->getSystemValue('force_locale', false) === false ||
629
+                $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
630
+                $permittedFields[] = 'locale';
631
+            }
632
+
633
+            $permittedFields[] = IAccountManager::PROPERTY_PHONE;
634
+            $permittedFields[] = IAccountManager::PROPERTY_ADDRESS;
635
+            $permittedFields[] = IAccountManager::PROPERTY_WEBSITE;
636
+            $permittedFields[] = IAccountManager::PROPERTY_TWITTER;
637
+            $permittedFields[] = IAccountManager::PROPERTY_PHONE . self::SCOPE_SUFFIX;
638
+            $permittedFields[] = IAccountManager::PROPERTY_ADDRESS . self::SCOPE_SUFFIX;
639
+            $permittedFields[] = IAccountManager::PROPERTY_WEBSITE . self::SCOPE_SUFFIX;
640
+            $permittedFields[] = IAccountManager::PROPERTY_TWITTER . self::SCOPE_SUFFIX;
641
+
642
+            $permittedFields[] = IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX;
643
+
644
+            // If admin they can edit their own quota
645
+            if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
646
+                $permittedFields[] = 'quota';
647
+            }
648
+        } else {
649
+            // Check if admin / subadmin
650
+            $subAdminManager = $this->groupManager->getSubAdmin();
651
+            if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
652
+            || $subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
653
+                // They have permissions over the user
654
+                if ($targetUser->getBackend() instanceof ISetDisplayNameBackend
655
+                    || $targetUser->getBackend()->implementsActions(Backend::SET_DISPLAYNAME)) {
656
+                    $permittedFields[] = 'display';
657
+                    $permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME;
658
+                }
659
+                $permittedFields[] = IAccountManager::PROPERTY_EMAIL;
660
+                $permittedFields[] = 'password';
661
+                $permittedFields[] = 'language';
662
+                $permittedFields[] = 'locale';
663
+                $permittedFields[] = IAccountManager::PROPERTY_PHONE;
664
+                $permittedFields[] = IAccountManager::PROPERTY_ADDRESS;
665
+                $permittedFields[] = IAccountManager::PROPERTY_WEBSITE;
666
+                $permittedFields[] = IAccountManager::PROPERTY_TWITTER;
667
+                $permittedFields[] = 'quota';
668
+            } else {
669
+                // No rights
670
+                throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
671
+            }
672
+        }
673
+        // Check if permitted to edit this field
674
+        if (!in_array($key, $permittedFields)) {
675
+            throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
676
+        }
677
+        // Process the edit
678
+        switch ($key) {
679
+            case 'display':
680
+            case IAccountManager::PROPERTY_DISPLAYNAME:
681
+                $targetUser->setDisplayName($value);
682
+                break;
683
+            case 'quota':
684
+                $quota = $value;
685
+                if ($quota !== 'none' && $quota !== 'default') {
686
+                    if (is_numeric($quota)) {
687
+                        $quota = (float) $quota;
688
+                    } else {
689
+                        $quota = \OCP\Util::computerFileSize($quota);
690
+                    }
691
+                    if ($quota === false) {
692
+                        throw new OCSException('Invalid quota value '.$value, 103);
693
+                    }
694
+                    if ($quota === -1) {
695
+                        $quota = 'none';
696
+                    } else {
697
+                        $quota = \OCP\Util::humanFileSize($quota);
698
+                    }
699
+                }
700
+                $targetUser->setQuota($quota);
701
+                break;
702
+            case 'password':
703
+                try {
704
+                    if (!$targetUser->canChangePassword()) {
705
+                        throw new OCSException('Setting the password is not supported by the users backend', 103);
706
+                    }
707
+                    $targetUser->setPassword($value);
708
+                } catch (HintException $e) { // password policy error
709
+                    throw new OCSException($e->getMessage(), 103);
710
+                }
711
+                break;
712
+            case 'language':
713
+                $languagesCodes = $this->l10nFactory->findAvailableLanguages();
714
+                if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
715
+                    throw new OCSException('Invalid language', 102);
716
+                }
717
+                $this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
718
+                break;
719
+            case 'locale':
720
+                if (!$this->l10nFactory->localeExists($value)) {
721
+                    throw new OCSException('Invalid locale', 102);
722
+                }
723
+                $this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
724
+                break;
725
+            case IAccountManager::PROPERTY_EMAIL:
726
+                if (filter_var($value, FILTER_VALIDATE_EMAIL) || $value === '') {
727
+                    $targetUser->setEMailAddress($value);
728
+                } else {
729
+                    throw new OCSException('', 102);
730
+                }
731
+                break;
732
+            case IAccountManager::PROPERTY_PHONE:
733
+            case IAccountManager::PROPERTY_ADDRESS:
734
+            case IAccountManager::PROPERTY_WEBSITE:
735
+            case IAccountManager::PROPERTY_TWITTER:
736
+                $userAccount = $this->accountManager->getAccount($targetUser);
737
+                $userProperty = $userAccount->getProperty($key);
738
+                if ($userProperty->getValue() !== $value) {
739
+                    try {
740
+                        $userProperty->setValue($value);
741
+                        $this->accountManager->updateAccount($userAccount);
742
+
743
+                        if ($userProperty->getName() === IAccountManager::PROPERTY_PHONE) {
744
+                            $this->knownUserService->deleteByContactUserId($targetUser->getUID());
745
+                        }
746
+                    } catch (\InvalidArgumentException $e) {
747
+                        throw new OCSException('Invalid ' . $e->getMessage(), 102);
748
+                    }
749
+                }
750
+                break;
751
+            case IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX:
752
+            case IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX:
753
+            case IAccountManager::PROPERTY_PHONE . self::SCOPE_SUFFIX:
754
+            case IAccountManager::PROPERTY_ADDRESS . self::SCOPE_SUFFIX:
755
+            case IAccountManager::PROPERTY_WEBSITE . self::SCOPE_SUFFIX:
756
+            case IAccountManager::PROPERTY_TWITTER . self::SCOPE_SUFFIX:
757
+            case IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX:
758
+                $propertyName = substr($key, 0, strlen($key) - strlen(self::SCOPE_SUFFIX));
759
+                $userAccount = $this->accountManager->getAccount($targetUser);
760
+                $userProperty = $userAccount->getProperty($propertyName);
761
+                if ($userProperty->getScope() !== $value) {
762
+                    try {
763
+                        $userProperty->setScope($value);
764
+                        $this->accountManager->updateAccount($userAccount);
765
+                    } catch (\InvalidArgumentException $e) {
766
+                        throw new OCSException('Invalid ' . $e->getMessage(), 102);
767
+                    }
768
+                }
769
+                break;
770
+            default:
771
+                throw new OCSException('', 103);
772
+        }
773
+        return new DataResponse();
774
+    }
775
+
776
+    /**
777
+     * @PasswordConfirmationRequired
778
+     * @NoAdminRequired
779
+     *
780
+     * @param string $userId
781
+     *
782
+     * @return DataResponse
783
+     *
784
+     * @throws OCSException
785
+     */
786
+    public function wipeUserDevices(string $userId): DataResponse {
787
+        /** @var IUser $currentLoggedInUser */
788
+        $currentLoggedInUser = $this->userSession->getUser();
789
+
790
+        $targetUser = $this->userManager->get($userId);
791
+
792
+        if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
793
+            throw new OCSException('', 101);
794
+        }
795
+
796
+        // If not permitted
797
+        $subAdminManager = $this->groupManager->getSubAdmin();
798
+        if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
799
+            throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
800
+        }
801
+
802
+        $this->remoteWipe->markAllTokensForWipe($targetUser);
803
+
804
+        return new DataResponse();
805
+    }
806
+
807
+    /**
808
+     * @PasswordConfirmationRequired
809
+     * @NoAdminRequired
810
+     *
811
+     * @param string $userId
812
+     * @return DataResponse
813
+     * @throws OCSException
814
+     */
815
+    public function deleteUser(string $userId): DataResponse {
816
+        $currentLoggedInUser = $this->userSession->getUser();
817
+
818
+        $targetUser = $this->userManager->get($userId);
819
+
820
+        if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
821
+            throw new OCSException('', 101);
822
+        }
823
+
824
+        // If not permitted
825
+        $subAdminManager = $this->groupManager->getSubAdmin();
826
+        if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
827
+            throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
828
+        }
829
+
830
+        // Go ahead with the delete
831
+        if ($targetUser->delete()) {
832
+            return new DataResponse();
833
+        } else {
834
+            throw new OCSException('', 101);
835
+        }
836
+    }
837
+
838
+    /**
839
+     * @PasswordConfirmationRequired
840
+     * @NoAdminRequired
841
+     *
842
+     * @param string $userId
843
+     * @return DataResponse
844
+     * @throws OCSException
845
+     * @throws OCSForbiddenException
846
+     */
847
+    public function disableUser(string $userId): DataResponse {
848
+        return $this->setEnabled($userId, false);
849
+    }
850
+
851
+    /**
852
+     * @PasswordConfirmationRequired
853
+     * @NoAdminRequired
854
+     *
855
+     * @param string $userId
856
+     * @return DataResponse
857
+     * @throws OCSException
858
+     * @throws OCSForbiddenException
859
+     */
860
+    public function enableUser(string $userId): DataResponse {
861
+        return $this->setEnabled($userId, true);
862
+    }
863
+
864
+    /**
865
+     * @param string $userId
866
+     * @param bool $value
867
+     * @return DataResponse
868
+     * @throws OCSException
869
+     */
870
+    private function setEnabled(string $userId, bool $value): DataResponse {
871
+        $currentLoggedInUser = $this->userSession->getUser();
872
+
873
+        $targetUser = $this->userManager->get($userId);
874
+        if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
875
+            throw new OCSException('', 101);
876
+        }
877
+
878
+        // If not permitted
879
+        $subAdminManager = $this->groupManager->getSubAdmin();
880
+        if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
881
+            throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
882
+        }
883
+
884
+        // enable/disable the user now
885
+        $targetUser->setEnabled($value);
886
+        return new DataResponse();
887
+    }
888
+
889
+    /**
890
+     * @NoAdminRequired
891
+     * @NoSubAdminRequired
892
+     *
893
+     * @param string $userId
894
+     * @return DataResponse
895
+     * @throws OCSException
896
+     */
897
+    public function getUsersGroups(string $userId): DataResponse {
898
+        $loggedInUser = $this->userSession->getUser();
899
+
900
+        $targetUser = $this->userManager->get($userId);
901
+        if ($targetUser === null) {
902
+            throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
903
+        }
904
+
905
+        if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
906
+            // Self lookup or admin lookup
907
+            return new DataResponse([
908
+                'groups' => $this->groupManager->getUserGroupIds($targetUser)
909
+            ]);
910
+        } else {
911
+            $subAdminManager = $this->groupManager->getSubAdmin();
912
+
913
+            // Looking up someone else
914
+            if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
915
+                // Return the group that the method caller is subadmin of for the user in question
916
+                /** @var IGroup[] $getSubAdminsGroups */
917
+                $getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
918
+                foreach ($getSubAdminsGroups as $key => $group) {
919
+                    $getSubAdminsGroups[$key] = $group->getGID();
920
+                }
921
+                $groups = array_intersect(
922
+                    $getSubAdminsGroups,
923
+                    $this->groupManager->getUserGroupIds($targetUser)
924
+                );
925
+                return new DataResponse(['groups' => $groups]);
926
+            } else {
927
+                // Not permitted
928
+                throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
929
+            }
930
+        }
931
+    }
932
+
933
+    /**
934
+     * @PasswordConfirmationRequired
935
+     * @NoAdminRequired
936
+     *
937
+     * @param string $userId
938
+     * @param string $groupid
939
+     * @return DataResponse
940
+     * @throws OCSException
941
+     */
942
+    public function addToGroup(string $userId, string $groupid = ''): DataResponse {
943
+        if ($groupid === '') {
944
+            throw new OCSException('', 101);
945
+        }
946
+
947
+        $group = $this->groupManager->get($groupid);
948
+        $targetUser = $this->userManager->get($userId);
949
+        if ($group === null) {
950
+            throw new OCSException('', 102);
951
+        }
952
+        if ($targetUser === null) {
953
+            throw new OCSException('', 103);
954
+        }
955
+
956
+        // If they're not an admin, check they are a subadmin of the group in question
957
+        $loggedInUser = $this->userSession->getUser();
958
+        $subAdminManager = $this->groupManager->getSubAdmin();
959
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
960
+            throw new OCSException('', 104);
961
+        }
962
+
963
+        // Add user to group
964
+        $group->addUser($targetUser);
965
+        return new DataResponse();
966
+    }
967
+
968
+    /**
969
+     * @PasswordConfirmationRequired
970
+     * @NoAdminRequired
971
+     *
972
+     * @param string $userId
973
+     * @param string $groupid
974
+     * @return DataResponse
975
+     * @throws OCSException
976
+     */
977
+    public function removeFromGroup(string $userId, string $groupid): DataResponse {
978
+        $loggedInUser = $this->userSession->getUser();
979
+
980
+        if ($groupid === null || trim($groupid) === '') {
981
+            throw new OCSException('', 101);
982
+        }
983
+
984
+        $group = $this->groupManager->get($groupid);
985
+        if ($group === null) {
986
+            throw new OCSException('', 102);
987
+        }
988
+
989
+        $targetUser = $this->userManager->get($userId);
990
+        if ($targetUser === null) {
991
+            throw new OCSException('', 103);
992
+        }
993
+
994
+        // If they're not an admin, check they are a subadmin of the group in question
995
+        $subAdminManager = $this->groupManager->getSubAdmin();
996
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
997
+            throw new OCSException('', 104);
998
+        }
999
+
1000
+        // Check they aren't removing themselves from 'admin' or their 'subadmin; group
1001
+        if ($targetUser->getUID() === $loggedInUser->getUID()) {
1002
+            if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
1003
+                if ($group->getGID() === 'admin') {
1004
+                    throw new OCSException('Cannot remove yourself from the admin group', 105);
1005
+                }
1006
+            } else {
1007
+                // Not an admin, so the user must be a subadmin of this group, but that is not allowed.
1008
+                throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
1009
+            }
1010
+        } elseif (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
1011
+            /** @var IGroup[] $subAdminGroups */
1012
+            $subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
1013
+            $subAdminGroups = array_map(function (IGroup $subAdminGroup) {
1014
+                return $subAdminGroup->getGID();
1015
+            }, $subAdminGroups);
1016
+            $userGroups = $this->groupManager->getUserGroupIds($targetUser);
1017
+            $userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
1018
+
1019
+            if (count($userSubAdminGroups) <= 1) {
1020
+                // Subadmin must not be able to remove a user from all their subadmin groups.
1021
+                throw new OCSException('Not viable to remove user from the last group you are SubAdmin of', 105);
1022
+            }
1023
+        }
1024
+
1025
+        // Remove user from group
1026
+        $group->removeUser($targetUser);
1027
+        return new DataResponse();
1028
+    }
1029
+
1030
+    /**
1031
+     * Creates a subadmin
1032
+     *
1033
+     * @PasswordConfirmationRequired
1034
+     *
1035
+     * @param string $userId
1036
+     * @param string $groupid
1037
+     * @return DataResponse
1038
+     * @throws OCSException
1039
+     */
1040
+    public function addSubAdmin(string $userId, string $groupid): DataResponse {
1041
+        $group = $this->groupManager->get($groupid);
1042
+        $user = $this->userManager->get($userId);
1043
+
1044
+        // Check if the user exists
1045
+        if ($user === null) {
1046
+            throw new OCSException('User does not exist', 101);
1047
+        }
1048
+        // Check if group exists
1049
+        if ($group === null) {
1050
+            throw new OCSException('Group does not exist',  102);
1051
+        }
1052
+        // Check if trying to make subadmin of admin group
1053
+        if ($group->getGID() === 'admin') {
1054
+            throw new OCSException('Cannot create subadmins for admin group', 103);
1055
+        }
1056
+
1057
+        $subAdminManager = $this->groupManager->getSubAdmin();
1058
+
1059
+        // We cannot be subadmin twice
1060
+        if ($subAdminManager->isSubAdminOfGroup($user, $group)) {
1061
+            return new DataResponse();
1062
+        }
1063
+        // Go
1064
+        $subAdminManager->createSubAdmin($user, $group);
1065
+        return new DataResponse();
1066
+    }
1067
+
1068
+    /**
1069
+     * Removes a subadmin from a group
1070
+     *
1071
+     * @PasswordConfirmationRequired
1072
+     *
1073
+     * @param string $userId
1074
+     * @param string $groupid
1075
+     * @return DataResponse
1076
+     * @throws OCSException
1077
+     */
1078
+    public function removeSubAdmin(string $userId, string $groupid): DataResponse {
1079
+        $group = $this->groupManager->get($groupid);
1080
+        $user = $this->userManager->get($userId);
1081
+        $subAdminManager = $this->groupManager->getSubAdmin();
1082
+
1083
+        // Check if the user exists
1084
+        if ($user === null) {
1085
+            throw new OCSException('User does not exist', 101);
1086
+        }
1087
+        // Check if the group exists
1088
+        if ($group === null) {
1089
+            throw new OCSException('Group does not exist', 101);
1090
+        }
1091
+        // Check if they are a subadmin of this said group
1092
+        if (!$subAdminManager->isSubAdminOfGroup($user, $group)) {
1093
+            throw new OCSException('User is not a subadmin of this group', 102);
1094
+        }
1095
+
1096
+        // Go
1097
+        $subAdminManager->deleteSubAdmin($user, $group);
1098
+        return new DataResponse();
1099
+    }
1100
+
1101
+    /**
1102
+     * Get the groups a user is a subadmin of
1103
+     *
1104
+     * @param string $userId
1105
+     * @return DataResponse
1106
+     * @throws OCSException
1107
+     */
1108
+    public function getUserSubAdminGroups(string $userId): DataResponse {
1109
+        $groups = $this->getUserSubAdminGroupsData($userId);
1110
+        return new DataResponse($groups);
1111
+    }
1112
+
1113
+    /**
1114
+     * @NoAdminRequired
1115
+     * @PasswordConfirmationRequired
1116
+     *
1117
+     * resend welcome message
1118
+     *
1119
+     * @param string $userId
1120
+     * @return DataResponse
1121
+     * @throws OCSException
1122
+     */
1123
+    public function resendWelcomeMessage(string $userId): DataResponse {
1124
+        $currentLoggedInUser = $this->userSession->getUser();
1125
+
1126
+        $targetUser = $this->userManager->get($userId);
1127
+        if ($targetUser === null) {
1128
+            throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
1129
+        }
1130
+
1131
+        // Check if admin / subadmin
1132
+        $subAdminManager = $this->groupManager->getSubAdmin();
1133
+        if (!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
1134
+            && !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
1135
+            // No rights
1136
+            throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
1137
+        }
1138
+
1139
+        $email = $targetUser->getEMailAddress();
1140
+        if ($email === '' || $email === null) {
1141
+            throw new OCSException('Email address not available', 101);
1142
+        }
1143
+
1144
+        try {
1145
+            $emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
1146
+            $this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
1147
+        } catch (\Exception $e) {
1148
+            $this->logger->error("Can't send new user mail to $email",
1149
+                [
1150
+                    'app' => 'settings',
1151
+                    'exception' => $e,
1152
+                ]
1153
+            );
1154
+            throw new OCSException('Sending email failed', 102);
1155
+        }
1156
+
1157
+        return new DataResponse();
1158
+    }
1159 1159
 }
Please login to merge, or discard this patch.
Spacing   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
 		$matches = [];
291 291
 		foreach ($userMatches as $phone => $userId) {
292 292
 			// Not using the ICloudIdManager as that would run a search for each contact to find the display name in the address book
293
-			$matches[$normalizedNumberToKey[$phone]] = $userId . '@' . $cloudUrl;
293
+			$matches[$normalizedNumberToKey[$phone]] = $userId.'@'.$cloudUrl;
294 294
 			$this->knownUserService->storeIsKnownToUser($knownTo, $userId);
295 295
 		}
296 296
 
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
 					throw new OCSException('group '.$group.' does not exist', 104);
355 355
 				}
356 356
 				if (!$isAdmin && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
357
-					throw new OCSException('insufficient privileges for group '. $group, 105);
357
+					throw new OCSException('insufficient privileges for group '.$group, 105);
358 358
 				}
359 359
 			}
360 360
 		} else {
@@ -369,7 +369,7 @@  discard block
 block discarded – undo
369 369
 				$group = $this->groupManager->get($groupid);
370 370
 				// Check if group exists
371 371
 				if ($group === null) {
372
-					throw new OCSException('Subadmin group does not exist',  102);
372
+					throw new OCSException('Subadmin group does not exist', 102);
373 373
 				}
374 374
 				// Check if trying to make subadmin of admin group
375 375
 				if ($group->getGID() === 'admin') {
@@ -410,11 +410,11 @@  discard block
 block discarded – undo
410 410
 
411 411
 		try {
412 412
 			$newUser = $this->userManager->createUser($userid, $password);
413
-			$this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']);
413
+			$this->logger->info('Successful addUser call with userid: '.$userid, ['app' => 'ocs_api']);
414 414
 
415 415
 			foreach ($groups as $group) {
416 416
 				$this->groupManager->get($group)->addUser($newUser);
417
-				$this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']);
417
+				$this->logger->info('Added userid '.$userid.' to group '.$group, ['app' => 'ocs_api']);
418 418
 			}
419 419
 			foreach ($subadminGroups as $group) {
420 420
 				$subAdminManager->createSubAdmin($newUser, $group);
@@ -616,8 +616,8 @@  discard block
 block discarded – undo
616 616
 				$permittedFields[] = IAccountManager::PROPERTY_EMAIL;
617 617
 			}
618 618
 
619
-			$permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX;
620
-			$permittedFields[] = IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX;
619
+			$permittedFields[] = IAccountManager::PROPERTY_DISPLAYNAME.self::SCOPE_SUFFIX;
620
+			$permittedFields[] = IAccountManager::PROPERTY_EMAIL.self::SCOPE_SUFFIX;
621 621
 
622 622
 			$permittedFields[] = 'password';
623 623
 			if ($this->config->getSystemValue('force_language', false) === false ||
@@ -634,12 +634,12 @@  discard block
 block discarded – undo
634 634
 			$permittedFields[] = IAccountManager::PROPERTY_ADDRESS;
635 635
 			$permittedFields[] = IAccountManager::PROPERTY_WEBSITE;
636 636
 			$permittedFields[] = IAccountManager::PROPERTY_TWITTER;
637
-			$permittedFields[] = IAccountManager::PROPERTY_PHONE . self::SCOPE_SUFFIX;
638
-			$permittedFields[] = IAccountManager::PROPERTY_ADDRESS . self::SCOPE_SUFFIX;
639
-			$permittedFields[] = IAccountManager::PROPERTY_WEBSITE . self::SCOPE_SUFFIX;
640
-			$permittedFields[] = IAccountManager::PROPERTY_TWITTER . self::SCOPE_SUFFIX;
637
+			$permittedFields[] = IAccountManager::PROPERTY_PHONE.self::SCOPE_SUFFIX;
638
+			$permittedFields[] = IAccountManager::PROPERTY_ADDRESS.self::SCOPE_SUFFIX;
639
+			$permittedFields[] = IAccountManager::PROPERTY_WEBSITE.self::SCOPE_SUFFIX;
640
+			$permittedFields[] = IAccountManager::PROPERTY_TWITTER.self::SCOPE_SUFFIX;
641 641
 
642
-			$permittedFields[] = IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX;
642
+			$permittedFields[] = IAccountManager::PROPERTY_AVATAR.self::SCOPE_SUFFIX;
643 643
 
644 644
 			// If admin they can edit their own quota
645 645
 			if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
@@ -744,17 +744,17 @@  discard block
 block discarded – undo
744 744
 							$this->knownUserService->deleteByContactUserId($targetUser->getUID());
745 745
 						}
746 746
 					} catch (\InvalidArgumentException $e) {
747
-						throw new OCSException('Invalid ' . $e->getMessage(), 102);
747
+						throw new OCSException('Invalid '.$e->getMessage(), 102);
748 748
 					}
749 749
 				}
750 750
 				break;
751
-			case IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX:
752
-			case IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX:
753
-			case IAccountManager::PROPERTY_PHONE . self::SCOPE_SUFFIX:
754
-			case IAccountManager::PROPERTY_ADDRESS . self::SCOPE_SUFFIX:
755
-			case IAccountManager::PROPERTY_WEBSITE . self::SCOPE_SUFFIX:
756
-			case IAccountManager::PROPERTY_TWITTER . self::SCOPE_SUFFIX:
757
-			case IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX:
751
+			case IAccountManager::PROPERTY_DISPLAYNAME.self::SCOPE_SUFFIX:
752
+			case IAccountManager::PROPERTY_EMAIL.self::SCOPE_SUFFIX:
753
+			case IAccountManager::PROPERTY_PHONE.self::SCOPE_SUFFIX:
754
+			case IAccountManager::PROPERTY_ADDRESS.self::SCOPE_SUFFIX:
755
+			case IAccountManager::PROPERTY_WEBSITE.self::SCOPE_SUFFIX:
756
+			case IAccountManager::PROPERTY_TWITTER.self::SCOPE_SUFFIX:
757
+			case IAccountManager::PROPERTY_AVATAR.self::SCOPE_SUFFIX:
758 758
 				$propertyName = substr($key, 0, strlen($key) - strlen(self::SCOPE_SUFFIX));
759 759
 				$userAccount = $this->accountManager->getAccount($targetUser);
760 760
 				$userProperty = $userAccount->getProperty($propertyName);
@@ -763,7 +763,7 @@  discard block
 block discarded – undo
763 763
 						$userProperty->setScope($value);
764 764
 						$this->accountManager->updateAccount($userAccount);
765 765
 					} catch (\InvalidArgumentException $e) {
766
-						throw new OCSException('Invalid ' . $e->getMessage(), 102);
766
+						throw new OCSException('Invalid '.$e->getMessage(), 102);
767 767
 					}
768 768
 				}
769 769
 				break;
@@ -1010,7 +1010,7 @@  discard block
 block discarded – undo
1010 1010
 		} elseif (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
1011 1011
 			/** @var IGroup[] $subAdminGroups */
1012 1012
 			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
1013
-			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
1013
+			$subAdminGroups = array_map(function(IGroup $subAdminGroup) {
1014 1014
 				return $subAdminGroup->getGID();
1015 1015
 			}, $subAdminGroups);
1016 1016
 			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
@@ -1047,7 +1047,7 @@  discard block
 block discarded – undo
1047 1047
 		}
1048 1048
 		// Check if group exists
1049 1049
 		if ($group === null) {
1050
-			throw new OCSException('Group does not exist',  102);
1050
+			throw new OCSException('Group does not exist', 102);
1051 1051
 		}
1052 1052
 		// Check if trying to make subadmin of admin group
1053 1053
 		if ($group->getGID() === 'admin') {
Please login to merge, or discard this patch.
apps/provisioning_api/lib/Controller/GroupsController.php 1 patch
Indentation   +266 added lines, -266 removed lines patch added patch discarded remove patch
@@ -52,270 +52,270 @@
 block discarded – undo
52 52
 
53 53
 class GroupsController extends AUserData {
54 54
 
55
-	/** @var LoggerInterface */
56
-	private $logger;
57
-
58
-	public function __construct(string $appName,
59
-								IRequest $request,
60
-								IUserManager $userManager,
61
-								IConfig $config,
62
-								IGroupManager $groupManager,
63
-								IUserSession $userSession,
64
-								IAccountManager $accountManager,
65
-								IFactory $l10nFactory,
66
-								LoggerInterface $logger) {
67
-		parent::__construct($appName,
68
-			$request,
69
-			$userManager,
70
-			$config,
71
-			$groupManager,
72
-			$userSession,
73
-			$accountManager,
74
-			$l10nFactory
75
-		);
76
-
77
-		$this->logger = $logger;
78
-	}
79
-
80
-	/**
81
-	 * returns a list of groups
82
-	 *
83
-	 * @NoAdminRequired
84
-	 *
85
-	 * @param string $search
86
-	 * @param int $limit
87
-	 * @param int $offset
88
-	 * @return DataResponse
89
-	 */
90
-	public function getGroups(string $search = '', int $limit = null, int $offset = 0): DataResponse {
91
-		$groups = $this->groupManager->search($search, $limit, $offset);
92
-		$groups = array_map(function ($group) {
93
-			/** @var IGroup $group */
94
-			return $group->getGID();
95
-		}, $groups);
96
-
97
-		return new DataResponse(['groups' => $groups]);
98
-	}
99
-
100
-	/**
101
-	 * returns a list of groups details with ids and displaynames
102
-	 *
103
-	 * @NoAdminRequired
104
-	 *
105
-	 * @param string $search
106
-	 * @param int $limit
107
-	 * @param int $offset
108
-	 * @return DataResponse
109
-	 */
110
-	public function getGroupsDetails(string $search = '', int $limit = null, int $offset = 0): DataResponse {
111
-		$groups = $this->groupManager->search($search, $limit, $offset);
112
-		$groups = array_map(function ($group) {
113
-			/** @var IGroup $group */
114
-			return [
115
-				'id' => $group->getGID(),
116
-				'displayname' => $group->getDisplayName(),
117
-				'usercount' => $group->count(),
118
-				'disabled' => $group->countDisabled(),
119
-				'canAdd' => $group->canAddUser(),
120
-				'canRemove' => $group->canRemoveUser(),
121
-			];
122
-		}, $groups);
123
-
124
-		return new DataResponse(['groups' => $groups]);
125
-	}
126
-
127
-	/**
128
-	 * @NoAdminRequired
129
-	 *
130
-	 * @param string $groupId
131
-	 * @return DataResponse
132
-	 * @throws OCSException
133
-	 *
134
-	 * @deprecated 14 Use getGroupUsers
135
-	 */
136
-	public function getGroup(string $groupId): DataResponse {
137
-		return $this->getGroupUsers($groupId);
138
-	}
139
-
140
-	/**
141
-	 * returns an array of users in the specified group
142
-	 *
143
-	 * @NoAdminRequired
144
-	 *
145
-	 * @param string $groupId
146
-	 * @return DataResponse
147
-	 * @throws OCSException
148
-	 */
149
-	public function getGroupUsers(string $groupId): DataResponse {
150
-		$groupId = urldecode($groupId);
151
-
152
-		$user = $this->userSession->getUser();
153
-		$isSubadminOfGroup = false;
154
-
155
-		// Check the group exists
156
-		$group = $this->groupManager->get($groupId);
157
-		if ($group !== null) {
158
-			$isSubadminOfGroup = $this->groupManager->getSubAdmin()->isSubAdminOfGroup($user, $group);
159
-		} else {
160
-			throw new OCSNotFoundException('The requested group could not be found');
161
-		}
162
-
163
-		// Check subadmin has access to this group
164
-		if ($this->groupManager->isAdmin($user->getUID())
165
-		   || $isSubadminOfGroup) {
166
-			$users = $this->groupManager->get($groupId)->getUsers();
167
-			$users = array_map(function ($user) {
168
-				/** @var IUser $user */
169
-				return $user->getUID();
170
-			}, $users);
171
-			$users = array_values($users);
172
-			return new DataResponse(['users' => $users]);
173
-		}
174
-
175
-		throw new OCSForbiddenException();
176
-	}
177
-
178
-	/**
179
-	 * returns an array of users details in the specified group
180
-	 *
181
-	 * @NoAdminRequired
182
-	 *
183
-	 * @param string $groupId
184
-	 * @param string $search
185
-	 * @param int $limit
186
-	 * @param int $offset
187
-	 * @return DataResponse
188
-	 * @throws OCSException
189
-	 */
190
-	public function getGroupUsersDetails(string $groupId, string $search = '', int $limit = null, int $offset = 0): DataResponse {
191
-		$groupId = urldecode($groupId);
192
-		$currentUser = $this->userSession->getUser();
193
-
194
-		// Check the group exists
195
-		$group = $this->groupManager->get($groupId);
196
-		if ($group !== null) {
197
-			$isSubadminOfGroup = $this->groupManager->getSubAdmin()->isSubAdminOfGroup($currentUser, $group);
198
-		} else {
199
-			throw new OCSException('The requested group could not be found', OCSController::RESPOND_NOT_FOUND);
200
-		}
201
-
202
-		// Check subadmin has access to this group
203
-		if ($this->groupManager->isAdmin($currentUser->getUID()) || $isSubadminOfGroup) {
204
-			$users = $group->searchUsers($search, $limit, $offset);
205
-
206
-			// Extract required number
207
-			$usersDetails = [];
208
-			foreach ($users as $user) {
209
-				try {
210
-					/** @var IUser $user */
211
-					$userId = (string)$user->getUID();
212
-					$userData = $this->getUserData($userId);
213
-					// Do not insert empty entry
214
-					if (!empty($userData)) {
215
-						$usersDetails[$userId] = $userData;
216
-					} else {
217
-						// Logged user does not have permissions to see this user
218
-						// only showing its id
219
-						$usersDetails[$userId] = ['id' => $userId];
220
-					}
221
-				} catch (OCSNotFoundException $e) {
222
-					// continue if a users ceased to exist.
223
-				}
224
-			}
225
-			return new DataResponse(['users' => $usersDetails]);
226
-		}
227
-
228
-		throw new OCSException('User does not have access to specified group', OCSController::RESPOND_UNAUTHORISED);
229
-	}
230
-
231
-	/**
232
-	 * creates a new group
233
-	 *
234
-	 * @PasswordConfirmationRequired
235
-	 *
236
-	 * @param string $groupid
237
-	 * @return DataResponse
238
-	 * @throws OCSException
239
-	 */
240
-	public function addGroup(string $groupid): DataResponse {
241
-		// Validate name
242
-		if (empty($groupid)) {
243
-			$this->logger->error('Group name not supplied', ['app' => 'provisioning_api']);
244
-			throw new OCSException('Invalid group name', 101);
245
-		}
246
-		// Check if it exists
247
-		if ($this->groupManager->groupExists($groupid)) {
248
-			throw new OCSException('group exists', 102);
249
-		}
250
-		$this->groupManager->createGroup($groupid);
251
-		return new DataResponse();
252
-	}
253
-
254
-	/**
255
-	 * @PasswordConfirmationRequired
256
-	 *
257
-	 * @param string $groupId
258
-	 * @param string $key
259
-	 * @param string $value
260
-	 * @return DataResponse
261
-	 * @throws OCSException
262
-	 */
263
-	public function updateGroup(string $groupId, string $key, string $value): DataResponse {
264
-		$groupId = urldecode($groupId);
265
-
266
-		if ($key === 'displayname') {
267
-			$group = $this->groupManager->get($groupId);
268
-			if ($group->setDisplayName($value)) {
269
-				return new DataResponse();
270
-			}
271
-
272
-			throw new OCSException('Not supported by backend', 101);
273
-		} else {
274
-			throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
275
-		}
276
-	}
277
-
278
-	/**
279
-	 * @PasswordConfirmationRequired
280
-	 *
281
-	 * @param string $groupId
282
-	 * @return DataResponse
283
-	 * @throws OCSException
284
-	 */
285
-	public function deleteGroup(string $groupId): DataResponse {
286
-		$groupId = urldecode($groupId);
287
-
288
-		// Check it exists
289
-		if (!$this->groupManager->groupExists($groupId)) {
290
-			throw new OCSException('', 101);
291
-		} elseif ($groupId === 'admin' || !$this->groupManager->get($groupId)->delete()) {
292
-			// Cannot delete admin group
293
-			throw new OCSException('', 102);
294
-		}
295
-
296
-		return new DataResponse();
297
-	}
298
-
299
-	/**
300
-	 * @param string $groupId
301
-	 * @return DataResponse
302
-	 * @throws OCSException
303
-	 */
304
-	public function getSubAdminsOfGroup(string $groupId): DataResponse {
305
-		// Check group exists
306
-		$targetGroup = $this->groupManager->get($groupId);
307
-		if ($targetGroup === null) {
308
-			throw new OCSException('Group does not exist', 101);
309
-		}
310
-
311
-		/** @var IUser[] $subadmins */
312
-		$subadmins = $this->groupManager->getSubAdmin()->getGroupsSubAdmins($targetGroup);
313
-		// New class returns IUser[] so convert back
314
-		$uids = [];
315
-		foreach ($subadmins as $user) {
316
-			$uids[] = $user->getUID();
317
-		}
318
-
319
-		return new DataResponse($uids);
320
-	}
55
+    /** @var LoggerInterface */
56
+    private $logger;
57
+
58
+    public function __construct(string $appName,
59
+                                IRequest $request,
60
+                                IUserManager $userManager,
61
+                                IConfig $config,
62
+                                IGroupManager $groupManager,
63
+                                IUserSession $userSession,
64
+                                IAccountManager $accountManager,
65
+                                IFactory $l10nFactory,
66
+                                LoggerInterface $logger) {
67
+        parent::__construct($appName,
68
+            $request,
69
+            $userManager,
70
+            $config,
71
+            $groupManager,
72
+            $userSession,
73
+            $accountManager,
74
+            $l10nFactory
75
+        );
76
+
77
+        $this->logger = $logger;
78
+    }
79
+
80
+    /**
81
+     * returns a list of groups
82
+     *
83
+     * @NoAdminRequired
84
+     *
85
+     * @param string $search
86
+     * @param int $limit
87
+     * @param int $offset
88
+     * @return DataResponse
89
+     */
90
+    public function getGroups(string $search = '', int $limit = null, int $offset = 0): DataResponse {
91
+        $groups = $this->groupManager->search($search, $limit, $offset);
92
+        $groups = array_map(function ($group) {
93
+            /** @var IGroup $group */
94
+            return $group->getGID();
95
+        }, $groups);
96
+
97
+        return new DataResponse(['groups' => $groups]);
98
+    }
99
+
100
+    /**
101
+     * returns a list of groups details with ids and displaynames
102
+     *
103
+     * @NoAdminRequired
104
+     *
105
+     * @param string $search
106
+     * @param int $limit
107
+     * @param int $offset
108
+     * @return DataResponse
109
+     */
110
+    public function getGroupsDetails(string $search = '', int $limit = null, int $offset = 0): DataResponse {
111
+        $groups = $this->groupManager->search($search, $limit, $offset);
112
+        $groups = array_map(function ($group) {
113
+            /** @var IGroup $group */
114
+            return [
115
+                'id' => $group->getGID(),
116
+                'displayname' => $group->getDisplayName(),
117
+                'usercount' => $group->count(),
118
+                'disabled' => $group->countDisabled(),
119
+                'canAdd' => $group->canAddUser(),
120
+                'canRemove' => $group->canRemoveUser(),
121
+            ];
122
+        }, $groups);
123
+
124
+        return new DataResponse(['groups' => $groups]);
125
+    }
126
+
127
+    /**
128
+     * @NoAdminRequired
129
+     *
130
+     * @param string $groupId
131
+     * @return DataResponse
132
+     * @throws OCSException
133
+     *
134
+     * @deprecated 14 Use getGroupUsers
135
+     */
136
+    public function getGroup(string $groupId): DataResponse {
137
+        return $this->getGroupUsers($groupId);
138
+    }
139
+
140
+    /**
141
+     * returns an array of users in the specified group
142
+     *
143
+     * @NoAdminRequired
144
+     *
145
+     * @param string $groupId
146
+     * @return DataResponse
147
+     * @throws OCSException
148
+     */
149
+    public function getGroupUsers(string $groupId): DataResponse {
150
+        $groupId = urldecode($groupId);
151
+
152
+        $user = $this->userSession->getUser();
153
+        $isSubadminOfGroup = false;
154
+
155
+        // Check the group exists
156
+        $group = $this->groupManager->get($groupId);
157
+        if ($group !== null) {
158
+            $isSubadminOfGroup = $this->groupManager->getSubAdmin()->isSubAdminOfGroup($user, $group);
159
+        } else {
160
+            throw new OCSNotFoundException('The requested group could not be found');
161
+        }
162
+
163
+        // Check subadmin has access to this group
164
+        if ($this->groupManager->isAdmin($user->getUID())
165
+           || $isSubadminOfGroup) {
166
+            $users = $this->groupManager->get($groupId)->getUsers();
167
+            $users = array_map(function ($user) {
168
+                /** @var IUser $user */
169
+                return $user->getUID();
170
+            }, $users);
171
+            $users = array_values($users);
172
+            return new DataResponse(['users' => $users]);
173
+        }
174
+
175
+        throw new OCSForbiddenException();
176
+    }
177
+
178
+    /**
179
+     * returns an array of users details in the specified group
180
+     *
181
+     * @NoAdminRequired
182
+     *
183
+     * @param string $groupId
184
+     * @param string $search
185
+     * @param int $limit
186
+     * @param int $offset
187
+     * @return DataResponse
188
+     * @throws OCSException
189
+     */
190
+    public function getGroupUsersDetails(string $groupId, string $search = '', int $limit = null, int $offset = 0): DataResponse {
191
+        $groupId = urldecode($groupId);
192
+        $currentUser = $this->userSession->getUser();
193
+
194
+        // Check the group exists
195
+        $group = $this->groupManager->get($groupId);
196
+        if ($group !== null) {
197
+            $isSubadminOfGroup = $this->groupManager->getSubAdmin()->isSubAdminOfGroup($currentUser, $group);
198
+        } else {
199
+            throw new OCSException('The requested group could not be found', OCSController::RESPOND_NOT_FOUND);
200
+        }
201
+
202
+        // Check subadmin has access to this group
203
+        if ($this->groupManager->isAdmin($currentUser->getUID()) || $isSubadminOfGroup) {
204
+            $users = $group->searchUsers($search, $limit, $offset);
205
+
206
+            // Extract required number
207
+            $usersDetails = [];
208
+            foreach ($users as $user) {
209
+                try {
210
+                    /** @var IUser $user */
211
+                    $userId = (string)$user->getUID();
212
+                    $userData = $this->getUserData($userId);
213
+                    // Do not insert empty entry
214
+                    if (!empty($userData)) {
215
+                        $usersDetails[$userId] = $userData;
216
+                    } else {
217
+                        // Logged user does not have permissions to see this user
218
+                        // only showing its id
219
+                        $usersDetails[$userId] = ['id' => $userId];
220
+                    }
221
+                } catch (OCSNotFoundException $e) {
222
+                    // continue if a users ceased to exist.
223
+                }
224
+            }
225
+            return new DataResponse(['users' => $usersDetails]);
226
+        }
227
+
228
+        throw new OCSException('User does not have access to specified group', OCSController::RESPOND_UNAUTHORISED);
229
+    }
230
+
231
+    /**
232
+     * creates a new group
233
+     *
234
+     * @PasswordConfirmationRequired
235
+     *
236
+     * @param string $groupid
237
+     * @return DataResponse
238
+     * @throws OCSException
239
+     */
240
+    public function addGroup(string $groupid): DataResponse {
241
+        // Validate name
242
+        if (empty($groupid)) {
243
+            $this->logger->error('Group name not supplied', ['app' => 'provisioning_api']);
244
+            throw new OCSException('Invalid group name', 101);
245
+        }
246
+        // Check if it exists
247
+        if ($this->groupManager->groupExists($groupid)) {
248
+            throw new OCSException('group exists', 102);
249
+        }
250
+        $this->groupManager->createGroup($groupid);
251
+        return new DataResponse();
252
+    }
253
+
254
+    /**
255
+     * @PasswordConfirmationRequired
256
+     *
257
+     * @param string $groupId
258
+     * @param string $key
259
+     * @param string $value
260
+     * @return DataResponse
261
+     * @throws OCSException
262
+     */
263
+    public function updateGroup(string $groupId, string $key, string $value): DataResponse {
264
+        $groupId = urldecode($groupId);
265
+
266
+        if ($key === 'displayname') {
267
+            $group = $this->groupManager->get($groupId);
268
+            if ($group->setDisplayName($value)) {
269
+                return new DataResponse();
270
+            }
271
+
272
+            throw new OCSException('Not supported by backend', 101);
273
+        } else {
274
+            throw new OCSException('', OCSController::RESPOND_UNAUTHORISED);
275
+        }
276
+    }
277
+
278
+    /**
279
+     * @PasswordConfirmationRequired
280
+     *
281
+     * @param string $groupId
282
+     * @return DataResponse
283
+     * @throws OCSException
284
+     */
285
+    public function deleteGroup(string $groupId): DataResponse {
286
+        $groupId = urldecode($groupId);
287
+
288
+        // Check it exists
289
+        if (!$this->groupManager->groupExists($groupId)) {
290
+            throw new OCSException('', 101);
291
+        } elseif ($groupId === 'admin' || !$this->groupManager->get($groupId)->delete()) {
292
+            // Cannot delete admin group
293
+            throw new OCSException('', 102);
294
+        }
295
+
296
+        return new DataResponse();
297
+    }
298
+
299
+    /**
300
+     * @param string $groupId
301
+     * @return DataResponse
302
+     * @throws OCSException
303
+     */
304
+    public function getSubAdminsOfGroup(string $groupId): DataResponse {
305
+        // Check group exists
306
+        $targetGroup = $this->groupManager->get($groupId);
307
+        if ($targetGroup === null) {
308
+            throw new OCSException('Group does not exist', 101);
309
+        }
310
+
311
+        /** @var IUser[] $subadmins */
312
+        $subadmins = $this->groupManager->getSubAdmin()->getGroupsSubAdmins($targetGroup);
313
+        // New class returns IUser[] so convert back
314
+        $uids = [];
315
+        foreach ($subadmins as $user) {
316
+            $uids[] = $user->getUID();
317
+        }
318
+
319
+        return new DataResponse($uids);
320
+    }
321 321
 }
Please login to merge, or discard this patch.
apps/provisioning_api/lib/Controller/AUserData.php 2 patches
Indentation   +191 added lines, -191 removed lines patch added patch discarded remove patch
@@ -52,195 +52,195 @@
 block discarded – undo
52 52
 use OCP\User\Backend\ISetPasswordBackend;
53 53
 
54 54
 abstract class AUserData extends OCSController {
55
-	public const SCOPE_SUFFIX = 'Scope';
56
-
57
-	/** @var IUserManager */
58
-	protected $userManager;
59
-	/** @var IConfig */
60
-	protected $config;
61
-	/** @var IGroupManager|Manager */ // FIXME Requires a method that is not on the interface
62
-	protected $groupManager;
63
-	/** @var IUserSession */
64
-	protected $userSession;
65
-	/** @var IAccountManager */
66
-	protected $accountManager;
67
-	/** @var IFactory */
68
-	protected $l10nFactory;
69
-
70
-	public function __construct(string $appName,
71
-								IRequest $request,
72
-								IUserManager $userManager,
73
-								IConfig $config,
74
-								IGroupManager $groupManager,
75
-								IUserSession $userSession,
76
-								IAccountManager $accountManager,
77
-								IFactory $l10nFactory) {
78
-		parent::__construct($appName, $request);
79
-
80
-		$this->userManager = $userManager;
81
-		$this->config = $config;
82
-		$this->groupManager = $groupManager;
83
-		$this->userSession = $userSession;
84
-		$this->accountManager = $accountManager;
85
-		$this->l10nFactory = $l10nFactory;
86
-	}
87
-
88
-	/**
89
-	 * creates a array with all user data
90
-	 *
91
-	 * @param string $userId
92
-	 * @param bool $includeScopes
93
-	 * @return array
94
-	 * @throws NotFoundException
95
-	 * @throws OCSException
96
-	 * @throws OCSNotFoundException
97
-	 */
98
-	protected function getUserData(string $userId, bool $includeScopes = false): array {
99
-		$currentLoggedInUser = $this->userSession->getUser();
100
-
101
-		$data = [];
102
-
103
-		// Check if the target user exists
104
-		$targetUserObject = $this->userManager->get($userId);
105
-		if ($targetUserObject === null) {
106
-			throw new OCSNotFoundException('User does not exist');
107
-		}
108
-
109
-		// Should be at least Admin Or SubAdmin!
110
-		if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
111
-			|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
112
-			$data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true') === 'true';
113
-		} else {
114
-			// Check they are looking up themselves
115
-			if ($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
116
-				return $data;
117
-			}
118
-		}
119
-
120
-		// Get groups data
121
-		$userAccount = $this->accountManager->getAccount($targetUserObject);
122
-		$groups = $this->groupManager->getUserGroups($targetUserObject);
123
-		$gids = [];
124
-		foreach ($groups as $group) {
125
-			$gids[] = $group->getGID();
126
-		}
127
-
128
-		try {
129
-			# might be thrown by LDAP due to handling of users disappears
130
-			# from the external source (reasons unknown to us)
131
-			# cf. https://github.com/nextcloud/server/issues/12991
132
-			$data['storageLocation'] = $targetUserObject->getHome();
133
-		} catch (NoUserException $e) {
134
-			throw new OCSNotFoundException($e->getMessage(), $e);
135
-		}
136
-
137
-		// Find the data
138
-		$data['id'] = $targetUserObject->getUID();
139
-		$data['lastLogin'] = $targetUserObject->getLastLogin() * 1000;
140
-		$data['backend'] = $targetUserObject->getBackendClassName();
141
-		$data['subadmin'] = $this->getUserSubAdminGroupsData($targetUserObject->getUID());
142
-		$data['quota'] = $this->fillStorageInfo($targetUserObject->getUID());
143
-
144
-		try {
145
-			if ($includeScopes) {
146
-				$data[IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_AVATAR)->getScope();
147
-			}
148
-
149
-			$data[IAccountManager::PROPERTY_EMAIL] = $targetUserObject->getEMailAddress();
150
-			if ($includeScopes) {
151
-				$data[IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getScope();
152
-			}
153
-			$data[IAccountManager::PROPERTY_DISPLAYNAME] = $targetUserObject->getDisplayName();
154
-			if ($includeScopes) {
155
-				$data[IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getScope();
156
-			}
157
-
158
-			foreach ([
159
-				IAccountManager::PROPERTY_PHONE,
160
-				IAccountManager::PROPERTY_ADDRESS,
161
-				IAccountManager::PROPERTY_WEBSITE,
162
-				IAccountManager::PROPERTY_TWITTER,
163
-			] as $propertyName) {
164
-				$property = $userAccount->getProperty($propertyName);
165
-				$data[$propertyName] = $property->getValue();
166
-				if ($includeScopes) {
167
-					$data[$propertyName . self::SCOPE_SUFFIX] = $property->getScope();
168
-				}
169
-			}
170
-		} catch (PropertyDoesNotExistException $e) {
171
-			// hard coded properties should exist
172
-			throw new OCSException($e->getMessage(), Http::STATUS_INTERNAL_SERVER_ERROR, $e);
173
-		}
174
-
175
-		$data['groups'] = $gids;
176
-		$data['language'] = $this->l10nFactory->getUserLanguage($targetUserObject);
177
-		$data['locale'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'locale');
178
-
179
-		$backend = $targetUserObject->getBackend();
180
-		$data['backendCapabilities'] = [
181
-			'setDisplayName' => $backend instanceof ISetDisplayNameBackend || $backend->implementsActions(Backend::SET_DISPLAYNAME),
182
-			'setPassword' => $backend instanceof ISetPasswordBackend || $backend->implementsActions(Backend::SET_PASSWORD),
183
-		];
184
-
185
-		return $data;
186
-	}
187
-
188
-	/**
189
-	 * Get the groups a user is a subadmin of
190
-	 *
191
-	 * @param string $userId
192
-	 * @return array
193
-	 * @throws OCSException
194
-	 */
195
-	protected function getUserSubAdminGroupsData(string $userId): array {
196
-		$user = $this->userManager->get($userId);
197
-		// Check if the user exists
198
-		if ($user === null) {
199
-			throw new OCSNotFoundException('User does not exist');
200
-		}
201
-
202
-		// Get the subadmin groups
203
-		$subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
204
-		$groups = [];
205
-		foreach ($subAdminGroups as $key => $group) {
206
-			$groups[] = $group->getGID();
207
-		}
208
-
209
-		return $groups;
210
-	}
211
-
212
-	/**
213
-	 * @param string $userId
214
-	 * @return array
215
-	 * @throws OCSException
216
-	 */
217
-	protected function fillStorageInfo(string $userId): array {
218
-		try {
219
-			\OC_Util::tearDownFS();
220
-			\OC_Util::setupFS($userId);
221
-			$storage = OC_Helper::getStorageInfo('/');
222
-			$data = [
223
-				'free' => $storage['free'],
224
-				'used' => $storage['used'],
225
-				'total' => $storage['total'],
226
-				'relative' => $storage['relative'],
227
-				'quota' => $storage['quota'],
228
-			];
229
-		} catch (NotFoundException $ex) {
230
-			// User fs is not setup yet
231
-			$user = $this->userManager->get($userId);
232
-			if ($user === null) {
233
-				throw new OCSException('User does not exist', 101);
234
-			}
235
-			$quota = $user->getQuota();
236
-			if ($quota !== 'none') {
237
-				$quota = OC_Helper::computerFileSize($quota);
238
-			}
239
-			$data = [
240
-				'quota' => $quota !== false ? $quota : 'none',
241
-				'used' => 0
242
-			];
243
-		}
244
-		return $data;
245
-	}
55
+    public const SCOPE_SUFFIX = 'Scope';
56
+
57
+    /** @var IUserManager */
58
+    protected $userManager;
59
+    /** @var IConfig */
60
+    protected $config;
61
+    /** @var IGroupManager|Manager */ // FIXME Requires a method that is not on the interface
62
+    protected $groupManager;
63
+    /** @var IUserSession */
64
+    protected $userSession;
65
+    /** @var IAccountManager */
66
+    protected $accountManager;
67
+    /** @var IFactory */
68
+    protected $l10nFactory;
69
+
70
+    public function __construct(string $appName,
71
+                                IRequest $request,
72
+                                IUserManager $userManager,
73
+                                IConfig $config,
74
+                                IGroupManager $groupManager,
75
+                                IUserSession $userSession,
76
+                                IAccountManager $accountManager,
77
+                                IFactory $l10nFactory) {
78
+        parent::__construct($appName, $request);
79
+
80
+        $this->userManager = $userManager;
81
+        $this->config = $config;
82
+        $this->groupManager = $groupManager;
83
+        $this->userSession = $userSession;
84
+        $this->accountManager = $accountManager;
85
+        $this->l10nFactory = $l10nFactory;
86
+    }
87
+
88
+    /**
89
+     * creates a array with all user data
90
+     *
91
+     * @param string $userId
92
+     * @param bool $includeScopes
93
+     * @return array
94
+     * @throws NotFoundException
95
+     * @throws OCSException
96
+     * @throws OCSNotFoundException
97
+     */
98
+    protected function getUserData(string $userId, bool $includeScopes = false): array {
99
+        $currentLoggedInUser = $this->userSession->getUser();
100
+
101
+        $data = [];
102
+
103
+        // Check if the target user exists
104
+        $targetUserObject = $this->userManager->get($userId);
105
+        if ($targetUserObject === null) {
106
+            throw new OCSNotFoundException('User does not exist');
107
+        }
108
+
109
+        // Should be at least Admin Or SubAdmin!
110
+        if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
111
+            || $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
112
+            $data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true') === 'true';
113
+        } else {
114
+            // Check they are looking up themselves
115
+            if ($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
116
+                return $data;
117
+            }
118
+        }
119
+
120
+        // Get groups data
121
+        $userAccount = $this->accountManager->getAccount($targetUserObject);
122
+        $groups = $this->groupManager->getUserGroups($targetUserObject);
123
+        $gids = [];
124
+        foreach ($groups as $group) {
125
+            $gids[] = $group->getGID();
126
+        }
127
+
128
+        try {
129
+            # might be thrown by LDAP due to handling of users disappears
130
+            # from the external source (reasons unknown to us)
131
+            # cf. https://github.com/nextcloud/server/issues/12991
132
+            $data['storageLocation'] = $targetUserObject->getHome();
133
+        } catch (NoUserException $e) {
134
+            throw new OCSNotFoundException($e->getMessage(), $e);
135
+        }
136
+
137
+        // Find the data
138
+        $data['id'] = $targetUserObject->getUID();
139
+        $data['lastLogin'] = $targetUserObject->getLastLogin() * 1000;
140
+        $data['backend'] = $targetUserObject->getBackendClassName();
141
+        $data['subadmin'] = $this->getUserSubAdminGroupsData($targetUserObject->getUID());
142
+        $data['quota'] = $this->fillStorageInfo($targetUserObject->getUID());
143
+
144
+        try {
145
+            if ($includeScopes) {
146
+                $data[IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_AVATAR)->getScope();
147
+            }
148
+
149
+            $data[IAccountManager::PROPERTY_EMAIL] = $targetUserObject->getEMailAddress();
150
+            if ($includeScopes) {
151
+                $data[IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getScope();
152
+            }
153
+            $data[IAccountManager::PROPERTY_DISPLAYNAME] = $targetUserObject->getDisplayName();
154
+            if ($includeScopes) {
155
+                $data[IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getScope();
156
+            }
157
+
158
+            foreach ([
159
+                IAccountManager::PROPERTY_PHONE,
160
+                IAccountManager::PROPERTY_ADDRESS,
161
+                IAccountManager::PROPERTY_WEBSITE,
162
+                IAccountManager::PROPERTY_TWITTER,
163
+            ] as $propertyName) {
164
+                $property = $userAccount->getProperty($propertyName);
165
+                $data[$propertyName] = $property->getValue();
166
+                if ($includeScopes) {
167
+                    $data[$propertyName . self::SCOPE_SUFFIX] = $property->getScope();
168
+                }
169
+            }
170
+        } catch (PropertyDoesNotExistException $e) {
171
+            // hard coded properties should exist
172
+            throw new OCSException($e->getMessage(), Http::STATUS_INTERNAL_SERVER_ERROR, $e);
173
+        }
174
+
175
+        $data['groups'] = $gids;
176
+        $data['language'] = $this->l10nFactory->getUserLanguage($targetUserObject);
177
+        $data['locale'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'locale');
178
+
179
+        $backend = $targetUserObject->getBackend();
180
+        $data['backendCapabilities'] = [
181
+            'setDisplayName' => $backend instanceof ISetDisplayNameBackend || $backend->implementsActions(Backend::SET_DISPLAYNAME),
182
+            'setPassword' => $backend instanceof ISetPasswordBackend || $backend->implementsActions(Backend::SET_PASSWORD),
183
+        ];
184
+
185
+        return $data;
186
+    }
187
+
188
+    /**
189
+     * Get the groups a user is a subadmin of
190
+     *
191
+     * @param string $userId
192
+     * @return array
193
+     * @throws OCSException
194
+     */
195
+    protected function getUserSubAdminGroupsData(string $userId): array {
196
+        $user = $this->userManager->get($userId);
197
+        // Check if the user exists
198
+        if ($user === null) {
199
+            throw new OCSNotFoundException('User does not exist');
200
+        }
201
+
202
+        // Get the subadmin groups
203
+        $subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
204
+        $groups = [];
205
+        foreach ($subAdminGroups as $key => $group) {
206
+            $groups[] = $group->getGID();
207
+        }
208
+
209
+        return $groups;
210
+    }
211
+
212
+    /**
213
+     * @param string $userId
214
+     * @return array
215
+     * @throws OCSException
216
+     */
217
+    protected function fillStorageInfo(string $userId): array {
218
+        try {
219
+            \OC_Util::tearDownFS();
220
+            \OC_Util::setupFS($userId);
221
+            $storage = OC_Helper::getStorageInfo('/');
222
+            $data = [
223
+                'free' => $storage['free'],
224
+                'used' => $storage['used'],
225
+                'total' => $storage['total'],
226
+                'relative' => $storage['relative'],
227
+                'quota' => $storage['quota'],
228
+            ];
229
+        } catch (NotFoundException $ex) {
230
+            // User fs is not setup yet
231
+            $user = $this->userManager->get($userId);
232
+            if ($user === null) {
233
+                throw new OCSException('User does not exist', 101);
234
+            }
235
+            $quota = $user->getQuota();
236
+            if ($quota !== 'none') {
237
+                $quota = OC_Helper::computerFileSize($quota);
238
+            }
239
+            $data = [
240
+                'quota' => $quota !== false ? $quota : 'none',
241
+                'used' => 0
242
+            ];
243
+        }
244
+        return $data;
245
+    }
246 246
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -143,16 +143,16 @@  discard block
 block discarded – undo
143 143
 
144 144
 		try {
145 145
 			if ($includeScopes) {
146
-				$data[IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_AVATAR)->getScope();
146
+				$data[IAccountManager::PROPERTY_AVATAR.self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_AVATAR)->getScope();
147 147
 			}
148 148
 
149 149
 			$data[IAccountManager::PROPERTY_EMAIL] = $targetUserObject->getEMailAddress();
150 150
 			if ($includeScopes) {
151
-				$data[IAccountManager::PROPERTY_EMAIL . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getScope();
151
+				$data[IAccountManager::PROPERTY_EMAIL.self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_EMAIL)->getScope();
152 152
 			}
153 153
 			$data[IAccountManager::PROPERTY_DISPLAYNAME] = $targetUserObject->getDisplayName();
154 154
 			if ($includeScopes) {
155
-				$data[IAccountManager::PROPERTY_DISPLAYNAME . self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getScope();
155
+				$data[IAccountManager::PROPERTY_DISPLAYNAME.self::SCOPE_SUFFIX] = $userAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getScope();
156 156
 			}
157 157
 
158 158
 			foreach ([
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
 				$property = $userAccount->getProperty($propertyName);
165 165
 				$data[$propertyName] = $property->getValue();
166 166
 				if ($includeScopes) {
167
-					$data[$propertyName . self::SCOPE_SUFFIX] = $property->getScope();
167
+					$data[$propertyName.self::SCOPE_SUFFIX] = $property->getScope();
168 168
 				}
169 169
 			}
170 170
 		} catch (PropertyDoesNotExistException $e) {
Please login to merge, or discard this patch.
lib/public/Accounts/IAccountProperty.php 1 patch
Indentation   +60 added lines, -60 removed lines patch added patch discarded remove patch
@@ -35,70 +35,70 @@
 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
 }
Please login to merge, or discard this patch.
lib/private/Accounts/AccountProperty.php 1 patch
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -31,137 +31,137 @@
 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
-
43
-	public function __construct(string $name, string $value, string $scope, string $verified) {
44
-		$this->name = $name;
45
-		$this->value = $value;
46
-		$this->setScope($scope);
47
-		$this->verified = $verified;
48
-	}
49
-
50
-	public function jsonSerialize() {
51
-		return [
52
-			'name' => $this->getName(),
53
-			'value' => $this->getValue(),
54
-			'scope' => $this->getScope(),
55
-			'verified' => $this->getVerified()
56
-		];
57
-	}
58
-
59
-	/**
60
-	 * Set the value of a property
61
-	 *
62
-	 * @since 15.0.0
63
-	 *
64
-	 * @param string $value
65
-	 * @return IAccountProperty
66
-	 */
67
-	public function setValue(string $value): IAccountProperty {
68
-		$this->value = $value;
69
-		return $this;
70
-	}
71
-
72
-	/**
73
-	 * Set the scope of a property
74
-	 *
75
-	 * @since 15.0.0
76
-	 *
77
-	 * @param string $scope
78
-	 * @return IAccountProperty
79
-	 */
80
-	public function setScope(string $scope): IAccountProperty {
81
-		$newScope = $this->mapScopeToV2($scope);
82
-		if (!in_array($newScope, [
83
-			IAccountManager::SCOPE_LOCAL,
84
-			IAccountManager::SCOPE_FEDERATED,
85
-			IAccountManager::SCOPE_PRIVATE,
86
-			IAccountManager::SCOPE_PUBLISHED
87
-		])) {
88
-			throw new \InvalidArgumentException('Invalid scope');
89
-		}
90
-		$this->scope = $newScope;
91
-		return $this;
92
-	}
93
-
94
-	/**
95
-	 * Set the verification status of a property
96
-	 *
97
-	 * @since 15.0.0
98
-	 *
99
-	 * @param string $verified
100
-	 * @return IAccountProperty
101
-	 */
102
-	public function setVerified(string $verified): IAccountProperty {
103
-		$this->verified = $verified;
104
-		return $this;
105
-	}
106
-
107
-	/**
108
-	 * Get the name of a property
109
-	 *
110
-	 * @since 15.0.0
111
-	 *
112
-	 * @return string
113
-	 */
114
-	public function getName(): string {
115
-		return $this->name;
116
-	}
117
-
118
-	/**
119
-	 * Get the value of a property
120
-	 *
121
-	 * @since 15.0.0
122
-	 *
123
-	 * @return string
124
-	 */
125
-	public function getValue(): string {
126
-		return $this->value;
127
-	}
128
-
129
-	/**
130
-	 * Get the scope of a property
131
-	 *
132
-	 * @since 15.0.0
133
-	 *
134
-	 * @return string
135
-	 */
136
-	public function getScope(): string {
137
-		return $this->scope;
138
-	}
139
-
140
-	public static function mapScopeToV2(string $scope): string {
141
-		if (strpos($scope, 'v2-') === 0) {
142
-			return $scope;
143
-		}
144
-
145
-		switch ($scope) {
146
-			case IAccountManager::VISIBILITY_PRIVATE:
147
-				return IAccountManager::SCOPE_LOCAL;
148
-			case IAccountManager::VISIBILITY_CONTACTS_ONLY:
149
-				return IAccountManager::SCOPE_FEDERATED;
150
-			case IAccountManager::VISIBILITY_PUBLIC:
151
-				return IAccountManager::SCOPE_PUBLISHED;
152
-			default:
153
-				return $scope;
154
-		}
155
-	}
156
-
157
-	/**
158
-	 * Get the verification status of a property
159
-	 *
160
-	 * @since 15.0.0
161
-	 *
162
-	 * @return string
163
-	 */
164
-	public function getVerified(): string {
165
-		return $this->verified;
166
-	}
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
+
43
+    public function __construct(string $name, string $value, string $scope, string $verified) {
44
+        $this->name = $name;
45
+        $this->value = $value;
46
+        $this->setScope($scope);
47
+        $this->verified = $verified;
48
+    }
49
+
50
+    public function jsonSerialize() {
51
+        return [
52
+            'name' => $this->getName(),
53
+            'value' => $this->getValue(),
54
+            'scope' => $this->getScope(),
55
+            'verified' => $this->getVerified()
56
+        ];
57
+    }
58
+
59
+    /**
60
+     * Set the value of a property
61
+     *
62
+     * @since 15.0.0
63
+     *
64
+     * @param string $value
65
+     * @return IAccountProperty
66
+     */
67
+    public function setValue(string $value): IAccountProperty {
68
+        $this->value = $value;
69
+        return $this;
70
+    }
71
+
72
+    /**
73
+     * Set the scope of a property
74
+     *
75
+     * @since 15.0.0
76
+     *
77
+     * @param string $scope
78
+     * @return IAccountProperty
79
+     */
80
+    public function setScope(string $scope): IAccountProperty {
81
+        $newScope = $this->mapScopeToV2($scope);
82
+        if (!in_array($newScope, [
83
+            IAccountManager::SCOPE_LOCAL,
84
+            IAccountManager::SCOPE_FEDERATED,
85
+            IAccountManager::SCOPE_PRIVATE,
86
+            IAccountManager::SCOPE_PUBLISHED
87
+        ])) {
88
+            throw new \InvalidArgumentException('Invalid scope');
89
+        }
90
+        $this->scope = $newScope;
91
+        return $this;
92
+    }
93
+
94
+    /**
95
+     * Set the verification status of a property
96
+     *
97
+     * @since 15.0.0
98
+     *
99
+     * @param string $verified
100
+     * @return IAccountProperty
101
+     */
102
+    public function setVerified(string $verified): IAccountProperty {
103
+        $this->verified = $verified;
104
+        return $this;
105
+    }
106
+
107
+    /**
108
+     * Get the name of a property
109
+     *
110
+     * @since 15.0.0
111
+     *
112
+     * @return string
113
+     */
114
+    public function getName(): string {
115
+        return $this->name;
116
+    }
117
+
118
+    /**
119
+     * Get the value of a property
120
+     *
121
+     * @since 15.0.0
122
+     *
123
+     * @return string
124
+     */
125
+    public function getValue(): string {
126
+        return $this->value;
127
+    }
128
+
129
+    /**
130
+     * Get the scope of a property
131
+     *
132
+     * @since 15.0.0
133
+     *
134
+     * @return string
135
+     */
136
+    public function getScope(): string {
137
+        return $this->scope;
138
+    }
139
+
140
+    public static function mapScopeToV2(string $scope): string {
141
+        if (strpos($scope, 'v2-') === 0) {
142
+            return $scope;
143
+        }
144
+
145
+        switch ($scope) {
146
+            case IAccountManager::VISIBILITY_PRIVATE:
147
+                return IAccountManager::SCOPE_LOCAL;
148
+            case IAccountManager::VISIBILITY_CONTACTS_ONLY:
149
+                return IAccountManager::SCOPE_FEDERATED;
150
+            case IAccountManager::VISIBILITY_PUBLIC:
151
+                return IAccountManager::SCOPE_PUBLISHED;
152
+            default:
153
+                return $scope;
154
+        }
155
+    }
156
+
157
+    /**
158
+     * Get the verification status of a property
159
+     *
160
+     * @since 15.0.0
161
+     *
162
+     * @return string
163
+     */
164
+    public function getVerified(): string {
165
+        return $this->verified;
166
+    }
167 167
 }
Please login to merge, or discard this patch.