Completed
Push — master ( 29f5ab...43315e )
by Lukas
08:11
created

UsersController::getUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Lukas Reschke <[email protected]>
8
 * @author michag86 <[email protected]>
9
 * @author Morris Jobke <[email protected]>
10
 * @author Roeland Jago Douma <[email protected]>
11
 * @author Thomas Müller <[email protected]>
12
 * @author Tom Needham <[email protected]>
13
 *
14
 * @license AGPL-3.0
15
 *
16
 * This code is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License, version 3,
18
 * as published by the Free Software Foundation.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License, version 3,
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
27
 *
28
 */
29
30
namespace OCA\Provisioning_API\Controller;
31
32
use OC\Accounts\AccountManager;
33
use \OC_Helper;
34
use OCP\AppFramework\Http\DataResponse;
35
use OCP\AppFramework\OCS\OCSException;
36
use OCP\AppFramework\OCS\OCSForbiddenException;
37
use OCP\AppFramework\OCSController;
38
use OCP\Files\NotFoundException;
39
use OCP\IConfig;
40
use OCP\IGroup;
41
use OCP\IGroupManager;
42
use OCP\ILogger;
43
use OCP\IRequest;
44
use OCP\IUserManager;
45
use OCP\IUserSession;
46
47
class UsersController extends OCSController {
48
49
	/** @var IUserManager */
50
	private $userManager;
51
	/** @var IConfig */
52
	private $config;
53
	/** @var IGroupManager|\OC\Group\Manager */ // FIXME Requires a method that is not on the interface
54
	private $groupManager;
55
	/** @var IUserSession */
56
	private $userSession;
57
	/** @var AccountManager */
58
	private $accountManager;
59
	/** @var ILogger */
60
	private $logger;
61
62
	/**
63
	 * @param string $appName
64
	 * @param IRequest $request
65
	 * @param IUserManager $userManager
66
	 * @param IConfig $config
67
	 * @param IGroupManager $groupManager
68
	 * @param IUserSession $userSession
69
	 * @param AccountManager $accountManager
70
	 * @param ILogger $logger
71
	 */
72 View Code Duplication
	public function __construct($appName,
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
73
								IRequest $request,
74
								IUserManager $userManager,
75
								IConfig $config,
76
								IGroupManager $groupManager,
77
								IUserSession $userSession,
78
								AccountManager $accountManager,
79
								ILogger $logger) {
80
		parent::__construct($appName, $request);
81
82
		$this->userManager = $userManager;
83
		$this->config = $config;
84
		$this->groupManager = $groupManager;
85
		$this->userSession = $userSession;
86
		$this->accountManager = $accountManager;
87
		$this->logger = $logger;
88
	}
89
90
	/**
91
	 * @NoAdminRequired
92
	 *
93
	 * returns a list of users
94
	 *
95
	 * @param string $search
96
	 * @param int $limit
97
	 * @param int $offset
98
	 * @return DataResponse
99
	 */
100
	public function getUsers($search = '', $limit = null, $offset = null) {
101
		$user = $this->userSession->getUser();
102
		$users = [];
103
104
		// Admin? Or SubAdmin?
105
		$uid = $user->getUID();
106
		$subAdminManager = $this->groupManager->getSubAdmin();
107
		if($this->groupManager->isAdmin($uid)){
108
			$users = $this->userManager->search($search, $limit, $offset);
109
		} else if ($subAdminManager->isSubAdmin($user)) {
110
			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
111
			foreach ($subAdminOfGroups as $key => $group) {
112
				$subAdminOfGroups[$key] = $group->getGID();
113
			}
114
115
			if($offset === null) {
116
				$offset = 0;
117
			}
118
119
			$users = [];
120
			foreach ($subAdminOfGroups as $group) {
121
				$users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search));
122
			}
123
124
			$users = array_slice($users, $offset, $limit);
125
		}
126
127
		$users = array_keys($users);
128
129
		return new DataResponse([
130
			'users' => $users
131
		]);
132
	}
133
134
	/**
135
	 * @PasswordConfirmationRequired
136
	 * @NoAdminRequired
137
	 *
138
	 * @param string $userid
139
	 * @param string $password
140
	 * @param array $groups
141
	 * @return DataResponse
142
	 * @throws OCSException
143
	 */
