Passed
Push — master ( 2139b2...5b5550 )
by Joas
12:20 queued 14s
created

SubAdmin::isUserAccessible()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 2
b 0
f 0
nc 3
nop 2
dl 0
loc 12
rs 10
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Bart Visscher <[email protected]>
7
 * @author Christoph Wurst <[email protected]>
8
 * @author Georg Ehrke <[email protected]>
9
 * @author John Molakvoæ (skjnldsv) <[email protected]>
10
 * @author Lukas Reschke <[email protected]>
11
 * @author Morris Jobke <[email protected]>
12
 * @author Roeland Jago Douma <[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 OC;
31
32
use OC\Hooks\PublicEmitter;
33
use OCP\Group\ISubAdmin;
34
use OCP\IDBConnection;
35
use OCP\IGroup;
36
use OCP\IGroupManager;
37
use OCP\IUser;
38
use OCP\IUserManager;
39
40
class SubAdmin extends PublicEmitter implements ISubAdmin {
0 ignored issues
show
Deprecated Code introduced by
The class OC\Hooks\PublicEmitter has been deprecated: 18.0.0 use events and the \OCP\EventDispatcher\IEventDispatcher service ( Ignorable by Annotation )

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

40
class SubAdmin extends /** @scrutinizer ignore-deprecated */ PublicEmitter implements ISubAdmin {
Loading history...
41
42
	/** @var IUserManager */
43
	private $userManager;
44
45
	/** @var IGroupManager */
46
	private $groupManager;
47
48
	/** @var IDBConnection */
49
	private $dbConn;
50
51
	/**
52
	 * @param IUserManager $userManager
53
	 * @param IGroupManager $groupManager
54
	 * @param IDBConnection $dbConn
55
	 */
56
	public function __construct(IUserManager $userManager,
57
								IGroupManager $groupManager,
58
								IDBConnection $dbConn) {
59
		$this->userManager = $userManager;
60
		$this->groupManager = $groupManager;
61
		$this->dbConn = $dbConn;
62
63
		$this->userManager->listen('\OC\User', 'postDelete', function ($user) {
0 ignored issues
show
Bug introduced by
The method listen() does not exist on OCP\IUserManager. Since it exists in all sub-types, consider adding an abstract or default implementation to OCP\IUserManager. ( Ignorable by Annotation )

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

63
		$this->userManager->/** @scrutinizer ignore-call */ 
64
                      listen('\OC\User', 'postDelete', function ($user) {
Loading history...
64
			$this->post_deleteUser($user);
65
		});
66
		$this->groupManager->listen('\OC\Group', 'postDelete', function ($group) {
0 ignored issues
show
Bug introduced by
The method listen() 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

66
		$this->groupManager->/** @scrutinizer ignore-call */ 
67
                       listen('\OC\Group', 'postDelete', function ($group) {
Loading history...
67
			$this->post_deleteGroup($group);
68
		});
69
	}
70
71
	/**
72
	 * add a SubAdmin
73
	 * @param IUser $user user to be SubAdmin
74
	 * @param IGroup $group group $user becomes subadmin of
75
	 */
76
	public function createSubAdmin(IUser $user, IGroup $group): void {
77
		$qb = $this->dbConn->getQueryBuilder();
78
79
		$qb->insert('group_admin')
80
			->values([
81
				'gid' => $qb->createNamedParameter($group->getGID()),
82
				'uid' => $qb->createNamedParameter($user->getUID())
83
			])
84
			->execute();
85
86
		$this->emit('\OC\SubAdmin', 'postCreateSubAdmin', [$user, $group]);
87
		\OC_Hook::emit("OC_SubAdmin", "post_createSubAdmin", ["gid" => $group->getGID()]);
88
	}
89
90
	/**
91
	 * delete a SubAdmin
92
	 * @param IUser $user the user that is the SubAdmin
93
	 * @param IGroup $group the group
94
	 */
95
	public function deleteSubAdmin(IUser $user, IGroup $group): void {
96
		$qb = $this->dbConn->getQueryBuilder();
97
98
		$qb->delete('group_admin')
99
			->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
100
			->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
101
			->execute();
102
103
		$this->emit('\OC\SubAdmin', 'postDeleteSubAdmin', [$user, $group]);
104
		\OC_Hook::emit("OC_SubAdmin", "post_deleteSubAdmin", ["gid" => $group->getGID()]);
105
	}
106
107
	/**
108
	 * get groups of a SubAdmin
109
	 * @param IUser $user the SubAdmin
110
	 * @return IGroup[]
111
	 */
112
	public function getSubAdminsGroups(IUser $user): array {
113
		$groupIds = $this->getSubAdminsGroupIds($user);
114
115
		$groups = [];
116
		foreach ($groupIds as $groupId) {
117
			$group = $this->groupManager->get($groupId);
118
			if ($group !== null) {
119
				$groups[$group->getGID()] = $group;
120
			}
121
		}
122
123
		return $groups;
124
	}
125
126
	/**
127
	 * Get group ids of a SubAdmin
128
	 * @param IUser $user the SubAdmin
129
	 * @return string[]
130
	 */
131
	public function getSubAdminsGroupIds(IUser $user): array {
132
		$qb = $this->dbConn->getQueryBuilder();
133
134
		$result = $qb->select('gid')
135
			->from('group_admin')
136
			->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
137
			->execute();
138
139
		$groups = [];
140
		while ($row = $result->fetch()) {
141
			$groups[] = $row['gid'];
142
		}
143
		$result->closeCursor();
144
145
		return $groups;
146
	}
147
148
	/**
149
	 * get an array of groupid and displayName for a user
150
	 * @param IUser $user
151
	 * @return array ['displayName' => displayname]
152
	 */
153
	public function getSubAdminsGroupsName(IUser $user): array {
154
		return array_map(function ($group) {
155
			return ['displayName' => $group->getDisplayName()];
156
		}, $this->getSubAdminsGroups($user));
157
	}
158
159
	/**
160
	 * get SubAdmins of a group
161
	 * @param IGroup $group the group
162
	 * @return IUser[]
163
	 */
164
	public function getGroupsSubAdmins(IGroup $group): array {
165
		$qb = $this->dbConn->getQueryBuilder();
166
167
		$result = $qb->select('uid')
168
			->from('group_admin')
169
			->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
170
			->execute();
171
172
		$users = [];
173
		while ($row = $result->fetch()) {
174
			$user = $this->userManager->get($row['uid']);
175
			if (!is_null($user)) {
176
				$users[] = $user;
177
			}
178
		}
179
		$result->closeCursor();
180
181
		return $users;
182
	}
183
184
	/**
185
	 * get all SubAdmins
186
	 * @return array
187
	 */
188
	public function getAllSubAdmins(): array {
189
		$qb = $this->dbConn->getQueryBuilder();
190
191
		$result = $qb->select('*')
192
			->from('group_admin')
193
			->execute();
194
195
		$subadmins = [];
196
		while ($row = $result->fetch()) {
197
			$user = $this->userManager->get($row['uid']);
198
			$group = $this->groupManager->get($row['gid']);
199
			if (!is_null($user) && !is_null($group)) {
200
				$subadmins[] = [
201
					'user'  => $user,
202
					'group' => $group
203
				];
204
			}
205
		}
206
		$result->closeCursor();
207
208
		return $subadmins;
209
	}
210
211
	/**
212
	 * checks if a user is a SubAdmin of a group
213
	 * @param IUser $user
214
	 * @param IGroup $group
215
	 * @return bool
216
	 */
217
	public function isSubAdminOfGroup(IUser $user, IGroup $group): bool {
218
		$qb = $this->dbConn->getQueryBuilder();
219
220
		/*
221
		 * Primary key is ('gid', 'uid') so max 1 result possible here
222
		 */
223
		$result = $qb->select('*')
224
			->from('group_admin')
225
			->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
226
			->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
227
			->execute();
228
229
		$fetch =  $result->fetch();
230
		$result->closeCursor();
231
		$result = !empty($fetch) ? true : false;
232
233
		return $result;
234
	}
235
236
	/**
237
	 * checks if a user is a SubAdmin
238
	 * @param IUser $user
239
	 * @return bool
240
	 */
241
	public function isSubAdmin(IUser $user): bool {
242
		// Check if the user is already an admin
243
		if ($this->groupManager->isAdmin($user->getUID())) {
244
			return true;
245
		}
246
247
		$qb = $this->dbConn->getQueryBuilder();
248
249
		$result = $qb->select('gid')
250
			->from('group_admin')
251
			->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
252
			->setMaxResults(1)
253
			->execute();
254
255
		$isSubAdmin = $result->fetch();
256
		$result->closeCursor();
257
258
		return $isSubAdmin !== false;
259
	}
260
261
	/**
262
	 * checks if a user is a accessible by a subadmin
263
	 * @param IUser $subadmin
264
	 * @param IUser $user
265
	 * @return bool
266
	 */
267
	public function isUserAccessible(IUser $subadmin, IUser $user): bool {
268
		if (!$this->isSubAdmin($subadmin)) {
269
			return false;
270
		}
271
		if ($this->groupManager->isAdmin($user->getUID())) {
272
			return false;
273
		}
274
275
		$accessibleGroups = $this->getSubAdminsGroupIds($subadmin);
276
		$userGroups = $this->groupManager->getUserGroupIds($user);
277
278
		return !empty(array_intersect($accessibleGroups, $userGroups));
279
	}
280
281
	/**
282
	 * delete all SubAdmins by $user
283
	 * @param IUser $user
284
	 */
285
	private function post_deleteUser(IUser $user) {
286
		$qb = $this->dbConn->getQueryBuilder();
287
288
		$qb->delete('group_admin')
289
			->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
290
			->execute();
291
	}
292
293
	/**
294
	 * delete all SubAdmins by $group
295
	 * @param IGroup $group
296
	 */
297
	private function post_deleteGroup(IGroup $group) {
298
		$qb = $this->dbConn->getQueryBuilder();
299
300
		$qb->delete('group_admin')
301
			->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
302
			->execute();
303
	}
304
}
305