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