144
	public function addUser($userid, $password, $groups = null) {
145
		$user = $this->userSession->getUser();
146
		$isAdmin = $this->groupManager->isAdmin($user->getUID());
147
		$subAdminManager = $this->groupManager->getSubAdmin();
148
149
		if($this->userManager->userExists($userid)) {
150
			$this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
151
			throw new OCSException('User already exists', 102);
152
		}
153
154
		if(is_array($groups)) {
155
			foreach ($groups as $group) {
156
				if(!$this->groupManager->groupExists($group)) {
157
					throw new OCSException('group '.$group.' does not exist', 104);
158
				}
159
				if(!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
160
					throw new OCSException('insufficient privileges for group '. $group, 105);
161
				}
162
			}
163
		} else {
164
			if(!$isAdmin) {
165
				throw new OCSException('no group specified (required for subadmins)', 106);
166
			}
167
		}
168
169
		try {
170
			$newUser = $this->userManager->createUser($userid, $password);
171
			$this->logger->info('Successful addUser call with userid: '.$userid, ['app' => 'ocs_api']);
172
173
			if (is_array($groups)) {
174
				foreach ($groups as $group) {
175
					$this->groupManager->get($group)->addUser($newUser);
0 ignored issues
show
Bug introduced by
It seems like $newUser defined by $this->userManager->crea...ser($userid, $password) on line 170 can also be of type boolean; however, OCP\IGroup::addUser() does only seem to accept object<OCP\IUser>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
176
					$this->logger->info('Added userid '.$userid.' to group '.$group, ['app' => 'ocs_api']);
177
				}
178
			}
179
			return new DataResponse();
180
		} catch (\Exception $e) {
181
			$this->logger->error('Failed addUser attempt with exception: '.$e->getMessage(), ['app' => 'ocs_api']);
182
			throw new OCSException('Bad request', 101);
183
		}
184
	}
185
186
	/**
187
	 * @NoAdminRequired
188
	 * @NoSubAdminRequired
189
	 *
190
	 * gets user info
191
	 *
192
	 * @param string $userId
193
	 * @return DataResponse
194
	 * @throws OCSException
195
	 */
196
	public function getUser($userId) {
197
		$data = $this->getUserData($userId);
198
		return new DataResponse($data);
199
	}
200
201
	/**
202
	 * @NoAdminRequired
203
	 * @NoSubAdminRequired
204
	 *
205
	 * gets user info from the currently logged in user
206
	 *
207
	 * @return DataResponse
208
	 * @throws OCSException
209
	 */
210
	public function getCurrentUser() {
211
		$user = $this->userSession->getUser();
212
		if ($user) {
213
			$data =  $this->getUserData($user->getUID());
214
			// rename "displayname" to "display-name" only for this call to keep
215
			// the API stable.
216
			$data['display-name'] = $data['displayname'];
217
			unset($data['displayname']);
218
			return new DataResponse($data);
219
220
		}
221
222
		throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
223
	}
224
225
	/**
226
	 * creates a array with all user data
227
	 *
228
	 * @param $userId
229
	 * @return array
230
	 * @throws OCSException
231
	 */
232
	protected function getUserData($userId) {
233
		$currentLoggedInUser = $this->userSession->getUser();
234
235
		$data = [];
236
237
		// Check if the target user exists
238
		$targetUserObject = $this->userManager->get($userId);
239
		if($targetUserObject === null) {
240
			throw new OCSException('The requested user could not be found', \OCP\API::RESPOND_NOT_FOUND);
241
		}
242
243
		// Admin? Or SubAdmin?
244
		if($this->groupManager->isAdmin($currentLoggedInUser->getUID())
245
			|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
246
			$data['enabled'] = $this->config->getUserValue($userId, 'core', 'enabled', 'true');
247
		} else {
248
			// Check they are looking up themselves
249
			if($currentLoggedInUser->getUID() !== $userId) {
250
				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
251
			}
252
		}
253
254
		$userAccount = $this->accountManager->getUser($targetUserObject);
255
256
		// Find the data
257
		$data['id'] = $targetUserObject->getUID();
258
		$data['quota'] = $this->fillStorageInfo($userId);
259
		$data['email'] = $targetUserObject->getEMailAddress();
260
		$data['displayname'] = $targetUserObject->getDisplayName();
261
		$data['phone'] = $userAccount[\OC\Accounts\AccountManager::PROPERTY_PHONE]['value'];
262
		$data['address'] = $userAccount[\OC\Accounts\AccountManager::PROPERTY_ADDRESS]['value'];
263
		$data['webpage'] = $userAccount[\OC\Accounts\AccountManager::PROPERTY_WEBSITE]['value'];
264
		$data['twitter'] = $userAccount[\OC\Accounts\AccountManager::PROPERTY_TWITTER]['value'];
265
266
		return $data;
267
	}
