Passed
Push — master ( 0a3df0...6cdb39 )
by Morris
13:13
created

GroupsController::getGroupUsersDetails()   B

Complexity

Conditions 7
Paths 9

Size

Total Lines 38
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 20
nc 9
nop 4
dl 0
loc 38
rs 8.6666
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * @copyright Copyright (c) 2016, ownCloud, Inc.
5
 *
6
 * @author Joas Schilling <[email protected]>
7
 * @author Lukas Reschke <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Roeland Jago Douma <[email protected]>
10
 * @author Tom Needham <[email protected]>
11
 * @author John Molakvoæ <[email protected]>
12
 *
13
 * @license AGPL-3.0
14
 *
15
 * This code is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License, version 3,
17
 * as published by the Free Software Foundation.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License, version 3,
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
26
 *
27
 */
28
29
namespace OCA\Provisioning_API\Controller;
30
31
use OC\Accounts\AccountManager;
32
use OCP\AppFramework\Http\DataResponse;
33
use OCP\AppFramework\OCS\OCSException;
34
use OCP\AppFramework\OCS\OCSNotFoundException;
35
use OCP\AppFramework\OCS\OCSForbiddenException;
36
use OCP\IConfig;
37
use OCP\IGroup;
38
use OCP\IGroupManager;
39
use OCP\ILogger;
40
use OCP\IRequest;
41
use OCP\IUserManager;
42
use OCP\IUserSession;
43
use OCP\IUser;
44
45
class GroupsController extends AUserData {
46
47
	/** @var ILogger */
48
	private $logger;
49
50
	/**
51
	 * @param string $appName
52
	 * @param IRequest $request
53
	 * @param IUserManager $userManager
54
	 * @param IConfig $config
55
	 * @param IGroupManager $groupManager
56
	 * @param IUserSession $userSession
57
	 * @param AccountManager $accountManager
58
	 * @param ILogger $logger
59
	 * @param UsersController $userController
60
	 */
61
	public function __construct(string $appName,
62
								IRequest $request,
63
								IUserManager $userManager,
64
								IConfig $config,
65
								IGroupManager $groupManager,
66
								IUserSession $userSession,
67
								AccountManager $accountManager,
68
								ILogger $logger) {
69
		parent::__construct($appName,
70
			$request,
71
			$userManager,
72
			$config,
73
			$groupManager,
74
			$userSession,
75
			$accountManager);
76
77
		$this->logger = $logger;
78
	}
79
80
	/**
81
	 * returns a list of groups
82
	 *
83
	 * @NoAdminRequired
84
	 *
85
	 * @param string $search
86
	 * @param int $limit
87
	 * @param int $offset
88
	 * @return DataResponse
89
	 */
90
	public function getGroups(string $search = '', int $limit = null, int $offset = 0): DataResponse {
91
		$groups = $this->groupManager->search($search, $limit, $offset);
92
		$groups = array_map(function($group) {
93
			/** @var IGroup $group */
94
			return $group->getGID();
95
		}, $groups);
96
97
		return new DataResponse(['groups' => $groups]);
98
	}
99
100
	/**
101
	 * returns a list of groups details with ids and displaynames
102
	 *
103
	 * @NoAdminRequired
104
	 *
105
	 * @param string $search
106
	 * @param int $limit
107
	 * @param int $offset
108
	 * @return DataResponse
109
	 */
110
	public function getGroupsDetails(string $search = '', int $limit = null, int $offset = 0): DataResponse {
111
		$groups = $this->groupManager->search($search, $limit, $offset);
112
		$groups = array_map(function($group) {
113
			/** @var IGroup $group */
114
			return [
115
				'id' => $group->getGID(),
116
				'displayname' => $group->getDisplayName(),
117
				'usercount' => $group->count(),
118
				'disabled' => $group->countDisabled(),
119
				'canAdd' => $group->canAddUser(),
120
				'canRemove' => $group->canRemoveUser(),
121
			];
122
		}, $groups);
123
124
		return new DataResponse(['groups' => $groups]);
125
	}
126
127
	/**
128
	 * @NoAdminRequired
129
	 *
130
	 * @param string $groupId
131
	 * @return DataResponse
132
	 * @throws OCSException	
133
	 *
134
	 * @deprecated 14 Use getGroupUsers
135
	 */
136
	public function getGroup(string $groupId): DataResponse {
137
		return $this->getGroupUsers($groupId);
138
	}
139
140
	/**
141
	 * returns an array of users in the specified group
142
	 *
143
	 * @NoAdminRequired
144
	 *
145
	 * @param string $groupId
146
	 * @return DataResponse
147
	 * @throws OCSException
148
	 */
149
	public function getGroupUsers(string $groupId): DataResponse {
150
		$user = $this->userSession->getUser();
151
		$isSubadminOfGroup = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $isSubadminOfGroup is dead and can be removed.
Loading history...
152
153
		// Check the group exists
154
		$group = $this->groupManager->get($groupId);
155
		if ($group !== null) {
156
			$isSubadminOfGroup =$this->groupManager->getSubAdmin()->isSubAdminOfGroup($user, $group);
0 ignored issues
show
Bug introduced by
The method getSubAdmin() does not exist on OCP\IGroupManager. Since it exists in all sub-types, consider adding an abstract or default implementation to OCP\IGroupManager. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
			$isSubadminOfGroup =$this->groupManager->/** @scrutinizer ignore-call */ getSubAdmin()->isSubAdminOfGroup($user, $group);
Loading history...
Bug introduced by
It seems like $user can also be of type null; however, parameter $user of OC\SubAdmin::isSubAdminOfGroup() does only seem to accept OCP\IUser, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

156
			$isSubadminOfGroup =$this->groupManager->getSubAdmin()->isSubAdminOfGroup(/** @scrutinizer ignore-type */ $user, $group);
Loading history...
157
		} else {
158
			throw new OCSNotFoundException('The requested group could not be found');
159
		}
160
161
		// Check subadmin has access to this group
162
		if($this->groupManager->isAdmin($user->getUID())
163
		   || $isSubadminOfGroup) {
164
			$users = $this->groupManager->get($groupId)->getUsers();
165
			$users =  array_map(function($user) {
166
				/** @var IUser $user */
167
				return $user->getUID();
168
			}, $users);
169
			$users = array_values($users);
170
			return new DataResponse(['users' => $users]);
171
		}
172
173
		throw new OCSForbiddenException();
174
	}
175
176
	/**
177
	 * returns an array of users details in the specified group
178
	 *
179
	 * @NoAdminRequired
180
	 *
181
	 * @param string $groupId
182
	 * @param string $search
183
	 * @param int $limit
184
	 * @param int $offset
185
	 * @return DataResponse
186
	 * @throws OCSException
187
	 */
188
	public function getGroupUsersDetails(string $groupId, string $search = '', int $limit = null, int $offset = 0): DataResponse {
189
		$currentUser = $this->userSession->getUser();
190
191
		// Check the group exists
192
		$group = $this->groupManager->get($groupId);
193
		if ($group !== null) {
194
			$isSubadminOfGroup = $this->groupManager->getSubAdmin()->isSubAdminOfGroup($currentUser, $group);
0 ignored issues
show
Bug introduced by
It seems like $currentUser can also be of type null; however, parameter $user of OC\SubAdmin::isSubAdminOfGroup() does only seem to accept OCP\IUser, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

194
			$isSubadminOfGroup = $this->groupManager->getSubAdmin()->isSubAdminOfGroup(/** @scrutinizer ignore-type */ $currentUser, $group);
Loading history...
195
		} else {
196
			throw new OCSException('The requested group could not be found', \OCP\API::RESPOND_NOT_FOUND);
197
		}
198
199
		// Check subadmin has access to this group
200
		if($this->groupManager->isAdmin($currentUser->getUID()) || $isSubadminOfGroup) {
201
			$users = $group->searchUsers($search, $limit, $offset);
202
203
			// Extract required number
204
			$usersDetails = [];
205
			foreach ($users as $user) {
206
				try {
207
					/** @var IUser $user */
208
					$userId = (string)$user->getUID();
209
					$userData = $this->getUserData($userId);
210
					// Do not insert empty entry
211
					if (!empty($userData)) {
212
						$usersDetails[$userId] = $userData;
213
					} else {
214
						// Logged user does not have permissions to see this user
215
						// only showing its id
216
						$usersDetails[$userId] = ['id' => $userId];
217
					}
218
				} catch(OCSNotFoundException $e) {
219
					// continue if a users ceased to exist.
220
				}
221
			}
222
			return new DataResponse(['users' => $usersDetails]);
223
		}
224
225
		throw new OCSException('User does not have access to specified group', \OCP\API::RESPOND_UNAUTHORISED);
226
	}
227
228
	/**
229
	 * creates a new group
230
	 *
231
	 * @PasswordConfirmationRequired
232
	 *
233
	 * @param string $groupid
234
	 * @return DataResponse
235
	 * @throws OCSException
236
	 */
237
	public function addGroup(string $groupid): DataResponse {
238
		// Validate name
239
		if(empty($groupid)) {
240
			$this->logger->error('Group name not supplied', ['app' => 'provisioning_api']);
241
			throw new OCSException('Invalid group name', 101);
242
		}
243
		// Check if it exists
244
		if($this->groupManager->groupExists($groupid)){
245
			throw new OCSException('group exists', 102);
246
		}
247
		$this->groupManager->createGroup($groupid);
248
		return new DataResponse();
249
	}
250
251
	/**
252
	 * @PasswordConfirmationRequired
253
	 *
254
	 * @param string $groupId
255
	 * @return DataResponse
256
	 * @throws OCSException
257
	 */
258
	public function deleteGroup(string $groupId): DataResponse {
259
		// Check it exists
260
		if(!$this->groupManager->groupExists($groupId)){
261
			throw new OCSException('', 101);
262
		} else if($groupId === 'admin' || !$this->groupManager->get($groupId)->delete()){
263
			// Cannot delete admin group
264
			throw new OCSException('', 102);
265
		}
266
267
		return new DataResponse();
268
	}
269
270
	/**
271
	 * @param string $groupId
272
	 * @return DataResponse
273
	 * @throws OCSException
274
	 */
275
	public function getSubAdminsOfGroup(string $groupId): DataResponse {
276
		// Check group exists
277
		$targetGroup = $this->groupManager->get($groupId);
278
		if($targetGroup === null) {
279
			throw new OCSException('Group does not exist', 101);
280
		}
281
282
		/** @var IUser[] $subadmins */
283
		$subadmins = $this->groupManager->getSubAdmin()->getGroupsSubAdmins($targetGroup);
284
		// New class returns IUser[] so convert back
285
		$uids = [];
286
		foreach ($subadmins as $user) {
287
			$uids[] = $user->getUID();
288
		}
289
290
		return new DataResponse($uids);
291
	}
292
293
}
294