Completed
Push — master ( d3f2b6...e275b9 )
by Morris
61:09 queued 36:10
created
apps/provisioning_api/lib/Controller/UsersController.php 1 patch
Indentation   +835 added lines, -835 removed lines patch added patch discarded remove patch
@@ -52,839 +52,839 @@
 block discarded – undo
52 52
 
53 53
 class UsersController extends AUserData {
54 54
 
55
-	/** @var IAppManager */
56
-	private $appManager;
57
-	/** @var ILogger */
58
-	private $logger;
59
-	/** @var IFactory */
60
-	private $l10nFactory;
61
-	/** @var NewUserMailHelper */
62
-	private $newUserMailHelper;
63
-	/** @var FederatedFileSharingFactory */
64
-	private $federatedFileSharingFactory;
65
-	/** @var ISecureRandom */
66
-	private $secureRandom;
67
-
68
-	/**
69
-	 * @param string $appName
70
-	 * @param IRequest $request
71
-	 * @param IUserManager $userManager
72
-	 * @param IConfig $config
73
-	 * @param IAppManager $appManager
74
-	 * @param IGroupManager $groupManager
75
-	 * @param IUserSession $userSession
76
-	 * @param AccountManager $accountManager
77
-	 * @param ILogger $logger
78
-	 * @param IFactory $l10nFactory
79
-	 * @param NewUserMailHelper $newUserMailHelper
80
-	 * @param FederatedFileSharingFactory $federatedFileSharingFactory
81
-	 * @param ISecureRandom $secureRandom
82
-	 */
83
-	public function __construct(string $appName,
84
-								IRequest $request,
85
-								IUserManager $userManager,
86
-								IConfig $config,
87
-								IAppManager $appManager,
88
-								IGroupManager $groupManager,
89
-								IUserSession $userSession,
90
-								AccountManager $accountManager,
91
-								ILogger $logger,
92
-								IFactory $l10nFactory,
93
-								NewUserMailHelper $newUserMailHelper,
94
-								FederatedFileSharingFactory $federatedFileSharingFactory,
95
-								ISecureRandom $secureRandom) {
96
-		parent::__construct($appName,
97
-							$request,
98
-							$userManager,
99
-							$config,
100
-							$groupManager,
101
-							$userSession,
102
-							$accountManager);
103
-
104
-		$this->appManager = $appManager;
105
-		$this->logger = $logger;
106
-		$this->l10nFactory = $l10nFactory;
107
-		$this->newUserMailHelper = $newUserMailHelper;
108
-		$this->federatedFileSharingFactory = $federatedFileSharingFactory;
109
-		$this->secureRandom = $secureRandom;
110
-	}
111
-
112
-	/**
113
-	 * @NoAdminRequired
114
-	 *
115
-	 * returns a list of users
116
-	 *
117
-	 * @param string $search
118
-	 * @param int $limit
119
-	 * @param int $offset
120
-	 * @return DataResponse
121
-	 */
122
-	public function getUsers(string $search = '', $limit = null, $offset = 0): DataResponse {
123
-		$user = $this->userSession->getUser();
124
-		$users = [];
125
-
126
-		// Admin? Or SubAdmin?
127
-		$uid = $user->getUID();
128
-		$subAdminManager = $this->groupManager->getSubAdmin();
129
-		if ($this->groupManager->isAdmin($uid)){
130
-			$users = $this->userManager->search($search, $limit, $offset);
131
-		} else if ($subAdminManager->isSubAdmin($user)) {
132
-			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
133
-			foreach ($subAdminOfGroups as $key => $group) {
134
-				$subAdminOfGroups[$key] = $group->getGID();
135
-			}
136
-
137
-			$users = [];
138
-			foreach ($subAdminOfGroups as $group) {
139
-				$users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
140
-			}
141
-		}
142
-
143
-		$users = array_keys($users);
144
-
145
-		return new DataResponse([
146
-			'users' => $users
147
-		]);
148
-	}
149
-
150
-	/**
151
-	 * @NoAdminRequired
152
-	 *
153
-	 * returns a list of users and their data
154
-	 */
155
-	public function getUsersDetails(string $search = '', $limit = null, $offset = 0): DataResponse {
156
-		$user = $this->userSession->getUser();
157
-		$users = [];
158
-
159
-		// Admin? Or SubAdmin?
160
-		$uid = $user->getUID();
161
-		$subAdminManager = $this->groupManager->getSubAdmin();
162
-		if ($this->groupManager->isAdmin($uid)){
163
-			$users = $this->userManager->search($search, $limit, $offset);
164
-		} else if ($subAdminManager->isSubAdmin($user)) {
165
-			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
166
-			foreach ($subAdminOfGroups as $key => $group) {
167
-				$subAdminOfGroups[$key] = $group->getGID();
168
-			}
169
-
170
-			$users = [];
171
-			foreach ($subAdminOfGroups as $group) {
172
-				$users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
173
-			}
174
-		}
175
-
176
-		$users = array_keys($users);
177
-		$usersDetails = [];
178
-		foreach ($users as $key => $userId) {
179
-			$userData = $this->getUserData($userId);
180
-			// Do not insert empty entry
181
-			if (!empty($userData)) {
182
-				$usersDetails[$userId] = $userData;
183
-			}
184
-		}
185
-
186
-		return new DataResponse([
187
-			'users' => $usersDetails
188
-		]);
189
-	}
190
-
191
-	/**
192
-	 * @PasswordConfirmationRequired
193
-	 * @NoAdminRequired
194
-	 *
195
-	 * @param string $userid
196
-	 * @param string $password
197
-	 * @param string $email
198
-	 * @param array $groups
199
-	 * @param array $subadmins
200
-	 * @param string $quota
201
-	 * @return DataResponse
202
-	 * @throws OCSException
203
-	 */
204
-	public function addUser(string $userid,
205
-							string $password = '',
206
-							string $email = '',
207
-							array $groups = [],
208
-							array $subadmin = [],
209
-							string $quota = ''): DataResponse {
210
-		$user = $this->userSession->getUser();
211
-		$isAdmin = $this->groupManager->isAdmin($user->getUID());
212
-		$subAdminManager = $this->groupManager->getSubAdmin();
213
-
214
-		if ($this->userManager->userExists($userid)) {
215
-			$this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
216
-			throw new OCSException('User already exists', 102);
217
-		}
218
-
219
-		if ($groups !== []) {
220
-			foreach ($groups as $group) {
221
-				if (!$this->groupManager->groupExists($group)) {
222
-					throw new OCSException('group '.$group.' does not exist', 104);
223
-				}
224
-				if (!$isAdmin && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
225
-					throw new OCSException('insufficient privileges for group '. $group, 105);
226
-				}
227
-			}
228
-		} else {
229
-			if (!$isAdmin) {
230
-				throw new OCSException('no group specified (required for subadmins)', 106);
231
-			}
232
-		}
233
-
234
-		$subadminGroups = [];
235
-		if ($subadmin !== []) {
236
-			foreach ($subadmin as $groupid) {
237
-				$group = $this->groupManager->get($groupid);
238
-				// Check if group exists
239
-				if ($group === null) {
240
-					throw new OCSException('Subadmin group does not exist',  102);
241
-				}
242
-				// Check if trying to make subadmin of admin group
243
-				if ($group->getGID() === 'admin') {
244
-					throw new OCSException('Cannot create subadmins for admin group', 103);
245
-				}
246
-				// Check if has permission to promote subadmins
247
-				if (!$subAdminManager->isSubAdminOfGroup($user, $group) && !$isAdmin) {
248
-					throw new OCSForbiddenException('No permissions to promote subadmins');
249
-				}
250
-				$subadminGroups[] = $group;
251
-			}
252
-		}
253
-
254
-		$generatePasswordResetToken = false;
255
-		if ($password === '') {
256
-			if ($email === '') {
257
-				throw new OCSException('To send a password link to the user an email address is required.', 108);
258
-			}
259
-
260
-			$password = $this->secureRandom->generate(10);
261
-			// Make sure we pass the password_policy
262
-			$password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()');
263
-			$generatePasswordResetToken = true;
264
-		}
265
-
266
-		try {
267
-			$newUser = $this->userManager->createUser($userid, $password);
268
-			$this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']);
269
-
270
-			foreach ($groups as $group) {
271
-				$this->groupManager->get($group)->addUser($newUser);
272
-				$this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']);
273
-			}
274
-			foreach ($subadminGroups as $group) {
275
-				$subAdminManager->createSubAdmin($newUser, $group);
276
-			}
277
-
278
-			if ($quota !== '') {
279
-				$this->editUser($userid, 'quota', $quota);
280
-			}
281
-
282
-			// Send new user mail only if a mail is set
283
-			if ($email !== '') {
284
-				$newUser->setEMailAddress($email);
285
-				try {
286
-					$emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
287
-					$this->newUserMailHelper->sendMail($newUser, $emailTemplate);
288
-				} catch (\Exception $e) {
289
-					$this->logger->logException($e, [
290
-						'message' => "Can't send new user mail to $email",
291
-						'level' => \OCP\Util::ERROR,
292
-						'app' => 'ocs_api',
293
-					]);
294
-					throw new OCSException('Unable to send the invitation mail', 109);
295
-				}
296
-			}
297
-
298
-			return new DataResponse();
299
-
300
-		} catch (HintException $e ) {
301
-			$this->logger->logException($e, [
302
-				'message' => 'Failed addUser attempt with hint exception.',
303
-				'level' => \OCP\Util::WARN,
304
-				'app' => 'ocs_api',
305
-			]);
306
-			throw new OCSException($e->getHint(), 107);
307
-		} catch (\Exception $e) {
308
-			$this->logger->logException($e, [
309
-				'message' => 'Failed addUser attempt with exception.',
310
-				'level' => \OCP\Util::ERROR,
311
-				'app' => 'ocs_api',
312
-			]);
313
-			throw new OCSException('Bad request', 101);
314
-		}
315
-	}
316
-
317
-	/**
318
-	 * @NoAdminRequired
319
-	 * @NoSubAdminRequired
320
-	 *
321
-	 * gets user info
322
-	 *
323
-	 * @param string $userId
324
-	 * @return DataResponse
325
-	 * @throws OCSException
326
-	 */
327
-	public function getUser(string $userId): DataResponse {
328
-		$data = $this->getUserData($userId);
329
-		// getUserData returns empty array if not enough permissions
330
-		if (empty($data)) {
331
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
332
-		}
333
-		return new DataResponse($data);
334
-	}
335
-
336
-	/**
337
-	 * @NoAdminRequired
338
-	 * @NoSubAdminRequired
339
-	 *
340
-	 * gets user info from the currently logged in user
341
-	 *
342
-	 * @return DataResponse
343
-	 * @throws OCSException
344
-	 */
345
-	public function getCurrentUser(): DataResponse {
346
-		$user = $this->userSession->getUser();
347
-		if ($user) {
348
-			$data =  $this->getUserData($user->getUID());
349
-			// rename "displayname" to "display-name" only for this call to keep
350
-			// the API stable.
351
-			$data['display-name'] = $data['displayname'];
352
-			unset($data['displayname']);
353
-			return new DataResponse($data);
354
-
355
-		}
356
-
357
-		throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
358
-	}
359
-
360
-	/**
361
-	 * @NoAdminRequired
362
-	 * @NoSubAdminRequired
363
-	 */
364
-	public function getEditableFields(): DataResponse {
365
-		$permittedFields = [];
366
-
367
-		// Editing self (display, email)
368
-		if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
369
-			$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
370
-			$permittedFields[] = AccountManager::PROPERTY_EMAIL;
371
-		}
372
-
373
-		if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
374
-			$federatedFileSharing = $this->federatedFileSharingFactory->get();
375
-			$shareProvider = $federatedFileSharing->getFederatedShareProvider();
376
-			if ($shareProvider->isLookupServerUploadEnabled()) {
377
-				$permittedFields[] = AccountManager::PROPERTY_PHONE;
378
-				$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
379
-				$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
380
-				$permittedFields[] = AccountManager::PROPERTY_TWITTER;
381
-			}
382
-		}
383
-
384
-		return new DataResponse($permittedFields);
385
-	}
386
-
387
-	/**
388
-	 * @NoAdminRequired
389
-	 * @NoSubAdminRequired
390
-	 * @PasswordConfirmationRequired
391
-	 *
392
-	 * edit users
393
-	 *
394
-	 * @param string $userId
395
-	 * @param string $key
396
-	 * @param string $value
397
-	 * @return DataResponse
398
-	 * @throws OCSException
399
-	 */
400
-	public function editUser(string $userId, string $key, string $value): DataResponse {
401
-		$currentLoggedInUser = $this->userSession->getUser();
402
-
403
-		$targetUser = $this->userManager->get($userId);
404
-		if ($targetUser === null) {
405
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
406
-		}
407
-
408
-		$permittedFields = [];
409
-		if ($targetUser->getUID() === $currentLoggedInUser->getUID()) {
410
-			// Editing self (display, email)
411
-			if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
412
-				$permittedFields[] = 'display';
413
-				$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
414
-				$permittedFields[] = AccountManager::PROPERTY_EMAIL;
415
-			}
416
-
417
-			$permittedFields[] = 'password';
418
-			if ($this->config->getSystemValue('force_language', false) === false ||
419
-				$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
420
-				$permittedFields[] = 'language';
421
-			}
422
-
423
-			if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
424
-				$federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
425
-				$shareProvider = $federatedFileSharing->getFederatedShareProvider();
426
-				if ($shareProvider->isLookupServerUploadEnabled()) {
427
-					$permittedFields[] = AccountManager::PROPERTY_PHONE;
428
-					$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
429
-					$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
430
-					$permittedFields[] = AccountManager::PROPERTY_TWITTER;
431
-				}
432
-			}
433
-
434
-			// If admin they can edit their own quota
435
-			if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
436
-				$permittedFields[] = 'quota';
437
-			}
438
-		} else {
439
-			// Check if admin / subadmin
440
-			$subAdminManager = $this->groupManager->getSubAdmin();
441
-			if ($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
442
-			|| $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
443
-				// They have permissions over the user
444
-				$permittedFields[] = 'display';
445
-				$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
446
-				$permittedFields[] = AccountManager::PROPERTY_EMAIL;
447
-				$permittedFields[] = 'password';
448
-				$permittedFields[] = 'language';
449
-				$permittedFields[] = AccountManager::PROPERTY_PHONE;
450
-				$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
451
-				$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
452
-				$permittedFields[] = AccountManager::PROPERTY_TWITTER;
453
-				$permittedFields[] = 'quota';
454
-			} else {
455
-				// No rights
456
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
457
-			}
458
-		}
459
-		// Check if permitted to edit this field
460
-		if (!in_array($key, $permittedFields)) {
461
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
462
-		}
463
-		// Process the edit
464
-		switch($key) {
465
-			case 'display':
466
-			case AccountManager::PROPERTY_DISPLAYNAME:
467
-				$targetUser->setDisplayName($value);
468
-				break;
469
-			case 'quota':
470
-				$quota = $value;
471
-				if ($quota !== 'none' && $quota !== 'default') {
472
-					if (is_numeric($quota)) {
473
-						$quota = (float) $quota;
474
-					} else {
475
-						$quota = \OCP\Util::computerFileSize($quota);
476
-					}
477
-					if ($quota === false) {
478
-						throw new OCSException('Invalid quota value '.$value, 103);
479
-					}
480
-					if ($quota === 0) {
481
-						$quota = 'default';
482
-					}else if ($quota === -1) {
483
-						$quota = 'none';
484
-					} else {
485
-						$quota = \OCP\Util::humanFileSize($quota);
486
-					}
487
-				}
488
-				$targetUser->setQuota($quota);
489
-				break;
490
-			case 'password':
491
-				$targetUser->setPassword($value);
492
-				break;
493
-			case 'language':
494
-				$languagesCodes = $this->l10nFactory->findAvailableLanguages();
495
-				if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
496
-					throw new OCSException('Invalid language', 102);
497
-				}
498
-				$this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
499
-				break;
500
-			case AccountManager::PROPERTY_EMAIL:
501
-				if (filter_var($value, FILTER_VALIDATE_EMAIL) || $value === '') {
502
-					$targetUser->setEMailAddress($value);
503
-				} else {
504
-					throw new OCSException('', 102);
505
-				}
506
-				break;
507
-			case AccountManager::PROPERTY_PHONE:
508
-			case AccountManager::PROPERTY_ADDRESS:
509
-			case AccountManager::PROPERTY_WEBSITE:
510
-			case AccountManager::PROPERTY_TWITTER:
511
-				$userAccount = $this->accountManager->getUser($targetUser);
512
-				if ($userAccount[$key]['value'] !== $value) {
513
-					$userAccount[$key]['value'] = $value;
514
-					$this->accountManager->updateUser($targetUser, $userAccount);
515
-				}
516
-				break;
517
-			default:
518
-				throw new OCSException('', 103);
519
-		}
520
-		return new DataResponse();
521
-	}
522
-
523
-	/**
524
-	 * @PasswordConfirmationRequired
525
-	 * @NoAdminRequired
526
-	 *
527
-	 * @param string $userId
528
-	 * @return DataResponse
529
-	 * @throws OCSException
530
-	 */
531
-	public function deleteUser(string $userId): DataResponse {
532
-		$currentLoggedInUser = $this->userSession->getUser();
533
-
534
-		$targetUser = $this->userManager->get($userId);
535
-
536
-		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
537
-			throw new OCSException('', 101);
538
-		}
539
-
540
-		// If not permitted
541
-		$subAdminManager = $this->groupManager->getSubAdmin();
542
-		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
543
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
544
-		}
545
-
546
-		// Go ahead with the delete
547
-		if ($targetUser->delete()) {
548
-			return new DataResponse();
549
-		} else {
550
-			throw new OCSException('', 101);
551
-		}
552
-	}
553
-
554
-	/**
555
-	 * @PasswordConfirmationRequired
556
-	 * @NoAdminRequired
557
-	 *
558
-	 * @param string $userId
559
-	 * @return DataResponse
560
-	 * @throws OCSException
561
-	 * @throws OCSForbiddenException
562
-	 */
563
-	public function disableUser(string $userId): DataResponse {
564
-		return $this->setEnabled($userId, false);
565
-	}
566
-
567
-	/**
568
-	 * @PasswordConfirmationRequired
569
-	 * @NoAdminRequired
570
-	 *
571
-	 * @param string $userId
572
-	 * @return DataResponse
573
-	 * @throws OCSException
574
-	 * @throws OCSForbiddenException
575
-	 */
576
-	public function enableUser(string $userId): DataResponse {
577
-		return $this->setEnabled($userId, true);
578
-	}
579
-
580
-	/**
581
-	 * @param string $userId
582
-	 * @param bool $value
583
-	 * @return DataResponse
584
-	 * @throws OCSException
585
-	 */
586
-	private function setEnabled(string $userId, bool $value): DataResponse {
587
-		$currentLoggedInUser = $this->userSession->getUser();
588
-
589
-		$targetUser = $this->userManager->get($userId);
590
-		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
591
-			throw new OCSException('', 101);
592
-		}
593
-
594
-		// If not permitted
595
-		$subAdminManager = $this->groupManager->getSubAdmin();
596
-		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
597
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
598
-		}
599
-
600
-		// enable/disable the user now
601
-		$targetUser->setEnabled($value);
602
-		return new DataResponse();
603
-	}
604
-
605
-	/**
606
-	 * @NoAdminRequired
607
-	 * @NoSubAdminRequired
608
-	 *
609
-	 * @param string $userId
610
-	 * @return DataResponse
611
-	 * @throws OCSException
612
-	 */
613
-	public function getUsersGroups(string $userId): DataResponse {
614
-		$loggedInUser = $this->userSession->getUser();
615
-
616
-		$targetUser = $this->userManager->get($userId);
617
-		if ($targetUser === null) {
618
-			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
619
-		}
620
-
621
-		if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
622
-			// Self lookup or admin lookup
623
-			return new DataResponse([
624
-				'groups' => $this->groupManager->getUserGroupIds($targetUser)
625
-			]);
626
-		} else {
627
-			$subAdminManager = $this->groupManager->getSubAdmin();
628
-
629
-			// Looking up someone else
630
-			if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
631
-				// Return the group that the method caller is subadmin of for the user in question
632
-				/** @var IGroup[] $getSubAdminsGroups */
633
-				$getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
634
-				foreach ($getSubAdminsGroups as $key => $group) {
635
-					$getSubAdminsGroups[$key] = $group->getGID();
636
-				}
637
-				$groups = array_intersect(
638
-					$getSubAdminsGroups,
639
-					$this->groupManager->getUserGroupIds($targetUser)
640
-				);
641
-				return new DataResponse(['groups' => $groups]);
642
-			} else {
643
-				// Not permitted
644
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
645
-			}
646
-		}
647
-
648
-	}
649
-
650
-	/**
651
-	 * @PasswordConfirmationRequired
652
-	 * @NoAdminRequired
653
-	 *
654
-	 * @param string $userId
655
-	 * @param string $groupid
656
-	 * @return DataResponse
657
-	 * @throws OCSException
658
-	 */
659
-	public function addToGroup(string $userId, string $groupid = ''): DataResponse {
660
-		if ($groupid === '') {
661
-			throw new OCSException('', 101);
662
-		}
663
-
664
-		$group = $this->groupManager->get($groupid);
665
-		$targetUser = $this->userManager->get($userId);
666
-		if ($group === null) {
667
-			throw new OCSException('', 102);
668
-		}
669
-		if ($targetUser === null) {
670
-			throw new OCSException('', 103);
671
-		}
672
-
673
-		// If they're not an admin, check they are a subadmin of the group in question
674
-		$loggedInUser = $this->userSession->getUser();
675
-		$subAdminManager = $this->groupManager->getSubAdmin();
676
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
677
-			throw new OCSException('', 104);
678
-		}
679
-
680
-		// Add user to group
681
-		$group->addUser($targetUser);
682
-		return new DataResponse();
683
-	}
684
-
685
-	/**
686
-	 * @PasswordConfirmationRequired
687
-	 * @NoAdminRequired
688
-	 *
689
-	 * @param string $userId
690
-	 * @param string $groupid
691
-	 * @return DataResponse
692
-	 * @throws OCSException
693
-	 */
694
-	public function removeFromGroup(string $userId, string $groupid): DataResponse {
695
-		$loggedInUser = $this->userSession->getUser();
696
-
697
-		if ($groupid === null || trim($groupid) === '') {
698
-			throw new OCSException('', 101);
699
-		}
700
-
701
-		$group = $this->groupManager->get($groupid);
702
-		if ($group === null) {
703
-			throw new OCSException('', 102);
704
-		}
705
-
706
-		$targetUser = $this->userManager->get($userId);
707
-		if ($targetUser === null) {
708
-			throw new OCSException('', 103);
709
-		}
710
-
711
-		// If they're not an admin, check they are a subadmin of the group in question
712
-		$subAdminManager = $this->groupManager->getSubAdmin();
713
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
714
-			throw new OCSException('', 104);
715
-		}
716
-
717
-		// Check they aren't removing themselves from 'admin' or their 'subadmin; group
718
-		if ($targetUser->getUID() === $loggedInUser->getUID()) {
719
-			if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
720
-				if ($group->getGID() === 'admin') {
721
-					throw new OCSException('Cannot remove yourself from the admin group', 105);
722
-				}
723
-			} else {
724
-				// Not an admin, so the user must be a subadmin of this group, but that is not allowed.
725
-				throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
726
-			}
727
-
728
-		} else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
729
-			/** @var IGroup[] $subAdminGroups */
730
-			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
731
-			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
732
-				return $subAdminGroup->getGID();
733
-			}, $subAdminGroups);
734
-			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
735
-			$userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
736
-
737
-			if (count($userSubAdminGroups) <= 1) {
738
-				// Subadmin must not be able to remove a user from all their subadmin groups.
739
-				throw new OCSException('Cannot remove user from this group as this is the only remaining group you are a SubAdmin of', 105);
740
-			}
741
-		}
742
-
743
-		// Remove user from group
744
-		$group->removeUser($targetUser);
745
-		return new DataResponse();
746
-	}
747
-
748
-	/**
749
-	 * Creates a subadmin
750
-	 *
751
-	 * @PasswordConfirmationRequired
752
-	 *
753
-	 * @param string $userId
754
-	 * @param string $groupid
755
-	 * @return DataResponse
756
-	 * @throws OCSException
757
-	 */
758
-	public function addSubAdmin(string $userId, string $groupid): DataResponse {
759
-		$group = $this->groupManager->get($groupid);
760
-		$user = $this->userManager->get($userId);
761
-
762
-		// Check if the user exists
763
-		if ($user === null) {
764
-			throw new OCSException('User does not exist', 101);
765
-		}
766
-		// Check if group exists
767
-		if ($group === null) {
768
-			throw new OCSException('Group does not exist',  102);
769
-		}
770
-		// Check if trying to make subadmin of admin group
771
-		if ($group->getGID() === 'admin') {
772
-			throw new OCSException('Cannot create subadmins for admin group', 103);
773
-		}
774
-
775
-		$subAdminManager = $this->groupManager->getSubAdmin();
776
-
777
-		// We cannot be subadmin twice
778
-		if ($subAdminManager->isSubAdminOfGroup($user, $group)) {
779
-			return new DataResponse();
780
-		}
781
-		// Go
782
-		if ($subAdminManager->createSubAdmin($user, $group)) {
783
-			return new DataResponse();
784
-		} else {
785
-			throw new OCSException('Unknown error occurred', 103);
786
-		}
787
-	}
788
-
789
-	/**
790
-	 * Removes a subadmin from a group
791
-	 *
792
-	 * @PasswordConfirmationRequired
793
-	 *
794
-	 * @param string $userId
795
-	 * @param string $groupid
796
-	 * @return DataResponse
797
-	 * @throws OCSException
798
-	 */
799
-	public function removeSubAdmin(string $userId, string $groupid): DataResponse {
800
-		$group = $this->groupManager->get($groupid);
801
-		$user = $this->userManager->get($userId);
802
-		$subAdminManager = $this->groupManager->getSubAdmin();
803
-
804
-		// Check if the user exists
805
-		if ($user === null) {
806
-			throw new OCSException('User does not exist', 101);
807
-		}
808
-		// Check if the group exists
809
-		if ($group === null) {
810
-			throw new OCSException('Group does not exist', 101);
811
-		}
812
-		// Check if they are a subadmin of this said group
813
-		if (!$subAdminManager->isSubAdminOfGroup($user, $group)) {
814
-			throw new OCSException('User is not a subadmin of this group', 102);
815
-		}
816
-
817
-		// Go
818
-		if ($subAdminManager->deleteSubAdmin($user, $group)) {
819
-			return new DataResponse();
820
-		} else {
821
-			throw new OCSException('Unknown error occurred', 103);
822
-		}
823
-	}
824
-
825
-	/**
826
-	 * Get the groups a user is a subadmin of
827
-	 *
828
-	 * @param string $userId
829
-	 * @return DataResponse
830
-	 * @throws OCSException
831
-	 */
832
-	public function getUserSubAdminGroups(string $userId): DataResponse {
833
-		$groups = $this->getUserSubAdminGroupsData($userId);
834
-		return new DataResponse($groups);
835
-	}
836
-
837
-	/**
838
-	 * @NoAdminRequired
839
-	 * @PasswordConfirmationRequired
840
-	 *
841
-	 * resend welcome message
842
-	 *
843
-	 * @param string $userId
844
-	 * @return DataResponse
845
-	 * @throws OCSException
846
-	 */
847
-	public function resendWelcomeMessage(string $userId): DataResponse {
848
-		$currentLoggedInUser = $this->userSession->getUser();
849
-
850
-		$targetUser = $this->userManager->get($userId);
851
-		if ($targetUser === null) {
852
-			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
853
-		}
854
-
855
-		// Check if admin / subadmin
856
-		$subAdminManager = $this->groupManager->getSubAdmin();
857
-		if (!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
858
-			&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
859
-			// No rights
860
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
861
-		}
862
-
863
-		$email = $targetUser->getEMailAddress();
864
-		if ($email === '' || $email === null) {
865
-			throw new OCSException('Email address not available', 101);
866
-		}
867
-		$username = $targetUser->getUID();
868
-		$lang = $this->config->getUserValue($username, 'core', 'lang', 'en');
869
-		if (!$this->l10nFactory->languageExists('settings', $lang)) {
870
-			$lang = 'en';
871
-		}
872
-
873
-		$l10n = $this->l10nFactory->get('settings', $lang);
874
-
875
-		try {
876
-			$this->newUserMailHelper->setL10N($l10n);
877
-			$emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
878
-			$this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
879
-		} catch(\Exception $e) {
880
-			$this->logger->logException($e, [
881
-				'message' => "Can't send new user mail to $email",
882
-				'level' => \OCP\Util::ERROR,
883
-				'app' => 'settings',
884
-			]);
885
-			throw new OCSException('Sending email failed', 102);
886
-		}
887
-
888
-		return new DataResponse();
889
-	}
55
+    /** @var IAppManager */
56
+    private $appManager;
57
+    /** @var ILogger */
58
+    private $logger;
59
+    /** @var IFactory */
60
+    private $l10nFactory;
61
+    /** @var NewUserMailHelper */
62
+    private $newUserMailHelper;
63
+    /** @var FederatedFileSharingFactory */
64
+    private $federatedFileSharingFactory;
65
+    /** @var ISecureRandom */
66
+    private $secureRandom;
67
+
68
+    /**
69
+     * @param string $appName
70
+     * @param IRequest $request
71
+     * @param IUserManager $userManager
72
+     * @param IConfig $config
73
+     * @param IAppManager $appManager
74
+     * @param IGroupManager $groupManager
75
+     * @param IUserSession $userSession
76
+     * @param AccountManager $accountManager
77
+     * @param ILogger $logger
78
+     * @param IFactory $l10nFactory
79
+     * @param NewUserMailHelper $newUserMailHelper
80
+     * @param FederatedFileSharingFactory $federatedFileSharingFactory
81
+     * @param ISecureRandom $secureRandom
82
+     */
83
+    public function __construct(string $appName,
84
+                                IRequest $request,
85
+                                IUserManager $userManager,
86
+                                IConfig $config,
87
+                                IAppManager $appManager,
88
+                                IGroupManager $groupManager,
89
+                                IUserSession $userSession,
90
+                                AccountManager $accountManager,
91
+                                ILogger $logger,
92
+                                IFactory $l10nFactory,
93
+                                NewUserMailHelper $newUserMailHelper,
94
+                                FederatedFileSharingFactory $federatedFileSharingFactory,
95
+                                ISecureRandom $secureRandom) {
96
+        parent::__construct($appName,
97
+                            $request,
98
+                            $userManager,
99
+                            $config,
100
+                            $groupManager,
101
+                            $userSession,
102
+                            $accountManager);
103
+
104
+        $this->appManager = $appManager;
105
+        $this->logger = $logger;
106
+        $this->l10nFactory = $l10nFactory;
107
+        $this->newUserMailHelper = $newUserMailHelper;
108
+        $this->federatedFileSharingFactory = $federatedFileSharingFactory;
109
+        $this->secureRandom = $secureRandom;
110
+    }
111
+
112
+    /**
113
+     * @NoAdminRequired
114
+     *
115
+     * returns a list of users
116
+     *
117
+     * @param string $search
118
+     * @param int $limit
119
+     * @param int $offset
120
+     * @return DataResponse
121
+     */
122
+    public function getUsers(string $search = '', $limit = null, $offset = 0): DataResponse {
123
+        $user = $this->userSession->getUser();
124
+        $users = [];
125
+
126
+        // Admin? Or SubAdmin?
127
+        $uid = $user->getUID();
128
+        $subAdminManager = $this->groupManager->getSubAdmin();
129
+        if ($this->groupManager->isAdmin($uid)){
130
+            $users = $this->userManager->search($search, $limit, $offset);
131
+        } else if ($subAdminManager->isSubAdmin($user)) {
132
+            $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
133
+            foreach ($subAdminOfGroups as $key => $group) {
134
+                $subAdminOfGroups[$key] = $group->getGID();
135
+            }
136
+
137
+            $users = [];
138
+            foreach ($subAdminOfGroups as $group) {
139
+                $users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
140
+            }
141
+        }
142
+
143
+        $users = array_keys($users);
144
+
145
+        return new DataResponse([
146
+            'users' => $users
147
+        ]);
148
+    }
149
+
150
+    /**
151
+     * @NoAdminRequired
152
+     *
153
+     * returns a list of users and their data
154
+     */
155
+    public function getUsersDetails(string $search = '', $limit = null, $offset = 0): DataResponse {
156
+        $user = $this->userSession->getUser();
157
+        $users = [];
158
+
159
+        // Admin? Or SubAdmin?
160
+        $uid = $user->getUID();
161
+        $subAdminManager = $this->groupManager->getSubAdmin();
162
+        if ($this->groupManager->isAdmin($uid)){
163
+            $users = $this->userManager->search($search, $limit, $offset);
164
+        } else if ($subAdminManager->isSubAdmin($user)) {
165
+            $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
166
+            foreach ($subAdminOfGroups as $key => $group) {
167
+                $subAdminOfGroups[$key] = $group->getGID();
168
+            }
169
+
170
+            $users = [];
171
+            foreach ($subAdminOfGroups as $group) {
172
+                $users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
173
+            }
174
+        }
175
+
176
+        $users = array_keys($users);
177
+        $usersDetails = [];
178
+        foreach ($users as $key => $userId) {
179
+            $userData = $this->getUserData($userId);
180
+            // Do not insert empty entry
181
+            if (!empty($userData)) {
182
+                $usersDetails[$userId] = $userData;
183
+            }
184
+        }
185
+
186
+        return new DataResponse([
187
+            'users' => $usersDetails
188
+        ]);
189
+    }
190
+
191
+    /**
192
+     * @PasswordConfirmationRequired
193
+     * @NoAdminRequired
194
+     *
195
+     * @param string $userid
196
+     * @param string $password
197
+     * @param string $email
198
+     * @param array $groups
199
+     * @param array $subadmins
200
+     * @param string $quota
201
+     * @return DataResponse
202
+     * @throws OCSException
203
+     */
204
+    public function addUser(string $userid,
205
+                            string $password = '',
206
+                            string $email = '',
207
+                            array $groups = [],
208
+                            array $subadmin = [],
209
+                            string $quota = ''): DataResponse {
210
+        $user = $this->userSession->getUser();
211
+        $isAdmin = $this->groupManager->isAdmin($user->getUID());
212
+        $subAdminManager = $this->groupManager->getSubAdmin();
213
+
214
+        if ($this->userManager->userExists($userid)) {
215
+            $this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
216
+            throw new OCSException('User already exists', 102);
217
+        }
218
+
219
+        if ($groups !== []) {
220
+            foreach ($groups as $group) {
221
+                if (!$this->groupManager->groupExists($group)) {
222
+                    throw new OCSException('group '.$group.' does not exist', 104);
223
+                }
224
+                if (!$isAdmin && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
225
+                    throw new OCSException('insufficient privileges for group '. $group, 105);
226
+                }
227
+            }
228
+        } else {
229
+            if (!$isAdmin) {
230
+                throw new OCSException('no group specified (required for subadmins)', 106);
231
+            }
232
+        }
233
+
234
+        $subadminGroups = [];
235
+        if ($subadmin !== []) {
236
+            foreach ($subadmin as $groupid) {
237
+                $group = $this->groupManager->get($groupid);
238
+                // Check if group exists
239
+                if ($group === null) {
240
+                    throw new OCSException('Subadmin group does not exist',  102);
241
+                }
242
+                // Check if trying to make subadmin of admin group
243
+                if ($group->getGID() === 'admin') {
244
+                    throw new OCSException('Cannot create subadmins for admin group', 103);
245
+                }
246
+                // Check if has permission to promote subadmins
247
+                if (!$subAdminManager->isSubAdminOfGroup($user, $group) && !$isAdmin) {
248
+                    throw new OCSForbiddenException('No permissions to promote subadmins');
249
+                }
250
+                $subadminGroups[] = $group;
251
+            }
252
+        }
253
+
254
+        $generatePasswordResetToken = false;
255
+        if ($password === '') {
256
+            if ($email === '') {
257
+                throw new OCSException('To send a password link to the user an email address is required.', 108);
258
+            }
259
+
260
+            $password = $this->secureRandom->generate(10);
261
+            // Make sure we pass the password_policy
262
+            $password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()');
263
+            $generatePasswordResetToken = true;
264
+        }
265
+
266
+        try {
267
+            $newUser = $this->userManager->createUser($userid, $password);
268
+            $this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']);
269
+
270
+            foreach ($groups as $group) {
271
+                $this->groupManager->get($group)->addUser($newUser);
272
+                $this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']);
273
+            }
274
+            foreach ($subadminGroups as $group) {
275
+                $subAdminManager->createSubAdmin($newUser, $group);
276
+            }
277
+
278
+            if ($quota !== '') {
279
+                $this->editUser($userid, 'quota', $quota);
280
+            }
281
+
282
+            // Send new user mail only if a mail is set
283
+            if ($email !== '') {
284
+                $newUser->setEMailAddress($email);
285
+                try {
286
+                    $emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
287
+                    $this->newUserMailHelper->sendMail($newUser, $emailTemplate);
288
+                } catch (\Exception $e) {
289
+                    $this->logger->logException($e, [
290
+                        'message' => "Can't send new user mail to $email",
291
+                        'level' => \OCP\Util::ERROR,
292
+                        'app' => 'ocs_api',
293
+                    ]);
294
+                    throw new OCSException('Unable to send the invitation mail', 109);
295
+                }
296
+            }
297
+
298
+            return new DataResponse();
299
+
300
+        } catch (HintException $e ) {
301
+            $this->logger->logException($e, [
302
+                'message' => 'Failed addUser attempt with hint exception.',
303
+                'level' => \OCP\Util::WARN,
304
+                'app' => 'ocs_api',
305
+            ]);
306
+            throw new OCSException($e->getHint(), 107);
307
+        } catch (\Exception $e) {
308
+            $this->logger->logException($e, [
309
+                'message' => 'Failed addUser attempt with exception.',
310
+                'level' => \OCP\Util::ERROR,
311
+                'app' => 'ocs_api',
312
+            ]);
313
+            throw new OCSException('Bad request', 101);
314
+        }
315
+    }
316
+
317
+    /**
318
+     * @NoAdminRequired
319
+     * @NoSubAdminRequired
320
+     *
321
+     * gets user info
322
+     *
323
+     * @param string $userId
324
+     * @return DataResponse
325
+     * @throws OCSException
326
+     */
327
+    public function getUser(string $userId): DataResponse {
328
+        $data = $this->getUserData($userId);
329
+        // getUserData returns empty array if not enough permissions
330
+        if (empty($data)) {
331
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
332
+        }
333
+        return new DataResponse($data);
334
+    }
335
+
336
+    /**
337
+     * @NoAdminRequired
338
+     * @NoSubAdminRequired
339
+     *
340
+     * gets user info from the currently logged in user
341
+     *
342
+     * @return DataResponse
343
+     * @throws OCSException
344
+     */
345
+    public function getCurrentUser(): DataResponse {
346
+        $user = $this->userSession->getUser();
347
+        if ($user) {
348
+            $data =  $this->getUserData($user->getUID());
349
+            // rename "displayname" to "display-name" only for this call to keep
350
+            // the API stable.
351
+            $data['display-name'] = $data['displayname'];
352
+            unset($data['displayname']);
353
+            return new DataResponse($data);
354
+
355
+        }
356
+
357
+        throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
358
+    }
359
+
360
+    /**
361
+     * @NoAdminRequired
362
+     * @NoSubAdminRequired
363
+     */
364
+    public function getEditableFields(): DataResponse {
365
+        $permittedFields = [];
366
+
367
+        // Editing self (display, email)
368
+        if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
369
+            $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
370
+            $permittedFields[] = AccountManager::PROPERTY_EMAIL;
371
+        }
372
+
373
+        if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
374
+            $federatedFileSharing = $this->federatedFileSharingFactory->get();
375
+            $shareProvider = $federatedFileSharing->getFederatedShareProvider();
376
+            if ($shareProvider->isLookupServerUploadEnabled()) {
377
+                $permittedFields[] = AccountManager::PROPERTY_PHONE;
378
+                $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
379
+                $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
380
+                $permittedFields[] = AccountManager::PROPERTY_TWITTER;
381
+            }
382
+        }
383
+
384
+        return new DataResponse($permittedFields);
385
+    }
386
+
387
+    /**
388
+     * @NoAdminRequired
389
+     * @NoSubAdminRequired
390
+     * @PasswordConfirmationRequired
391
+     *
392
+     * edit users
393
+     *
394
+     * @param string $userId
395
+     * @param string $key
396
+     * @param string $value
397
+     * @return DataResponse
398
+     * @throws OCSException
399
+     */
400
+    public function editUser(string $userId, string $key, string $value): DataResponse {
401
+        $currentLoggedInUser = $this->userSession->getUser();
402
+
403
+        $targetUser = $this->userManager->get($userId);
404
+        if ($targetUser === null) {
405
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
406
+        }
407
+
408
+        $permittedFields = [];
409
+        if ($targetUser->getUID() === $currentLoggedInUser->getUID()) {
410
+            // Editing self (display, email)
411
+            if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
412
+                $permittedFields[] = 'display';
413
+                $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
414
+                $permittedFields[] = AccountManager::PROPERTY_EMAIL;
415
+            }
416
+
417
+            $permittedFields[] = 'password';
418
+            if ($this->config->getSystemValue('force_language', false) === false ||
419
+                $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
420
+                $permittedFields[] = 'language';
421
+            }
422
+
423
+            if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
424
+                $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
425
+                $shareProvider = $federatedFileSharing->getFederatedShareProvider();
426
+                if ($shareProvider->isLookupServerUploadEnabled()) {
427
+                    $permittedFields[] = AccountManager::PROPERTY_PHONE;
428
+                    $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
429
+                    $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
430
+                    $permittedFields[] = AccountManager::PROPERTY_TWITTER;
431
+                }
432
+            }
433
+
434
+            // If admin they can edit their own quota
435
+            if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
436
+                $permittedFields[] = 'quota';
437
+            }
438
+        } else {
439
+            // Check if admin / subadmin
440
+            $subAdminManager = $this->groupManager->getSubAdmin();
441
+            if ($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
442
+            || $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
443
+                // They have permissions over the user
444
+                $permittedFields[] = 'display';
445
+                $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
446
+                $permittedFields[] = AccountManager::PROPERTY_EMAIL;
447
+                $permittedFields[] = 'password';
448
+                $permittedFields[] = 'language';
449
+                $permittedFields[] = AccountManager::PROPERTY_PHONE;
450
+                $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
451
+                $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
452
+                $permittedFields[] = AccountManager::PROPERTY_TWITTER;
453
+                $permittedFields[] = 'quota';
454
+            } else {
455
+                // No rights
456
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
457
+            }
458
+        }
459
+        // Check if permitted to edit this field
460
+        if (!in_array($key, $permittedFields)) {
461
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
462
+        }
463
+        // Process the edit
464
+        switch($key) {
465
+            case 'display':
466
+            case AccountManager::PROPERTY_DISPLAYNAME:
467
+                $targetUser->setDisplayName($value);
468
+                break;
469
+            case 'quota':
470
+                $quota = $value;
471
+                if ($quota !== 'none' && $quota !== 'default') {
472
+                    if (is_numeric($quota)) {
473
+                        $quota = (float) $quota;
474
+                    } else {
475
+                        $quota = \OCP\Util::computerFileSize($quota);
476
+                    }
477
+                    if ($quota === false) {
478
+                        throw new OCSException('Invalid quota value '.$value, 103);
479
+                    }
480
+                    if ($quota === 0) {
481
+                        $quota = 'default';
482
+                    }else if ($quota === -1) {
483
+                        $quota = 'none';
484
+                    } else {
485
+                        $quota = \OCP\Util::humanFileSize($quota);
486
+                    }
487
+                }
488
+                $targetUser->setQuota($quota);
489
+                break;
490
+            case 'password':
491
+                $targetUser->setPassword($value);
492
+                break;
493
+            case 'language':
494
+                $languagesCodes = $this->l10nFactory->findAvailableLanguages();
495
+                if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
496
+                    throw new OCSException('Invalid language', 102);
497
+                }
498
+                $this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
499
+                break;
500
+            case AccountManager::PROPERTY_EMAIL:
501
+                if (filter_var($value, FILTER_VALIDATE_EMAIL) || $value === '') {
502
+                    $targetUser->setEMailAddress($value);
503
+                } else {
504
+                    throw new OCSException('', 102);
505
+                }
506
+                break;
507
+            case AccountManager::PROPERTY_PHONE:
508
+            case AccountManager::PROPERTY_ADDRESS:
509
+            case AccountManager::PROPERTY_WEBSITE:
510
+            case AccountManager::PROPERTY_TWITTER:
511
+                $userAccount = $this->accountManager->getUser($targetUser);
512
+                if ($userAccount[$key]['value'] !== $value) {
513
+                    $userAccount[$key]['value'] = $value;
514
+                    $this->accountManager->updateUser($targetUser, $userAccount);
515
+                }
516
+                break;
517
+            default:
518
+                throw new OCSException('', 103);
519
+        }
520
+        return new DataResponse();
521
+    }
522
+
523
+    /**
524
+     * @PasswordConfirmationRequired
525
+     * @NoAdminRequired
526
+     *
527
+     * @param string $userId
528
+     * @return DataResponse
529
+     * @throws OCSException
530
+     */
531
+    public function deleteUser(string $userId): DataResponse {
532
+        $currentLoggedInUser = $this->userSession->getUser();
533
+
534
+        $targetUser = $this->userManager->get($userId);
535
+
536
+        if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
537
+            throw new OCSException('', 101);
538
+        }
539
+
540
+        // If not permitted
541
+        $subAdminManager = $this->groupManager->getSubAdmin();
542
+        if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
543
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
544
+        }
545
+
546
+        // Go ahead with the delete
547
+        if ($targetUser->delete()) {
548
+            return new DataResponse();
549
+        } else {
550
+            throw new OCSException('', 101);
551
+        }
552
+    }
553
+
554
+    /**
555
+     * @PasswordConfirmationRequired
556
+     * @NoAdminRequired
557
+     *
558
+     * @param string $userId
559
+     * @return DataResponse
560
+     * @throws OCSException
561
+     * @throws OCSForbiddenException
562
+     */
563
+    public function disableUser(string $userId): DataResponse {
564
+        return $this->setEnabled($userId, false);
565
+    }
566
+
567
+    /**
568
+     * @PasswordConfirmationRequired
569
+     * @NoAdminRequired
570
+     *
571
+     * @param string $userId
572
+     * @return DataResponse
573
+     * @throws OCSException
574
+     * @throws OCSForbiddenException
575
+     */
576
+    public function enableUser(string $userId): DataResponse {
577
+        return $this->setEnabled($userId, true);
578
+    }
579
+
580
+    /**
581
+     * @param string $userId
582
+     * @param bool $value
583
+     * @return DataResponse
584
+     * @throws OCSException
585
+     */
586
+    private function setEnabled(string $userId, bool $value): DataResponse {
587
+        $currentLoggedInUser = $this->userSession->getUser();
588
+
589
+        $targetUser = $this->userManager->get($userId);
590
+        if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
591
+            throw new OCSException('', 101);
592
+        }
593
+
594
+        // If not permitted
595
+        $subAdminManager = $this->groupManager->getSubAdmin();
596
+        if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
597
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
598
+        }
599
+
600
+        // enable/disable the user now
601
+        $targetUser->setEnabled($value);
602
+        return new DataResponse();
603
+    }
604
+
605
+    /**
606
+     * @NoAdminRequired
607
+     * @NoSubAdminRequired
608
+     *
609
+     * @param string $userId
610
+     * @return DataResponse
611
+     * @throws OCSException
612
+     */
613
+    public function getUsersGroups(string $userId): DataResponse {
614
+        $loggedInUser = $this->userSession->getUser();
615
+
616
+        $targetUser = $this->userManager->get($userId);
617
+        if ($targetUser === null) {
618
+            throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
619
+        }
620
+
621
+        if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
622
+            // Self lookup or admin lookup
623
+            return new DataResponse([
624
+                'groups' => $this->groupManager->getUserGroupIds($targetUser)
625
+            ]);
626
+        } else {
627
+            $subAdminManager = $this->groupManager->getSubAdmin();
628
+
629
+            // Looking up someone else
630
+            if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
631
+                // Return the group that the method caller is subadmin of for the user in question
632
+                /** @var IGroup[] $getSubAdminsGroups */
633
+                $getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
634
+                foreach ($getSubAdminsGroups as $key => $group) {
635
+                    $getSubAdminsGroups[$key] = $group->getGID();
636
+                }
637
+                $groups = array_intersect(
638
+                    $getSubAdminsGroups,
639
+                    $this->groupManager->getUserGroupIds($targetUser)
640
+                );
641
+                return new DataResponse(['groups' => $groups]);
642
+            } else {
643
+                // Not permitted
644
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
645
+            }
646
+        }
647
+
648
+    }
649
+
650
+    /**
651
+     * @PasswordConfirmationRequired
652
+     * @NoAdminRequired
653
+     *
654
+     * @param string $userId
655
+     * @param string $groupid
656
+     * @return DataResponse
657
+     * @throws OCSException
658
+     */
659
+    public function addToGroup(string $userId, string $groupid = ''): DataResponse {
660
+        if ($groupid === '') {
661
+            throw new OCSException('', 101);
662
+        }
663
+
664
+        $group = $this->groupManager->get($groupid);
665
+        $targetUser = $this->userManager->get($userId);
666
+        if ($group === null) {
667
+            throw new OCSException('', 102);
668
+        }
669
+        if ($targetUser === null) {
670
+            throw new OCSException('', 103);
671
+        }
672
+
673
+        // If they're not an admin, check they are a subadmin of the group in question
674
+        $loggedInUser = $this->userSession->getUser();
675
+        $subAdminManager = $this->groupManager->getSubAdmin();
676
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
677
+            throw new OCSException('', 104);
678
+        }
679
+
680
+        // Add user to group
681
+        $group->addUser($targetUser);
682
+        return new DataResponse();
683
+    }
684
+
685
+    /**
686
+     * @PasswordConfirmationRequired
687
+     * @NoAdminRequired
688
+     *
689
+     * @param string $userId
690
+     * @param string $groupid
691
+     * @return DataResponse
692
+     * @throws OCSException
693
+     */
694
+    public function removeFromGroup(string $userId, string $groupid): DataResponse {
695
+        $loggedInUser = $this->userSession->getUser();
696
+
697
+        if ($groupid === null || trim($groupid) === '') {
698
+            throw new OCSException('', 101);
699
+        }
700
+
701
+        $group = $this->groupManager->get($groupid);
702
+        if ($group === null) {
703
+            throw new OCSException('', 102);
704
+        }
705
+
706
+        $targetUser = $this->userManager->get($userId);
707
+        if ($targetUser === null) {
708
+            throw new OCSException('', 103);
709
+        }
710
+
711
+        // If they're not an admin, check they are a subadmin of the group in question
712
+        $subAdminManager = $this->groupManager->getSubAdmin();
713
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
714
+            throw new OCSException('', 104);
715
+        }
716
+
717
+        // Check they aren't removing themselves from 'admin' or their 'subadmin; group
718
+        if ($targetUser->getUID() === $loggedInUser->getUID()) {
719
+            if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
720
+                if ($group->getGID() === 'admin') {
721
+                    throw new OCSException('Cannot remove yourself from the admin group', 105);
722
+                }
723
+            } else {
724
+                // Not an admin, so the user must be a subadmin of this group, but that is not allowed.
725
+                throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
726
+            }
727
+
728
+        } else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
729
+            /** @var IGroup[] $subAdminGroups */
730
+            $subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
731
+            $subAdminGroups = array_map(function (IGroup $subAdminGroup) {
732
+                return $subAdminGroup->getGID();
733
+            }, $subAdminGroups);
734
+            $userGroups = $this->groupManager->getUserGroupIds($targetUser);
735
+            $userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
736
+
737
+            if (count($userSubAdminGroups) <= 1) {
738
+                // Subadmin must not be able to remove a user from all their subadmin groups.
739
+                throw new OCSException('Cannot remove user from this group as this is the only remaining group you are a SubAdmin of', 105);
740
+            }
741
+        }
742
+
743
+        // Remove user from group
744
+        $group->removeUser($targetUser);
745
+        return new DataResponse();
746
+    }
747
+
748
+    /**
749
+     * Creates a subadmin
750
+     *
751
+     * @PasswordConfirmationRequired
752
+     *
753
+     * @param string $userId
754
+     * @param string $groupid
755
+     * @return DataResponse
756
+     * @throws OCSException
757
+     */
758
+    public function addSubAdmin(string $userId, string $groupid): DataResponse {
759
+        $group = $this->groupManager->get($groupid);
760
+        $user = $this->userManager->get($userId);
761
+
762
+        // Check if the user exists
763
+        if ($user === null) {
764
+            throw new OCSException('User does not exist', 101);
765
+        }
766
+        // Check if group exists
767
+        if ($group === null) {
768
+            throw new OCSException('Group does not exist',  102);
769
+        }
770
+        // Check if trying to make subadmin of admin group
771
+        if ($group->getGID() === 'admin') {
772
+            throw new OCSException('Cannot create subadmins for admin group', 103);
773
+        }
774
+
775
+        $subAdminManager = $this->groupManager->getSubAdmin();
776
+
777
+        // We cannot be subadmin twice
778
+        if ($subAdminManager->isSubAdminOfGroup($user, $group)) {
779
+            return new DataResponse();
780
+        }
781
+        // Go
782
+        if ($subAdminManager->createSubAdmin($user, $group)) {
783
+            return new DataResponse();
784
+        } else {
785
+            throw new OCSException('Unknown error occurred', 103);
786
+        }
787
+    }
788
+
789
+    /**
790
+     * Removes a subadmin from a group
791
+     *
792
+     * @PasswordConfirmationRequired
793
+     *
794
+     * @param string $userId
795
+     * @param string $groupid
796
+     * @return DataResponse
797
+     * @throws OCSException
798
+     */
799
+    public function removeSubAdmin(string $userId, string $groupid): DataResponse {
800
+        $group = $this->groupManager->get($groupid);
801
+        $user = $this->userManager->get($userId);
802
+        $subAdminManager = $this->groupManager->getSubAdmin();
803
+
804
+        // Check if the user exists
805
+        if ($user === null) {
806
+            throw new OCSException('User does not exist', 101);
807
+        }
808
+        // Check if the group exists
809
+        if ($group === null) {
810
+            throw new OCSException('Group does not exist', 101);
811
+        }
812
+        // Check if they are a subadmin of this said group
813
+        if (!$subAdminManager->isSubAdminOfGroup($user, $group)) {
814
+            throw new OCSException('User is not a subadmin of this group', 102);
815
+        }
816
+
817
+        // Go
818
+        if ($subAdminManager->deleteSubAdmin($user, $group)) {
819
+            return new DataResponse();
820
+        } else {
821
+            throw new OCSException('Unknown error occurred', 103);
822
+        }
823
+    }
824
+
825
+    /**
826
+     * Get the groups a user is a subadmin of
827
+     *
828
+     * @param string $userId
829
+     * @return DataResponse
830
+     * @throws OCSException
831
+     */
832
+    public function getUserSubAdminGroups(string $userId): DataResponse {
833
+        $groups = $this->getUserSubAdminGroupsData($userId);
834
+        return new DataResponse($groups);
835
+    }
836
+
837
+    /**
838
+     * @NoAdminRequired
839
+     * @PasswordConfirmationRequired
840
+     *
841
+     * resend welcome message
842
+     *
843
+     * @param string $userId
844
+     * @return DataResponse
845
+     * @throws OCSException
846
+     */
847
+    public function resendWelcomeMessage(string $userId): DataResponse {
848
+        $currentLoggedInUser = $this->userSession->getUser();
849
+
850
+        $targetUser = $this->userManager->get($userId);
851
+        if ($targetUser === null) {
852
+            throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
853
+        }
854
+
855
+        // Check if admin / subadmin
856
+        $subAdminManager = $this->groupManager->getSubAdmin();
857
+        if (!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
858
+            && !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
859
+            // No rights
860
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
861
+        }
862
+
863
+        $email = $targetUser->getEMailAddress();
864
+        if ($email === '' || $email === null) {
865
+            throw new OCSException('Email address not available', 101);
866
+        }
867
+        $username = $targetUser->getUID();
868
+        $lang = $this->config->getUserValue($username, 'core', 'lang', 'en');
869
+        if (!$this->l10nFactory->languageExists('settings', $lang)) {
870
+            $lang = 'en';
871
+        }
872
+
873
+        $l10n = $this->l10nFactory->get('settings', $lang);
874
+
875
+        try {
876
+            $this->newUserMailHelper->setL10N($l10n);
877
+            $emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
878
+            $this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
879
+        } catch(\Exception $e) {
880
+            $this->logger->logException($e, [
881
+                'message' => "Can't send new user mail to $email",
882
+                'level' => \OCP\Util::ERROR,
883
+                'app' => 'settings',
884
+            ]);
885
+            throw new OCSException('Sending email failed', 102);
886
+        }
887
+
888
+        return new DataResponse();
889
+    }
890 890
 }
Please login to merge, or discard this patch.