268
269
	/**
270
	 * @NoAdminRequired
271
	 * @NoSubAdminRequired
272
	 * @PasswordConfirmationRequired
273
	 *
274
	 * edit users
275
	 *
276
	 * @param string $userId
277
	 * @param string $key
278
	 * @param string $value
279
	 * @return DataResponse
280
	 * @throws OCSException
281
	 * @throws OCSForbiddenException
282
	 */
283
	public function editUser($userId, $key, $value) {
284
		$currentLoggedInUser = $this->userSession->getUser();
285
286
		$targetUser = $this->userManager->get($userId);
287
		if($targetUser === null) {
288
			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
289
		}
290
291
		$permittedFields = [];
292
		if($userId === $currentLoggedInUser->getUID()) {
293
			// Editing self (display, email)
294
			$permittedFields[] = 'display';
295
			$permittedFields[] = 'email';
296
			$permittedFields[] = 'password';
297
			// If admin they can edit their own quota
298
			if($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
299
				$permittedFields[] = 'quota';
300
			}
301
		} else {
302
			// Check if admin / subadmin
303
			$subAdminManager = $this->groupManager->getSubAdmin();
304
			if($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
305
			|| $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
306
				// They have permissions over the user
307
				$permittedFields[] = 'display';
308
				$permittedFields[] = 'quota';
309
				$permittedFields[] = 'password';
310
				$permittedFields[] = 'email';
311
			} else {
312
				// No rights
313
				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
314
			}
315
		}
316
		// Check if permitted to edit this field
317
		if(!in_array($key, $permittedFields)) {
318
			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
319
		}
320
		// Process the edit
321
		switch($key) {
322
			case 'display':
323
				$targetUser->setDisplayName($value);
324
				break;
325
			case 'quota':
326
				$quota = $value;
327
				if($quota !== 'none' && $quota !== 'default') {
328
					if (is_numeric($quota)) {
329
						$quota = (float) $quota;
330
					} else {
331
						$quota = \OCP\Util::computerFileSize($quota);
332
					}
333
					if ($quota === false) {
334
						throw new OCSException('Invalid quota value '.$value, 103);
335
					}
336
					if($quota === 0) {
337
						$quota = 'default';
338
					}else if($quota === -1) {
339
						$quota = 'none';
340
					} else {
341
						$quota = \OCP\Util::humanFileSize($quota);
342
					}
343
				}
344
				$targetUser->setQuota($quota);
345
				break;
346
			case 'password':
347
				$targetUser->setPassword($value);
348
				break;
349
			case 'email':
350
				if(filter_var($value, FILTER_VALIDATE_EMAIL)) {
351
					$targetUser->setEMailAddress($value);
352
				} else {
353
					throw new OCSException('', 102);
354
				}
355
				break;
356
			default:
357
				throw new OCSException('', 103);
358
		}
359
		return new DataResponse();
360
	}
361
362
	/**
363
	 * @PasswordConfirmationRequired
364
	 * @NoAdminRequired
365
	 *
366
	 * @param string $userId
367
	 * @return DataResponse
368
	 * @throws OCSException
369
	 * @throws OCSForbiddenException
370
	 */
371
	public function deleteUser($userId) {
372
		$currentLoggedInUser = $this->userSession->getUser();
373
374
		$targetUser = $this->userManager->get($userId);
375
376 View Code Duplication
		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
377
			throw new OCSException('', 101);
378
		}
379
380
		// If not permitted
381
		$subAdminManager = $this->groupManager->getSubAdmin();
382 View Code Duplication
		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
383
			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
384
		}
385
386
		// Go ahead with the delete
387
		if($targetUser->delete()) {
388
			return new DataResponse();
389
		} else {
390
			throw new OCSException('', 101);
391
		}
392
	}
393
394
	/**
395
	 * @PasswordConfirmationRequired
396
	 * @NoAdminRequired
397
	 *
398
	 * @param string $userId
399
	 * @return DataResponse
400
	 * @throws OCSException
401
	 * @throws OCSForbiddenException
402
	 */
403
	public function disableUser($userId) {
404
		return $this->setEnabled($userId, false);
405
	}
406
407
	/**
408
	 * @PasswordConfirmationRequired
409
	 * @NoAdminRequired
410
	 *
411
	 * @param string $userId
412
	 * @return DataResponse
413
	 * @throws OCSException
414
	 * @throws OCSForbiddenException
415
	 */
416
	public function enableUser($userId) {
417
		return $this->setEnabled($userId, true);
418
	}
419
420
	/**
421
	 * @param string $userId
422
	 * @param bool $value
423
	 * @return DataResponse
424
	 * @throws OCSException
425
	 * @throws OCSForbiddenException
426
	 */
