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