Passed
Push — master ( 83330b...e008b7 )
by Roeland
16:22 queued 11s
created
apps/settings/lib/Controller/AuthSettingsController.php 1 patch
Indentation   +263 added lines, -263 removed lines patch added patch discarded remove patch
@@ -55,267 +55,267 @@
 block discarded – undo
55 55
 
56 56
 class AuthSettingsController extends Controller {
57 57
 
58
-	/** @var IProvider */
59
-	private $tokenProvider;
60
-
61
-	/** @var ISession */
62
-	private $session;
63
-
64
-	/** IUserSession */
65
-	private $userSession;
66
-
67
-	/** @var string */
68
-	private $uid;
69
-
70
-	/** @var ISecureRandom */
71
-	private $random;
72
-
73
-	/** @var IManager */
74
-	private $activityManager;
75
-
76
-	/** @var RemoteWipe */
77
-	private $remoteWipe;
78
-
79
-	/** @var LoggerInterface */
80
-	private $logger;
81
-
82
-	/**
83
-	 * @param string $appName
84
-	 * @param IRequest $request
85
-	 * @param IProvider $tokenProvider
86
-	 * @param ISession $session
87
-	 * @param ISecureRandom $random
88
-	 * @param string|null $userId
89
-	 * @param IUserSession $userSession
90
-	 * @param IManager $activityManager
91
-	 * @param RemoteWipe $remoteWipe
92
-	 * @param LoggerInterface $logger
93
-	 */
94
-	public function __construct(string $appName,
95
-								IRequest $request,
96
-								IProvider $tokenProvider,
97
-								ISession $session,
98
-								ISecureRandom $random,
99
-								?string $userId,
100
-								IUserSession $userSession,
101
-								IManager $activityManager,
102
-								RemoteWipe $remoteWipe,
103
-								LoggerInterface $logger) {
104
-		parent::__construct($appName, $request);
105
-		$this->tokenProvider = $tokenProvider;
106
-		$this->uid = $userId;
107
-		$this->userSession = $userSession;
108
-		$this->session = $session;
109
-		$this->random = $random;
110
-		$this->activityManager = $activityManager;
111
-		$this->remoteWipe = $remoteWipe;
112
-		$this->logger = $logger;
113
-	}
114
-
115
-	/**
116
-	 * @NoAdminRequired
117
-	 * @NoSubAdminRequired
118
-	 * @PasswordConfirmationRequired
119
-	 *
120
-	 * @param string $name
121
-	 * @return JSONResponse
122
-	 */
123
-	public function create($name) {
124
-		if ($this->checkAppToken()) {
125
-			return $this->getServiceNotAvailableResponse();
126
-		}
127
-
128
-		try {
129
-			$sessionId = $this->session->getId();
130
-		} catch (SessionNotAvailableException $ex) {
131
-			return $this->getServiceNotAvailableResponse();
132
-		}
133
-		if ($this->userSession->getImpersonatingUserID() !== null) {
134
-			return $this->getServiceNotAvailableResponse();
135
-		}
136
-
137
-		try {
138
-			$sessionToken = $this->tokenProvider->getToken($sessionId);
139
-			$loginName = $sessionToken->getLoginName();
140
-			try {
141
-				$password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
142
-			} catch (PasswordlessTokenException $ex) {
143
-				$password = null;
144
-			}
145
-		} catch (InvalidTokenException $ex) {
146
-			return $this->getServiceNotAvailableResponse();
147
-		}
148
-
149
-		$token = $this->generateRandomDeviceToken();
150
-		$deviceToken = $this->tokenProvider->generateToken($token, $this->uid, $loginName, $password, $name, IToken::PERMANENT_TOKEN);
151
-		$tokenData = $deviceToken->jsonSerialize();
152
-		$tokenData['canDelete'] = true;
153
-		$tokenData['canRename'] = true;
154
-
155
-		$this->publishActivity(Provider::APP_TOKEN_CREATED, $deviceToken->getId(), ['name' => $deviceToken->getName()]);
156
-
157
-		return new JSONResponse([
158
-			'token' => $token,
159
-			'loginName' => $loginName,
160
-			'deviceToken' => $tokenData,
161
-		]);
162
-	}
163
-
164
-	/**
165
-	 * @return JSONResponse
166
-	 */
167
-	private function getServiceNotAvailableResponse() {
168
-		$resp = new JSONResponse();
169
-		$resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE);
170
-		return $resp;
171
-	}
172
-
173
-	/**
174
-	 * Return a 25 digit device password
175
-	 *
176
-	 * Example: AbCdE-fGhJk-MnPqR-sTwXy-23456
177
-	 *
178
-	 * @return string
179
-	 */
180
-	private function generateRandomDeviceToken() {
181
-		$groups = [];
182
-		for ($i = 0; $i < 5; $i++) {
183
-			$groups[] = $this->random->generate(5, ISecureRandom::CHAR_HUMAN_READABLE);
184
-		}
185
-		return implode('-', $groups);
186
-	}
187
-
188
-	private function checkAppToken(): bool {
189
-		return $this->session->exists('app_password');
190
-	}
191
-
192
-	/**
193
-	 * @NoAdminRequired
194
-	 * @NoSubAdminRequired
195
-	 *
196
-	 * @param int $id
197
-	 * @return array|JSONResponse
198
-	 */
199
-	public function destroy($id) {
200
-		if ($this->checkAppToken()) {
201
-			return new JSONResponse([], Http::STATUS_BAD_REQUEST);
202
-		}
203
-
204
-		try {
205
-			$token = $this->findTokenByIdAndUser($id);
206
-		} catch (WipeTokenException $e) {
207
-			//continue as we can destroy tokens in wipe
208
-			$token = $e->getToken();
209
-		} catch (InvalidTokenException $e) {
210
-			return new JSONResponse([], Http::STATUS_NOT_FOUND);
211
-		}
212
-
213
-		$this->tokenProvider->invalidateTokenById($this->uid, $token->getId());
214
-		$this->publishActivity(Provider::APP_TOKEN_DELETED, $token->getId(), ['name' => $token->getName()]);
215
-		return [];
216
-	}
217
-
218
-	/**
219
-	 * @NoAdminRequired
220
-	 * @NoSubAdminRequired
221
-	 *
222
-	 * @param int $id
223
-	 * @param array $scope
224
-	 * @param string $name
225
-	 * @return array|JSONResponse
226
-	 */
227
-	public function update($id, array $scope, string $name) {
228
-		if ($this->checkAppToken()) {
229
-			return new JSONResponse([], Http::STATUS_BAD_REQUEST);
230
-		}
231
-
232
-		try {
233
-			$token = $this->findTokenByIdAndUser($id);
234
-		} catch (InvalidTokenException $e) {
235
-			return new JSONResponse([], Http::STATUS_NOT_FOUND);
236
-		}
237
-
238
-		$currentName = $token->getName();
239
-
240
-		if ($scope !== $token->getScopeAsArray()) {
241
-			$token->setScope(['filesystem' => $scope['filesystem']]);
242
-			$this->publishActivity($scope['filesystem'] ? Provider::APP_TOKEN_FILESYSTEM_GRANTED : Provider::APP_TOKEN_FILESYSTEM_REVOKED, $token->getId(), ['name' => $currentName]);
243
-		}
244
-
245
-		if ($token instanceof INamedToken && $name !== $currentName) {
246
-			$token->setName($name);
247
-			$this->publishActivity(Provider::APP_TOKEN_RENAMED, $token->getId(), ['name' => $currentName, 'newName' => $name]);
248
-		}
249
-
250
-		$this->tokenProvider->updateToken($token);
251
-		return [];
252
-	}
253
-
254
-	/**
255
-	 * @param string $subject
256
-	 * @param int $id
257
-	 * @param array $parameters
258
-	 */
259
-	private function publishActivity(string $subject, int $id, array $parameters = []): void {
260
-		$event = $this->activityManager->generateEvent();
261
-		$event->setApp('settings')
262
-			->setType('security')
263
-			->setAffectedUser($this->uid)
264
-			->setAuthor($this->uid)
265
-			->setSubject($subject, $parameters)
266
-			->setObject('app_token', $id, 'App Password');
267
-
268
-		try {
269
-			$this->activityManager->publish($event);
270
-		} catch (BadMethodCallException $e) {
271
-			$this->logger->warning('could not publish activity', ['exception' => $e]);
272
-		}
273
-	}
274
-
275
-	/**
276
-	 * Find a token by given id and check if uid for current session belongs to this token
277
-	 *
278
-	 * @param int $id
279
-	 * @return IToken
280
-	 * @throws InvalidTokenException
281
-	 */
282
-	private function findTokenByIdAndUser(int $id): IToken {
283
-		try {
284
-			$token = $this->tokenProvider->getTokenById($id);
285
-		} catch (ExpiredTokenException $e) {
286
-			$token = $e->getToken();
287
-		}
288
-		if ($token->getUID() !== $this->uid) {
289
-			throw new InvalidTokenException('This token does not belong to you!');
290
-		}
291
-		return $token;
292
-	}
293
-
294
-	/**
295
-	 * @NoAdminRequired
296
-	 * @NoSubAdminRequired
297
-	 * @PasswordConfirmationRequired
298
-	 *
299
-	 * @param int $id
300
-	 * @return JSONResponse
301
-	 * @throws InvalidTokenException
302
-	 * @throws \OC\Authentication\Exceptions\ExpiredTokenException
303
-	 */
304
-	public function wipe(int $id): JSONResponse {
305
-		if ($this->checkAppToken()) {
306
-			return new JSONResponse([], Http::STATUS_BAD_REQUEST);
307
-		}
308
-
309
-		try {
310
-			$token = $this->findTokenByIdAndUser($id);
311
-		} catch (InvalidTokenException $e) {
312
-			return new JSONResponse([], Http::STATUS_NOT_FOUND);
313
-		}
314
-
315
-		if (!$this->remoteWipe->markTokenForWipe($token)) {
316
-			return new JSONResponse([], Http::STATUS_BAD_REQUEST);
317
-		}
318
-
319
-		return new JSONResponse([]);
320
-	}
58
+    /** @var IProvider */
59
+    private $tokenProvider;
60
+
61
+    /** @var ISession */
62
+    private $session;
63
+
64
+    /** IUserSession */
65
+    private $userSession;
66
+
67
+    /** @var string */
68
+    private $uid;
69
+
70
+    /** @var ISecureRandom */
71
+    private $random;
72
+
73
+    /** @var IManager */
74
+    private $activityManager;
75
+
76
+    /** @var RemoteWipe */
77
+    private $remoteWipe;
78
+
79
+    /** @var LoggerInterface */
80
+    private $logger;
81
+
82
+    /**
83
+     * @param string $appName
84
+     * @param IRequest $request
85
+     * @param IProvider $tokenProvider
86
+     * @param ISession $session
87
+     * @param ISecureRandom $random
88
+     * @param string|null $userId
89
+     * @param IUserSession $userSession
90
+     * @param IManager $activityManager
91
+     * @param RemoteWipe $remoteWipe
92
+     * @param LoggerInterface $logger
93
+     */
94
+    public function __construct(string $appName,
95
+                                IRequest $request,
96
+                                IProvider $tokenProvider,
97
+                                ISession $session,
98
+                                ISecureRandom $random,
99
+                                ?string $userId,
100
+                                IUserSession $userSession,
101
+                                IManager $activityManager,
102
+                                RemoteWipe $remoteWipe,
103
+                                LoggerInterface $logger) {
104
+        parent::__construct($appName, $request);
105
+        $this->tokenProvider = $tokenProvider;
106
+        $this->uid = $userId;
107
+        $this->userSession = $userSession;
108
+        $this->session = $session;
109
+        $this->random = $random;
110
+        $this->activityManager = $activityManager;
111
+        $this->remoteWipe = $remoteWipe;
112
+        $this->logger = $logger;
113
+    }
114
+
115
+    /**
116
+     * @NoAdminRequired
117
+     * @NoSubAdminRequired
118
+     * @PasswordConfirmationRequired
119
+     *
120
+     * @param string $name
121
+     * @return JSONResponse
122
+     */
123
+    public function create($name) {
124
+        if ($this->checkAppToken()) {
125
+            return $this->getServiceNotAvailableResponse();
126
+        }
127
+
128
+        try {
129
+            $sessionId = $this->session->getId();
130
+        } catch (SessionNotAvailableException $ex) {
131
+            return $this->getServiceNotAvailableResponse();
132
+        }
133
+        if ($this->userSession->getImpersonatingUserID() !== null) {
134
+            return $this->getServiceNotAvailableResponse();
135
+        }
136
+
137
+        try {
138
+            $sessionToken = $this->tokenProvider->getToken($sessionId);
139
+            $loginName = $sessionToken->getLoginName();
140
+            try {
141
+                $password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
142
+            } catch (PasswordlessTokenException $ex) {
143
+                $password = null;
144
+            }
145
+        } catch (InvalidTokenException $ex) {
146
+            return $this->getServiceNotAvailableResponse();
147
+        }
148
+
149
+        $token = $this->generateRandomDeviceToken();
150
+        $deviceToken = $this->tokenProvider->generateToken($token, $this->uid, $loginName, $password, $name, IToken::PERMANENT_TOKEN);
151
+        $tokenData = $deviceToken->jsonSerialize();
152
+        $tokenData['canDelete'] = true;
153
+        $tokenData['canRename'] = true;
154
+
155
+        $this->publishActivity(Provider::APP_TOKEN_CREATED, $deviceToken->getId(), ['name' => $deviceToken->getName()]);
156
+
157
+        return new JSONResponse([
158
+            'token' => $token,
159
+            'loginName' => $loginName,
160
+            'deviceToken' => $tokenData,
161
+        ]);
162
+    }
163
+
164
+    /**
165
+     * @return JSONResponse
166
+     */
167
+    private function getServiceNotAvailableResponse() {
168
+        $resp = new JSONResponse();
169
+        $resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE);
170
+        return $resp;
171
+    }
172
+
173
+    /**
174
+     * Return a 25 digit device password
175
+     *
176
+     * Example: AbCdE-fGhJk-MnPqR-sTwXy-23456
177
+     *
178
+     * @return string
179
+     */
180
+    private function generateRandomDeviceToken() {
181
+        $groups = [];
182
+        for ($i = 0; $i < 5; $i++) {
183
+            $groups[] = $this->random->generate(5, ISecureRandom::CHAR_HUMAN_READABLE);
184
+        }
185
+        return implode('-', $groups);
186
+    }
187
+
188
+    private function checkAppToken(): bool {
189
+        return $this->session->exists('app_password');
190
+    }
191
+
192
+    /**
193
+     * @NoAdminRequired
194
+     * @NoSubAdminRequired
195
+     *
196
+     * @param int $id
197
+     * @return array|JSONResponse
198
+     */
199
+    public function destroy($id) {
200
+        if ($this->checkAppToken()) {
201
+            return new JSONResponse([], Http::STATUS_BAD_REQUEST);
202
+        }
203
+
204
+        try {
205
+            $token = $this->findTokenByIdAndUser($id);
206
+        } catch (WipeTokenException $e) {
207
+            //continue as we can destroy tokens in wipe
208
+            $token = $e->getToken();
209
+        } catch (InvalidTokenException $e) {
210
+            return new JSONResponse([], Http::STATUS_NOT_FOUND);
211
+        }
212
+
213
+        $this->tokenProvider->invalidateTokenById($this->uid, $token->getId());
214
+        $this->publishActivity(Provider::APP_TOKEN_DELETED, $token->getId(), ['name' => $token->getName()]);
215
+        return [];
216
+    }
217
+
218
+    /**
219
+     * @NoAdminRequired
220
+     * @NoSubAdminRequired
221
+     *
222
+     * @param int $id
223
+     * @param array $scope
224
+     * @param string $name
225
+     * @return array|JSONResponse
226
+     */
227
+    public function update($id, array $scope, string $name) {
228
+        if ($this->checkAppToken()) {
229
+            return new JSONResponse([], Http::STATUS_BAD_REQUEST);
230
+        }
231
+
232
+        try {
233
+            $token = $this->findTokenByIdAndUser($id);
234
+        } catch (InvalidTokenException $e) {
235
+            return new JSONResponse([], Http::STATUS_NOT_FOUND);
236
+        }
237
+
238
+        $currentName = $token->getName();
239
+
240
+        if ($scope !== $token->getScopeAsArray()) {
241
+            $token->setScope(['filesystem' => $scope['filesystem']]);
242
+            $this->publishActivity($scope['filesystem'] ? Provider::APP_TOKEN_FILESYSTEM_GRANTED : Provider::APP_TOKEN_FILESYSTEM_REVOKED, $token->getId(), ['name' => $currentName]);
243
+        }
244
+
245
+        if ($token instanceof INamedToken && $name !== $currentName) {
246
+            $token->setName($name);
247
+            $this->publishActivity(Provider::APP_TOKEN_RENAMED, $token->getId(), ['name' => $currentName, 'newName' => $name]);
248
+        }
249
+
250
+        $this->tokenProvider->updateToken($token);
251
+        return [];
252
+    }
253
+
254
+    /**
255
+     * @param string $subject
256
+     * @param int $id
257
+     * @param array $parameters
258
+     */
259
+    private function publishActivity(string $subject, int $id, array $parameters = []): void {
260
+        $event = $this->activityManager->generateEvent();
261
+        $event->setApp('settings')
262
+            ->setType('security')
263
+            ->setAffectedUser($this->uid)
264
+            ->setAuthor($this->uid)
265
+            ->setSubject($subject, $parameters)
266
+            ->setObject('app_token', $id, 'App Password');
267
+
268
+        try {
269
+            $this->activityManager->publish($event);
270
+        } catch (BadMethodCallException $e) {
271
+            $this->logger->warning('could not publish activity', ['exception' => $e]);
272
+        }
273
+    }
274
+
275
+    /**
276
+     * Find a token by given id and check if uid for current session belongs to this token
277
+     *
278
+     * @param int $id
279
+     * @return IToken
280
+     * @throws InvalidTokenException
281
+     */
282
+    private function findTokenByIdAndUser(int $id): IToken {
283
+        try {
284
+            $token = $this->tokenProvider->getTokenById($id);
285
+        } catch (ExpiredTokenException $e) {
286
+            $token = $e->getToken();
287
+        }
288
+        if ($token->getUID() !== $this->uid) {
289
+            throw new InvalidTokenException('This token does not belong to you!');
290
+        }
291
+        return $token;
292
+    }
293
+
294
+    /**
295
+     * @NoAdminRequired
296
+     * @NoSubAdminRequired
297
+     * @PasswordConfirmationRequired
298
+     *
299
+     * @param int $id
300
+     * @return JSONResponse
301
+     * @throws InvalidTokenException
302
+     * @throws \OC\Authentication\Exceptions\ExpiredTokenException
303
+     */
304
+    public function wipe(int $id): JSONResponse {
305
+        if ($this->checkAppToken()) {
306
+            return new JSONResponse([], Http::STATUS_BAD_REQUEST);
307
+        }
308
+
309
+        try {
310
+            $token = $this->findTokenByIdAndUser($id);
311
+        } catch (InvalidTokenException $e) {
312
+            return new JSONResponse([], Http::STATUS_NOT_FOUND);
313
+        }
314
+
315
+        if (!$this->remoteWipe->markTokenForWipe($token)) {
316
+            return new JSONResponse([], Http::STATUS_BAD_REQUEST);
317
+        }
318
+
319
+        return new JSONResponse([]);
320
+    }
321 321
 }
Please login to merge, or discard this patch.