427
	private function setEnabled($userId, $value) {
428
		$currentLoggedInUser = $this->userSession->getUser();
429
430
		$targetUser = $this->userManager->get($userId);
431 View Code Duplication
		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
432
			throw new OCSException('', 101);
433
		}
434
435
		// If not permitted
436
		$subAdminManager = $this->groupManager->getSubAdmin();
437 View Code Duplication
		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
438
			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
439
		}
440
441
		// enable/disable the user now
442
		$targetUser->setEnabled($value);
443
		return new DataResponse();
444
	}
445
446
	/**
447
	 * @NoAdminRequired
448
	 * @NoSubAdminRequired
449
	 *
450
	 * @param string $userId
451
	 * @return DataResponse
452
	 * @throws OCSException
453
	 */
454
	public function getUsersGroups($userId) {
455
		$loggedInUser = $this->userSession->getUser();
456
457
		$targetUser = $this->userManager->get($userId);
458
		if($targetUser === null) {
459
			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
460
		}
461
462
		if($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
463
			// Self lookup or admin lookup
464
			return new DataResponse([
465
				'groups' => $this->groupManager->getUserGroupIds($targetUser)
466
			]);
467
		} else {
468
			$subAdminManager = $this->groupManager->getSubAdmin();
469
470
			// Looking up someone else
471
			if($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
472
				// Return the group that the method caller is subadmin of for the user in question
473
				/** @var IGroup[] $getSubAdminsGroups */
474
				$getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
475
				foreach ($getSubAdminsGroups as $key => $group) {
476
					$getSubAdminsGroups[$key] = $group->getGID();
477
				}
478
				$groups = array_intersect(
479
					$getSubAdminsGroups,
480
					$this->groupManager->getUserGroupIds($targetUser)
481
				);
482
				return new DataResponse(['groups' => $groups]);
483
			} else {
484
				// Not permitted
485
				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
486
			}
487
		}
488
489
	}
490
491
	/**
492
	 * @PasswordConfirmationRequired
493
	 * @NoAdminRequired
494
	 *
495
	 * @param string $userId
496
	 * @param string $groupid
497
	 * @return DataResponse
498
	 * @throws OCSException
499
	 */
500
	public function addToGroup($userId, $groupid = '') {
501
		if($groupid === '') {
502
			throw new OCSException('', 101);
503
		}
504
505
		$group = $this->groupManager->get($groupid);
506
		$targetUser = $this->userManager->get($userId);
507
		if($group === null) {
508
			throw new OCSException('', 102);
509
		}
510
		if($targetUser === null) {
511
			throw new OCSException('', 103);
512
		}
513
514
		// If they're not an admin, check they are a subadmin of the group in question
515
		$loggedInUser = $this->userSession->getUser();
516
		$subAdminManager = $this->groupManager->getSubAdmin();
517 View Code Duplication
		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
518
			throw new OCSException('', 104);
519
		}
520
521
		// Add user to group
522
		$group->addUser($targetUser);
523
		return new DataResponse();
524
	}
525
526
	/**
527
	 * @PasswordConfirmationRequired
528
	 * @NoAdminRequired
529
	 *
530
	 * @param string $userId
531
	 * @param string $groupid
532
	 * @return DataResponse
533
	 * @throws OCSException
534
	 */
535
	public function removeFromGroup($userId, $groupid) {
536
		$loggedInUser = $this->userSession->getUser();
537
538
		if($groupid === null) {
539
			throw new OCSException('', 101);
540
		}
541
542
		$group = $this->groupManager->get($groupid);
543
		if($group === null) {
544
			throw new OCSException('', 102);
545
		}
546
547
		$targetUser = $this->userManager->get($userId);
548
		if($targetUser === null) {
549
			throw new OCSException('', 103);
550
		}
551
552
		// If they're not an admin, check they are a subadmin of the group in question
553
		$subAdminManager = $this->groupManager->getSubAdmin();
554 View Code Duplication
		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
555
			throw new OCSException('', 104);
556
		}
557
558
		// Check they aren't removing themselves from 'admin' or their 'subadmin; group
559
		if ($userId === $loggedInUser->getUID()) {
560
			if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
561
				if ($group->getGID() === 'admin') {
562
					throw new OCSException('Cannot remove yourself from the admin group', 105);
563
				}
564
			} else {
565
				// Not an admin, so the user must be a subadmin of this group, but that is not allowed.
566
				throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
567
			}
568
569
		} else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
570
			/** @var IGroup[] $subAdminGroups */
571
			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
572
			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
573
				return $subAdminGroup->getGID();
574
			}, $subAdminGroups);
575
			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
576
			$userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
577
578
			if (count($userSubAdminGroups) <= 1) {
579
				// Subadmin must not be able to remove a user from all their subadmin groups.
580
				throw new OCSException('Cannot remove user from this group as this is the only remaining group you are a SubAdmin of', 105);
581
			}
582
		}
583
584
		// Remove user from group
585
		$group->removeUser($targetUser);
586
		return new DataResponse();
587
	}
588
589
	/**
590
	 * Creates a subadmin
591
	 *
592
	 * @PasswordConfirmationRequired
593
	 *
594
	 * @param string $userId
595
	 * @param string $groupid
596
	 * @return DataResponse
597
	 * @throws OCSException
598
	 */
599
	public function addSubAdmin($userId, $groupid) {
600
		$group = $this->groupManager->get($groupid);
601
		$user = $this->userManager->get($userId);
602
603
		// Check if the user exists
604
		if($user === null) {
605
			throw new OCSException('User does not exist', 101);
606
		}
607
		// Check if group exists
608
		if($group === null) {
609
			throw new OCSException('Group:'.$groupid.' does not exist',  102);
610
		}
611
		// Check if trying to make subadmin of admin group
612
		if(strtolower($groupid) === 'admin') {
613
			throw new OCSException('Cannot create subadmins for admin group', 103);
614
		}
615
616
		$subAdminManager = $this->groupManager->getSubAdmin();
617
618
		// We cannot be subadmin twice
619
		if ($subAdminManager->isSubAdminofGroup($user, $group)) {
620
			return new DataResponse();
621
		}
622
		// Go
623
		if($subAdminManager->createSubAdmin($user, $group)) {
624
			return new DataResponse();
625
		} else {
626
			throw new OCSException('Unknown error occurred', 103);
627
		}
628
	}
629
630
	/**
631
	 * Removes a subadmin from a group
632
	 *
633
	 * @PasswordConfirmationRequired
634
	 *
635
	 * @param string $userId
636
	 * @param string $groupid
637
	 * @return DataResponse
638
	 * @throws OCSException
639
	 */
640
	public function removeSubAdmin($userId, $groupid) {
641
		$group = $this->groupManager->get($groupid);
642
		$user = $this->userManager->get($userId);
643
		$subAdminManager = $this->groupManager->getSubAdmin();
644
645
		// Check if the user exists
646
		if($user === null) {
647
			throw new OCSException('User does not exist', 101);
648
		}
649
		// Check if the group exists
650
		if($group === null) {
651
			throw new OCSException('Group does not exist', 101);
652
		}
653
		// Check if they are a subadmin of this said group
654
		if(!$subAdminManager->isSubAdminofGroup($user, $group)) {
655
			throw new OCSException('User is not a subadmin of this group', 102);
656
		}
657
658
		// Go
659
		if($subAdminManager->deleteSubAdmin($user, $group)) {
660
			return new DataResponse();
661
		} else {
662
			throw new OCSException('Unknown error occurred', 103);
663
		}
664
	}
665
666
	/**
667
	 * Get the groups a user is a subadmin of
668
	 *
669
	 * @param string $userId
670
	 * @return DataResponse
671
	 * @throws OCSException
672
	 */
673
	public function getUserSubAdminGroups($userId) {
674
		$user = $this->userManager->get($userId);
675
		// Check if the user exists
676
		if($user === null) {
677
			throw new OCSException('User does not exist', 101);
678
		}
679
680
		// Get the subadmin groups
681
		$groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
682
		foreach ($groups as $key => $group) {
683
			$groups[$key] = $group->getGID();
684
		}
685
686
		if(!$groups) {
687
			throw new OCSException('Unknown error occurred', 102);
688
		} else {
689
			return new DataResponse($groups);
690
		}
691
	}
692
693
	/**
694
	 * @param string $userId
695
	 * @return array
696
	 * @throws \OCP\Files\NotFoundException
697
	 */
698
	protected function fillStorageInfo($userId) {
699
		try {
700
			\OC_Util::tearDownFS();
701
			\OC_Util::setupFS($userId);
702
			$storage = OC_Helper::getStorageInfo('/');
703
			$data = [
704
				'free' => $storage['free'],
705
				'used' => $storage['used'],
706
				'total' => $storage['total'],
707
				'relative' => $storage['relative'],
708
				'quota' => $storage['quota'],
709
			];
710
		} catch (NotFoundException $ex) {
711
			$data = [];
712
		}
713
		return $data;
714
	}
715
}
716