Passed
Push — dependabot/composer/fortawesom... ( 8ed7ee...6d7a79 )
by
unknown
03:49 queued 22s
created
includes/DataObjects/Request.php 1 patch
Indentation   +326 added lines, -326 removed lines patch added patch discarded remove patch
@@ -21,30 +21,30 @@  discard block
 block discarded – undo
21 21
  */
22 22
 class Request extends DataObject
23 23
 {
24
-    private $email;
25
-    private $ip;
26
-    private $name;
27
-    /** @var string|null */
28
-    private $status = "Open";
29
-    private $date;
30
-    private $emailsent = 0;
31
-    private $emailconfirm;
32
-    /** @var int|null */
33
-    private $reserved = null;
34
-    private $useragent;
35
-    private $forwardedip;
36
-    private $hasComments = false;
37
-    private $hasCommentsResolved = false;
38
-
39
-    /**
40
-     * @throws Exception
41
-     * @throws OptimisticLockFailedException
42
-     */
43
-    public function save()
44
-    {
45
-        if ($this->isNew()) {
46
-            // insert
47
-            $statement = $this->dbObject->prepare(<<<SQL
24
+	private $email;
25
+	private $ip;
26
+	private $name;
27
+	/** @var string|null */
28
+	private $status = "Open";
29
+	private $date;
30
+	private $emailsent = 0;
31
+	private $emailconfirm;
32
+	/** @var int|null */
33
+	private $reserved = null;
34
+	private $useragent;
35
+	private $forwardedip;
36
+	private $hasComments = false;
37
+	private $hasCommentsResolved = false;
38
+
39
+	/**
40
+	 * @throws Exception
41
+	 * @throws OptimisticLockFailedException
42
+	 */
43
+	public function save()
44
+	{
45
+		if ($this->isNew()) {
46
+			// insert
47
+			$statement = $this->dbObject->prepare(<<<SQL
48 48
 INSERT INTO `request` (
49 49
 	email, ip, name, status, date, emailsent,
50 50
 	emailconfirm, reserved, useragent, forwardedip
@@ -53,27 +53,27 @@  discard block
 block discarded – undo
53 53
 	:emailconfirm, :reserved, :useragent, :forwardedip
54 54
 );
55 55
 SQL
56
-            );
57
-            $statement->bindValue(':email', $this->email);
58
-            $statement->bindValue(':ip', $this->ip);
59
-            $statement->bindValue(':name', $this->name);
60
-            $statement->bindValue(':status', $this->status);
61
-            $statement->bindValue(':emailsent', $this->emailsent);
62
-            $statement->bindValue(':emailconfirm', $this->emailconfirm);
63
-            $statement->bindValue(':reserved', $this->reserved);
64
-            $statement->bindValue(':useragent', $this->useragent);
65
-            $statement->bindValue(':forwardedip', $this->forwardedip);
66
-
67
-            if ($statement->execute()) {
68
-                $this->id = (int)$this->dbObject->lastInsertId();
69
-            }
70
-            else {
71
-                throw new Exception($statement->errorInfo());
72
-            }
73
-        }
74
-        else {
75
-            // update
76
-            $statement = $this->dbObject->prepare(<<<SQL
56
+			);
57
+			$statement->bindValue(':email', $this->email);
58
+			$statement->bindValue(':ip', $this->ip);
59
+			$statement->bindValue(':name', $this->name);
60
+			$statement->bindValue(':status', $this->status);
61
+			$statement->bindValue(':emailsent', $this->emailsent);
62
+			$statement->bindValue(':emailconfirm', $this->emailconfirm);
63
+			$statement->bindValue(':reserved', $this->reserved);
64
+			$statement->bindValue(':useragent', $this->useragent);
65
+			$statement->bindValue(':forwardedip', $this->forwardedip);
66
+
67
+			if ($statement->execute()) {
68
+				$this->id = (int)$this->dbObject->lastInsertId();
69
+			}
70
+			else {
71
+				throw new Exception($statement->errorInfo());
72
+			}
73
+		}
74
+		else {
75
+			// update
76
+			$statement = $this->dbObject->prepare(<<<SQL
77 77
 UPDATE `request` SET
78 78
 	status = :status,
79 79
 	emailsent = :emailsent,
@@ -82,147 +82,147 @@  discard block
 block discarded – undo
82 82
 	updateversion = updateversion + 1
83 83
 WHERE id = :id AND updateversion = :updateversion;
84 84
 SQL
85
-            );
86
-
87
-            $statement->bindValue(':id', $this->id);
88
-            $statement->bindValue(':updateversion', $this->updateversion);
89
-
90
-            $statement->bindValue(':status', $this->status);
91
-            $statement->bindValue(':emailsent', $this->emailsent);
92
-            $statement->bindValue(':emailconfirm', $this->emailconfirm);
93
-            $statement->bindValue(':reserved', $this->reserved);
94
-
95
-            if (!$statement->execute()) {
96
-                throw new Exception($statement->errorInfo());
97
-            }
98
-
99
-            if ($statement->rowCount() !== 1) {
100
-                throw new OptimisticLockFailedException();
101
-            }
102
-
103
-            $this->updateversion++;
104
-        }
105
-    }
106
-
107
-    /**
108
-     * @return string
109
-     */
110
-    public function getIp()
111
-    {
112
-        return $this->ip;
113
-    }
114
-
115
-    /**
116
-     * @param string $ip
117
-     */
118
-    public function setIp($ip)
119
-    {
120
-        $this->ip = $ip;
121
-    }
122
-
123
-    /**
124
-     * @return string
125
-     */
126
-    public function getName()
127
-    {
128
-        return $this->name;
129
-    }
130
-
131
-    /**
132
-     * @param string $name
133
-     */
134
-    public function setName($name)
135
-    {
136
-        $this->name = $name;
137
-    }
138
-
139
-    /**
140
-     * @return string
141
-     */
142
-    public function getStatus()
143
-    {
144
-        return $this->status;
145
-    }
146
-
147
-    /**
148
-     * @param string $status
149
-     */
150
-    public function setStatus($status)
151
-    {
152
-        $this->status = $status;
153
-    }
154
-
155
-    /**
156
-     * Returns the time the request was first submitted
157
-     *
158
-     * @return DateTimeImmutable
159
-     */
160
-    public function getDate()
161
-    {
162
-        return new DateTimeImmutable($this->date);
163
-    }
164
-
165
-    /**
166
-     * @return bool
167
-     */
168
-    public function getEmailSent()
169
-    {
170
-        return $this->emailsent == "1";
171
-    }
172
-
173
-    /**
174
-     * @param bool $emailSent
175
-     */
176
-    public function setEmailSent($emailSent)
177
-    {
178
-        $this->emailsent = $emailSent ? 1 : 0;
179
-    }
180
-
181
-    /**
182
-     * @return int|null
183
-     */
184
-    public function getReserved()
185
-    {
186
-        return $this->reserved;
187
-    }
188
-
189
-    /**
190
-     * @param int|null $reserved
191
-     */
192
-    public function setReserved($reserved)
193
-    {
194
-        $this->reserved = $reserved;
195
-    }
196
-
197
-    /**
198
-     * @return string
199
-     */
200
-    public function getUserAgent()
201
-    {
202
-        return $this->useragent;
203
-    }
204
-
205
-    /**
206
-     * @param string $useragent
207
-     */
208
-    public function setUserAgent($useragent)
209
-    {
210
-        $this->useragent = $useragent;
211
-    }
212
-
213
-    /**
214
-     * @return string|null
215
-     */
216
-    public function getForwardedIp()
217
-    {
218
-        return $this->forwardedip;
219
-    }
220
-
221
-    /**
222
-     * @param string|null $forwardedip
223
-     */
224
-    public function setForwardedIp($forwardedip)
225
-    {
85
+			);
86
+
87
+			$statement->bindValue(':id', $this->id);
88
+			$statement->bindValue(':updateversion', $this->updateversion);
89
+
90
+			$statement->bindValue(':status', $this->status);
91
+			$statement->bindValue(':emailsent', $this->emailsent);
92
+			$statement->bindValue(':emailconfirm', $this->emailconfirm);
93
+			$statement->bindValue(':reserved', $this->reserved);
94
+
95
+			if (!$statement->execute()) {
96
+				throw new Exception($statement->errorInfo());
97
+			}
98
+
99
+			if ($statement->rowCount() !== 1) {
100
+				throw new OptimisticLockFailedException();
101
+			}
102
+
103
+			$this->updateversion++;
104
+		}
105
+	}
106
+
107
+	/**
108
+	 * @return string
109
+	 */
110
+	public function getIp()
111
+	{
112
+		return $this->ip;
113
+	}
114
+
115
+	/**
116
+	 * @param string $ip
117
+	 */
118
+	public function setIp($ip)
119
+	{
120
+		$this->ip = $ip;
121
+	}
122
+
123
+	/**
124
+	 * @return string
125
+	 */
126
+	public function getName()
127
+	{
128
+		return $this->name;
129
+	}
130
+
131
+	/**
132
+	 * @param string $name
133
+	 */
134
+	public function setName($name)
135
+	{
136
+		$this->name = $name;
137
+	}
138
+
139
+	/**
140
+	 * @return string
141
+	 */
142
+	public function getStatus()
143
+	{
144
+		return $this->status;
145
+	}
146
+
147
+	/**
148
+	 * @param string $status
149
+	 */
150
+	public function setStatus($status)
151
+	{
152
+		$this->status = $status;
153
+	}
154
+
155
+	/**
156
+	 * Returns the time the request was first submitted
157
+	 *
158
+	 * @return DateTimeImmutable
159
+	 */
160
+	public function getDate()
161
+	{
162
+		return new DateTimeImmutable($this->date);
163
+	}
164
+
165
+	/**
166
+	 * @return bool
167
+	 */
168
+	public function getEmailSent()
169
+	{
170
+		return $this->emailsent == "1";
171
+	}
172
+
173
+	/**
174
+	 * @param bool $emailSent
175
+	 */
176
+	public function setEmailSent($emailSent)
177
+	{
178
+		$this->emailsent = $emailSent ? 1 : 0;
179
+	}
180
+
181
+	/**
182
+	 * @return int|null
183
+	 */
184
+	public function getReserved()
185
+	{
186
+		return $this->reserved;
187
+	}
188
+
189
+	/**
190
+	 * @param int|null $reserved
191
+	 */
192
+	public function setReserved($reserved)
193
+	{
194
+		$this->reserved = $reserved;
195
+	}
196
+
197
+	/**
198
+	 * @return string
199
+	 */
200
+	public function getUserAgent()
201
+	{
202
+		return $this->useragent;
203
+	}
204
+
205
+	/**
206
+	 * @param string $useragent
207
+	 */
208
+	public function setUserAgent($useragent)
209
+	{
210
+		$this->useragent = $useragent;
211
+	}
212
+
213
+	/**
214
+	 * @return string|null
215
+	 */
216
+	public function getForwardedIp()
217
+	{
218
+		return $this->forwardedip;
219
+	}
220
+
221
+	/**
222
+	 * @param string|null $forwardedip
223
+	 */
224
+	public function setForwardedIp($forwardedip)
225
+	{
226 226
 		// Verify that the XFF chain only contains valid IP addresses, and silently discard anything that isn't.
227 227
 
228 228
 		$xff = explode(',', $forwardedip);
@@ -236,76 +236,76 @@  discard block
 block discarded – undo
236 236
 		}
237 237
 
238 238
 		$this->forwardedip = implode(", ", $valid);
239
-    }
240
-
241
-    /**
242
-     * @return bool
243
-     */
244
-    public function hasComments()
245
-    {
246
-        if ($this->hasCommentsResolved) {
247
-            return $this->hasComments;
248
-        }
249
-
250
-        $commentsQuery = $this->dbObject->prepare("SELECT COUNT(*) AS num FROM comment WHERE request = :id;");
251
-        $commentsQuery->bindValue(":id", $this->id);
252
-
253
-        $commentsQuery->execute();
254
-
255
-        $this->hasComments = ($commentsQuery->fetchColumn() != 0);
256
-        $this->hasCommentsResolved = true;
257
-
258
-        return $this->hasComments;
259
-    }
260
-
261
-    /**
262
-     * @return string
263
-     */
264
-    public function getEmailConfirm()
265
-    {
266
-        return $this->emailconfirm;
267
-    }
268
-
269
-    /**
270
-     * @param string $emailconfirm
271
-     */
272
-    public function setEmailConfirm($emailconfirm)
273
-    {
274
-        $this->emailconfirm = $emailconfirm;
275
-    }
276
-
277
-    public function generateEmailConfirmationHash()
278
-    {
279
-        $this->emailconfirm = bin2hex(openssl_random_pseudo_bytes(16));
280
-    }
281
-
282
-    /**
283
-     * @return string|null
284
-     */
285
-    public function getEmail()
286
-    {
287
-        return $this->email;
288
-    }
289
-
290
-    /**
291
-     * @param string|null $email
292
-     */
293
-    public function setEmail($email)
294
-    {
295
-        $this->email = $email;
296
-    }
297
-
298
-    /**
299
-     * @return string
300
-     * @throws Exception
301
-     */
302
-    public function getClosureReason()
303
-    {
304
-        if ($this->status != 'Closed') {
305
-            throw new Exception("Can't get closure reason for open request.");
306
-        }
307
-
308
-        $statement = $this->dbObject->prepare(<<<SQL
239
+	}
240
+
241
+	/**
242
+	 * @return bool
243
+	 */
244
+	public function hasComments()
245
+	{
246
+		if ($this->hasCommentsResolved) {
247
+			return $this->hasComments;
248
+		}
249
+
250
+		$commentsQuery = $this->dbObject->prepare("SELECT COUNT(*) AS num FROM comment WHERE request = :id;");
251
+		$commentsQuery->bindValue(":id", $this->id);
252
+
253
+		$commentsQuery->execute();
254
+
255
+		$this->hasComments = ($commentsQuery->fetchColumn() != 0);
256
+		$this->hasCommentsResolved = true;
257
+
258
+		return $this->hasComments;
259
+	}
260
+
261
+	/**
262
+	 * @return string
263
+	 */
264
+	public function getEmailConfirm()
265
+	{
266
+		return $this->emailconfirm;
267
+	}
268
+
269
+	/**
270
+	 * @param string $emailconfirm
271
+	 */
272
+	public function setEmailConfirm($emailconfirm)
273
+	{
274
+		$this->emailconfirm = $emailconfirm;
275
+	}
276
+
277
+	public function generateEmailConfirmationHash()
278
+	{
279
+		$this->emailconfirm = bin2hex(openssl_random_pseudo_bytes(16));
280
+	}
281
+
282
+	/**
283
+	 * @return string|null
284
+	 */
285
+	public function getEmail()
286
+	{
287
+		return $this->email;
288
+	}
289
+
290
+	/**
291
+	 * @param string|null $email
292
+	 */
293
+	public function setEmail($email)
294
+	{
295
+		$this->email = $email;
296
+	}
297
+
298
+	/**
299
+	 * @return string
300
+	 * @throws Exception
301
+	 */
302
+	public function getClosureReason()
303
+	{
304
+		if ($this->status != 'Closed') {
305
+			throw new Exception("Can't get closure reason for open request.");
306
+		}
307
+
308
+		$statement = $this->dbObject->prepare(<<<SQL
309 309
 SELECT closes.mail_desc
310 310
 FROM log
311 311
 INNER JOIN closes ON log.action = closes.closes
@@ -315,25 +315,25 @@  discard block
 block discarded – undo
315 315
 ORDER BY log.timestamp DESC
316 316
 LIMIT 1;
317 317
 SQL
318
-        );
319
-
320
-        $statement->bindValue(":requestId", $this->id);
321
-        $statement->execute();
322
-        $reason = $statement->fetchColumn();
323
-
324
-        return $reason;
325
-    }
326
-
327
-    /**
328
-     * Gets a value indicating whether the request was closed as created or not.
329
-     */
330
-    public function getWasCreated()
331
-    {
332
-        if ($this->status != 'Closed') {
333
-            throw new Exception("Can't get closure reason for open request.");
334
-        }
318
+		);
319
+
320
+		$statement->bindValue(":requestId", $this->id);
321
+		$statement->execute();
322
+		$reason = $statement->fetchColumn();
323
+
324
+		return $reason;
325
+	}
326
+
327
+	/**
328
+	 * Gets a value indicating whether the request was closed as created or not.
329
+	 */
330
+	public function getWasCreated()
331
+	{
332
+		if ($this->status != 'Closed') {
333
+			throw new Exception("Can't get closure reason for open request.");
334
+		}
335 335
 
336
-        $statement = $this->dbObject->prepare(<<<SQL
336
+		$statement = $this->dbObject->prepare(<<<SQL
337 337
 SELECT emailtemplate.oncreated, log.action
338 338
 FROM log
339 339
 LEFT JOIN emailtemplate ON CONCAT('Closed ', emailtemplate.id) = log.action
@@ -343,60 +343,60 @@  discard block
 block discarded – undo
343 343
 ORDER BY log.timestamp DESC
344 344
 LIMIT 1;
345 345
 SQL
346
-        );
347
-
348
-        $statement->bindValue(":requestId", $this->id);
349
-        $statement->execute();
350
-        $onCreated = $statement->fetchColumn(0);
351
-        $logAction = $statement->fetchColumn(1);
352
-        $statement->closeCursor();
353
-
354
-        if ($onCreated === null) {
355
-            return $logAction === "Closed custom-y";
356
-        }
357
-
358
-        return (bool)$onCreated;
359
-    }
360
-
361
-    /**
362
-     * @return DateTime
363
-     */
364
-    public function getClosureDate()
365
-    {
366
-        $logQuery = $this->dbObject->prepare(<<<SQL
346
+		);
347
+
348
+		$statement->bindValue(":requestId", $this->id);
349
+		$statement->execute();
350
+		$onCreated = $statement->fetchColumn(0);
351
+		$logAction = $statement->fetchColumn(1);
352
+		$statement->closeCursor();
353
+
354
+		if ($onCreated === null) {
355
+			return $logAction === "Closed custom-y";
356
+		}
357
+
358
+		return (bool)$onCreated;
359
+	}
360
+
361
+	/**
362
+	 * @return DateTime
363
+	 */
364
+	public function getClosureDate()
365
+	{
366
+		$logQuery = $this->dbObject->prepare(<<<SQL
367 367
 SELECT timestamp FROM log
368 368
 WHERE objectid = :request AND objecttype = 'Request' AND action LIKE 'Closed%'
369 369
 ORDER BY timestamp DESC LIMIT 1;
370 370
 SQL
371
-        );
372
-        $logQuery->bindValue(":request", $this->getId());
373
-        $logQuery->execute();
374
-        $logTime = $logQuery->fetchColumn();
375
-        $logQuery->closeCursor();
376
-
377
-        return new DateTime($logTime);
378
-    }
379
-
380
-    /**
381
-     * Returns a hash based on data within this request which can be generated easily from the data to be used to reveal
382
-     * data to unauthorised* users.
383
-     *
384
-     * *:Not tool admins, check users, or the reserving user.
385
-     *
386
-     * @return string
387
-     *
388
-     * @todo future work to make invalidation better. Possibly move to the database and invalidate on relevant events?
389
-     *       Maybe depend on the last logged action timestamp?
390
-     */
391
-    public function getRevealHash()
392
-    {
393
-        $data = $this->id         // unique per request
394
-            . '|' . $this->ip           // }
395
-            . '|' . $this->forwardedip  // } private data not known to those without access
396
-            . '|' . $this->useragent    // }
397
-            . '|' . $this->email        // }
398
-            . '|' . $this->status;      // to rudimentarily invalidate the token on status change
399
-
400
-        return hash('sha256', $data);
401
-    }
371
+		);
372
+		$logQuery->bindValue(":request", $this->getId());
373
+		$logQuery->execute();
374
+		$logTime = $logQuery->fetchColumn();
375
+		$logQuery->closeCursor();
376
+
377
+		return new DateTime($logTime);
378
+	}
379
+
380
+	/**
381
+	 * Returns a hash based on data within this request which can be generated easily from the data to be used to reveal
382
+	 * data to unauthorised* users.
383
+	 *
384
+	 * *:Not tool admins, check users, or the reserving user.
385
+	 *
386
+	 * @return string
387
+	 *
388
+	 * @todo future work to make invalidation better. Possibly move to the database and invalidate on relevant events?
389
+	 *       Maybe depend on the last logged action timestamp?
390
+	 */
391
+	public function getRevealHash()
392
+	{
393
+		$data = $this->id         // unique per request
394
+			. '|' . $this->ip           // }
395
+			. '|' . $this->forwardedip  // } private data not known to those without access
396
+			. '|' . $this->useragent    // }
397
+			. '|' . $this->email        // }
398
+			. '|' . $this->status;      // to rudimentarily invalidate the token on status change
399
+
400
+		return hash('sha256', $data);
401
+	}
402 402
 }
Please login to merge, or discard this patch.
includes/DataObjects/Comment.php 2 patches
Indentation   +157 added lines, -157 removed lines patch added patch discarded remove patch
@@ -20,171 +20,171 @@
 block discarded – undo
20 20
  */
21 21
 class Comment extends DataObject
22 22
 {
23
-    private $time;
24
-    private $user;
25
-    private $comment;
26
-    private $visibility = "user";
27
-    private $request;
28
-
29
-    /**
30
-     * Retrieves all comments for a request, optionally filtered
31
-     *
32
-     * @param integer     $id      Request ID to search by
33
-     * @param PdoDatabase $database
34
-     * @param bool        $showAll True to show all comments, False to show only unprotected comments, and protected
35
-     *                             comments visible to $userId
36
-     * @param null|int    $userId  User to filter by
37
-     *
38
-     * @return Comment[]
39
-     */
40
-    public static function getForRequest($id, PdoDatabase $database, $showAll = false, $userId = null)
41
-    {
42
-        if ($showAll) {
43
-            $statement = $database->prepare('SELECT * FROM comment WHERE request = :target;');
44
-        }
45
-        else {
46
-            $statement = $database->prepare(<<<SQL
23
+	private $time;
24
+	private $user;
25
+	private $comment;
26
+	private $visibility = "user";
27
+	private $request;
28
+
29
+	/**
30
+	 * Retrieves all comments for a request, optionally filtered
31
+	 *
32
+	 * @param integer     $id      Request ID to search by
33
+	 * @param PdoDatabase $database
34
+	 * @param bool        $showAll True to show all comments, False to show only unprotected comments, and protected
35
+	 *                             comments visible to $userId
36
+	 * @param null|int    $userId  User to filter by
37
+	 *
38
+	 * @return Comment[]
39
+	 */
40
+	public static function getForRequest($id, PdoDatabase $database, $showAll = false, $userId = null)
41
+	{
42
+		if ($showAll) {
43
+			$statement = $database->prepare('SELECT * FROM comment WHERE request = :target;');
44
+		}
45
+		else {
46
+			$statement = $database->prepare(<<<SQL
47 47
 SELECT * FROM comment
48 48
 WHERE request = :target AND (visibility = 'user' OR visibility = 'requester' OR user = :userid);
49 49
 SQL
50
-            );
51
-            $statement->bindValue(':userid', $userId);
52
-        }
53
-
54
-        $statement->bindValue(':target', $id);
55
-
56
-        $statement->execute();
57
-
58
-        $result = array();
59
-        /** @var Comment $v */
60
-        foreach ($statement->fetchAll(PDO::FETCH_CLASS, get_called_class()) as $v) {
61
-            $v->setDatabase($database);
62
-            $result[] = $v;
63
-        }
64
-
65
-        return $result;
66
-    }
67
-
68
-    /**
69
-     * @throws Exception
70
-     */
71
-    public function save()
72
-    {
73
-        if ($this->isNew()) {
74
-            // insert
75
-            $statement = $this->dbObject->prepare(<<<SQL
50
+			);
51
+			$statement->bindValue(':userid', $userId);
52
+		}
53
+
54
+		$statement->bindValue(':target', $id);
55
+
56
+		$statement->execute();
57
+
58
+		$result = array();
59
+		/** @var Comment $v */
60
+		foreach ($statement->fetchAll(PDO::FETCH_CLASS, get_called_class()) as $v) {
61
+			$v->setDatabase($database);
62
+			$result[] = $v;
63
+		}
64
+
65
+		return $result;
66
+	}
67
+
68
+	/**
69
+	 * @throws Exception
70
+	 */
71
+	public function save()
72
+	{
73
+		if ($this->isNew()) {
74
+			// insert
75
+			$statement = $this->dbObject->prepare(<<<SQL
76 76
 INSERT INTO comment ( time, user, comment, visibility, request )
77 77
 VALUES ( CURRENT_TIMESTAMP(), :user, :comment, :visibility, :request );
78 78
 SQL
79
-            );
80
-            $statement->bindValue(":user", $this->user);
81
-            $statement->bindValue(":comment", $this->comment);
82
-            $statement->bindValue(":visibility", $this->visibility);
83
-            $statement->bindValue(":request", $this->request);
84
-
85
-            if ($statement->execute()) {
86
-                $this->id = (int)$this->dbObject->lastInsertId();
87
-            }
88
-            else {
89
-                throw new Exception($statement->errorInfo());
90
-            }
91
-        }
92
-        else {
93
-            // update
94
-            $statement = $this->dbObject->prepare(<<<SQL
79
+			);
80
+			$statement->bindValue(":user", $this->user);
81
+			$statement->bindValue(":comment", $this->comment);
82
+			$statement->bindValue(":visibility", $this->visibility);
83
+			$statement->bindValue(":request", $this->request);
84
+
85
+			if ($statement->execute()) {
86
+				$this->id = (int)$this->dbObject->lastInsertId();
87
+			}
88
+			else {
89
+				throw new Exception($statement->errorInfo());
90
+			}
91
+		}
92
+		else {
93
+			// update
94
+			$statement = $this->dbObject->prepare(<<<SQL
95 95
 UPDATE comment
96 96
 SET comment = :comment, visibility = :visibility, updateversion = updateversion + 1
97 97
 WHERE id = :id AND updateversion = :updateversion;
98 98
 SQL
99
-            );
100
-
101
-            $statement->bindValue(':id', $this->id);
102
-            $statement->bindValue(':updateversion', $this->updateversion);
103
-
104
-            $statement->bindValue(':comment', $this->comment);
105
-            $statement->bindValue(':visibility', $this->visibility);
106
-
107
-            if (!$statement->execute()) {
108
-                throw new Exception($statement->errorInfo());
109
-            }
110
-
111
-            if ($statement->rowCount() !== 1) {
112
-                throw new OptimisticLockFailedException();
113
-            }
114
-
115
-            $this->updateversion++;
116
-        }
117
-    }
118
-
119
-    /**
120
-     * @return DateTimeImmutable
121
-     */
122
-    public function getTime()
123
-    {
124
-        return new DateTimeImmutable($this->time);
125
-    }
126
-
127
-    /**
128
-     * @return int
129
-     */
130
-    public function getUser()
131
-    {
132
-        return $this->user;
133
-    }
134
-
135
-    /**
136
-     * @param int $user
137
-     */
138
-    public function setUser($user)
139
-    {
140
-        $this->user = $user;
141
-    }
142
-
143
-    /**
144
-     * @return string
145
-     */
146
-    public function getComment()
147
-    {
148
-        return $this->comment;
149
-    }
150
-
151
-    /**
152
-     * @param string $comment
153
-     */
154
-    public function setComment($comment)
155
-    {
156
-        $this->comment = $comment;
157
-    }
158
-
159
-    /**
160
-     * @return string
161
-     */
162
-    public function getVisibility()
163
-    {
164
-        return $this->visibility;
165
-    }
166
-
167
-    /**
168
-     * @param string $visibility
169
-     */
170
-    public function setVisibility($visibility)
171
-    {
172
-        $this->visibility = $visibility;
173
-    }
174
-
175
-    /**
176
-     * @return int
177
-     */
178
-    public function getRequest()
179
-    {
180
-        return $this->request;
181
-    }
182
-
183
-    /**
184
-     * @param int $request
185
-     */
186
-    public function setRequest($request)
187
-    {
188
-        $this->request = $request;
189
-    }
99
+			);
100
+
101
+			$statement->bindValue(':id', $this->id);
102
+			$statement->bindValue(':updateversion', $this->updateversion);
103
+
104
+			$statement->bindValue(':comment', $this->comment);
105
+			$statement->bindValue(':visibility', $this->visibility);
106
+
107
+			if (!$statement->execute()) {
108
+				throw new Exception($statement->errorInfo());
109
+			}
110
+
111
+			if ($statement->rowCount() !== 1) {
112
+				throw new OptimisticLockFailedException();
113
+			}
114
+
115
+			$this->updateversion++;
116
+		}
117
+	}
118
+
119
+	/**
120
+	 * @return DateTimeImmutable
121
+	 */
122
+	public function getTime()
123
+	{
124
+		return new DateTimeImmutable($this->time);
125
+	}
126
+
127
+	/**
128
+	 * @return int
129
+	 */
130
+	public function getUser()
131
+	{
132
+		return $this->user;
133
+	}
134
+
135
+	/**
136
+	 * @param int $user
137
+	 */
138
+	public function setUser($user)
139
+	{
140
+		$this->user = $user;
141
+	}
142
+
143
+	/**
144
+	 * @return string
145
+	 */
146
+	public function getComment()
147
+	{
148
+		return $this->comment;
149
+	}
150
+
151
+	/**
152
+	 * @param string $comment
153
+	 */
154
+	public function setComment($comment)
155
+	{
156
+		$this->comment = $comment;
157
+	}
158
+
159
+	/**
160
+	 * @return string
161
+	 */
162
+	public function getVisibility()
163
+	{
164
+		return $this->visibility;
165
+	}
166
+
167
+	/**
168
+	 * @param string $visibility
169
+	 */
170
+	public function setVisibility($visibility)
171
+	{
172
+		$this->visibility = $visibility;
173
+	}
174
+
175
+	/**
176
+	 * @return int
177
+	 */
178
+	public function getRequest()
179
+	{
180
+		return $this->request;
181
+	}
182
+
183
+	/**
184
+	 * @param int $request
185
+	 */
186
+	public function setRequest($request)
187
+	{
188
+		$this->request = $request;
189
+	}
190 190
 }
Please login to merge, or discard this patch.
Braces   +3 added lines, -6 removed lines patch added patch discarded remove patch
@@ -41,8 +41,7 @@  discard block
 block discarded – undo
41 41
     {
42 42
         if ($showAll) {
43 43
             $statement = $database->prepare('SELECT * FROM comment WHERE request = :target;');
44
-        }
45
-        else {
44
+        } else {
46 45
             $statement = $database->prepare(<<<SQL
47 46
 SELECT * FROM comment
48 47
 WHERE request = :target AND (visibility = 'user' OR visibility = 'requester' OR user = :userid);
@@ -84,12 +83,10 @@  discard block
 block discarded – undo
84 83
 
85 84
             if ($statement->execute()) {
86 85
                 $this->id = (int)$this->dbObject->lastInsertId();
87
-            }
88
-            else {
86
+            } else {
89 87
                 throw new Exception($statement->errorInfo());
90 88
             }
91
-        }
92
-        else {
89
+        } else {
93 90
             // update
94 91
             $statement = $this->dbObject->prepare(<<<SQL
95 92
 UPDATE comment
Please login to merge, or discard this patch.
includes/Pages/Request/PageRequestAccount.php 2 patches
Indentation   +184 added lines, -184 removed lines patch added patch discarded remove patch
@@ -21,188 +21,188 @@
 block discarded – undo
21 21
 
22 22
 class PageRequestAccount extends PublicInterfacePageBase
23 23
 {
24
-    /**
25
-     * Main function for this page, when no specific actions are called.
26
-     * @return void
27
-     * @throws OptimisticLockFailedException
28
-     * @throws Exception
29
-     */
30
-    protected function main()
31
-    {
32
-        // dual mode page
33
-        if (WebRequest::wasPosted()) {
34
-            $request = $this->createNewRequest();
35
-            $comment = $this->createComment();
36
-
37
-            $validationErrors = $this->validateRequest($request);
38
-
39
-            if (count($validationErrors) > 0) {
40
-                foreach ($validationErrors as $validationError) {
41
-                    SessionAlert::error($validationError->getErrorMessage());
42
-                }
43
-
44
-                // Preserve the data after an error
45
-                WebRequest::setSessionContext('accountReq',
46
-                    array(
47
-                        'username' => WebRequest::postString('name'),
48
-                        'email'    => WebRequest::postEmail('email'),
49
-                        'comments' => WebRequest::postString('comments'),
50
-                    )
51
-                );
52
-
53
-                // Validation error, bomb out early.
54
-                $this->redirect();
55
-
56
-                return;
57
-            }
58
-
59
-            // actually save the request to the database
60
-            if ($this->getSiteConfiguration()->getEmailConfirmationEnabled()) {
61
-                $this->saveAsEmailConfirmation($request, $comment);
62
-            }
63
-            else {
64
-                $this->saveWithoutEmailConfirmation($request, $comment);
65
-            }
66
-        }
67
-        else {
68
-            // set the form values from the session context
69
-            $context = WebRequest::getSessionContext('accountReq');
70
-            if ($context !== null && is_array($context)) {
71
-                $this->assign('username', $context['username']);
72
-                $this->assign('email', $context['email']);
73
-                $this->assign('comments', $context['comments']);
74
-            }
75
-
76
-            // Clear it for a refresh
77
-            WebRequest::setSessionContext('accountReq', null);
78
-
79
-            $this->setTemplate('request/request-form.tpl');
80
-        }
81
-    }
82
-
83
-    /**
84
-     * @return Request
85
-     */
86
-    protected function createNewRequest()
87
-    {
88
-        $request = new Request();
89
-        $request->setDatabase($this->getDatabase());
90
-
91
-        $request->setName(WebRequest::postString('name'));
92
-        $request->setEmail(WebRequest::postEmail('email'));
93
-
94
-        $request->setIp(WebRequest::remoteAddress());
95
-        $request->setForwardedIp(WebRequest::forwardedAddress());
96
-
97
-        $request->setUserAgent(WebRequest::userAgent());
98
-
99
-        return $request;
100
-    }
101
-
102
-    /**
103
-     * @return Comment|null
104
-     */
105
-    private function createComment()
106
-    {
107
-        $commentText = WebRequest::postString('comments');
108
-        if ($commentText === null || trim($commentText) === '') {
109
-            return null;
110
-        }
111
-
112
-        $comment = new Comment();
113
-        $comment->setDatabase($this->getDatabase());
114
-
115
-        $comment->setVisibility('requester');
116
-        $comment->setUser(null);
117
-        $comment->setComment($commentText);
118
-
119
-        return $comment;
120
-    }
121
-
122
-    /**
123
-     * @param Request $request
124
-     *
125
-     * @return ValidationError[]
126
-     */
127
-    protected function validateRequest($request)
128
-    {
129
-        $validationHelper = new RequestValidationHelper(
130
-            new BanHelper($this->getDatabase()),
131
-            $request,
132
-            WebRequest::postEmail('emailconfirm'),
133
-            $this->getDatabase(),
134
-            $this->getAntiSpoofProvider(),
135
-            $this->getXffTrustProvider(),
136
-            $this->getHttpHelper(),
137
-            $this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
138
-            $this->getSiteConfiguration()->getTitleBlacklistEnabled(),
139
-            $this->getTorExitProvider());
140
-
141
-        // These are arrays of ValidationError.
142
-        $nameValidation = $validationHelper->validateName();
143
-        $emailValidation = $validationHelper->validateEmail();
144
-        $otherValidation = $validationHelper->validateOther();
145
-
146
-        $validationErrors = array_merge($nameValidation, $emailValidation, $otherValidation);
147
-
148
-        return $validationErrors;
149
-    }
150
-
151
-    /**
152
-     * @param Request      $request
153
-     *
154
-     * @param Comment|null $comment
155
-     *
156
-     * @throws OptimisticLockFailedException
157
-     * @throws Exception
158
-     */
159
-    protected function saveAsEmailConfirmation(Request $request, $comment)
160
-    {
161
-        $request->generateEmailConfirmationHash();
162
-        $request->save();
163
-
164
-        if ($comment !== null) {
165
-            $comment->setRequest($request->getId());
166
-            $comment->save();
167
-        }
168
-
169
-        $trustedIp = $this->getXffTrustProvider()->getTrustedClientIp(
170
-            $request->getIp(),
171
-            $request->getForwardedIp());
172
-
173
-        $this->assign("ip", $trustedIp);
174
-        $this->assign("id", $request->getId());
175
-        $this->assign("hash", $request->getEmailConfirm());
176
-
177
-        // Sends the confirmation email to the user.
178
-        $this->getEmailHelper()->sendMail(
179
-            $request->getEmail(),
180
-            "[ACC #{$request->getId()}] English Wikipedia Account Request",
181
-            $this->fetchTemplate('request/confirmation-mail.tpl'));
182
-
183
-        $this->redirect('emailConfirmationRequired');
184
-    }
185
-
186
-    /**
187
-     * @param Request      $request
188
-     *
189
-     * @param Comment|null $comment
190
-     *
191
-     * @throws OptimisticLockFailedException
192
-     * @throws Exception
193
-     */
194
-    protected function saveWithoutEmailConfirmation(Request $request, $comment)
195
-    {
196
-        $request->setEmailConfirm(0); // fixme Since it can't be null
197
-        $request->save();
198
-
199
-        if ($comment !== null) {
200
-            $comment->setRequest($request->getId());
201
-            $comment->save();
202
-        }
203
-
204
-        $this->getNotificationHelper()->requestReceived($request);
205
-
206
-        $this->redirect('requestSubmitted');
207
-    }
24
+	/**
25
+	 * Main function for this page, when no specific actions are called.
26
+	 * @return void
27
+	 * @throws OptimisticLockFailedException
28
+	 * @throws Exception
29
+	 */
30
+	protected function main()
31
+	{
32
+		// dual mode page
33
+		if (WebRequest::wasPosted()) {
34
+			$request = $this->createNewRequest();
35
+			$comment = $this->createComment();
36
+
37
+			$validationErrors = $this->validateRequest($request);
38
+
39
+			if (count($validationErrors) > 0) {
40
+				foreach ($validationErrors as $validationError) {
41
+					SessionAlert::error($validationError->getErrorMessage());
42
+				}
43
+
44
+				// Preserve the data after an error
45
+				WebRequest::setSessionContext('accountReq',
46
+					array(
47
+						'username' => WebRequest::postString('name'),
48
+						'email'    => WebRequest::postEmail('email'),
49
+						'comments' => WebRequest::postString('comments'),
50
+					)
51
+				);
52
+
53
+				// Validation error, bomb out early.
54
+				$this->redirect();
55
+
56
+				return;
57
+			}
58
+
59
+			// actually save the request to the database
60
+			if ($this->getSiteConfiguration()->getEmailConfirmationEnabled()) {
61
+				$this->saveAsEmailConfirmation($request, $comment);
62
+			}
63
+			else {
64
+				$this->saveWithoutEmailConfirmation($request, $comment);
65
+			}
66
+		}
67
+		else {
68
+			// set the form values from the session context
69
+			$context = WebRequest::getSessionContext('accountReq');
70
+			if ($context !== null && is_array($context)) {
71
+				$this->assign('username', $context['username']);
72
+				$this->assign('email', $context['email']);
73
+				$this->assign('comments', $context['comments']);
74
+			}
75
+
76
+			// Clear it for a refresh
77
+			WebRequest::setSessionContext('accountReq', null);
78
+
79
+			$this->setTemplate('request/request-form.tpl');
80
+		}
81
+	}
82
+
83
+	/**
84
+	 * @return Request
85
+	 */
86
+	protected function createNewRequest()
87
+	{
88
+		$request = new Request();
89
+		$request->setDatabase($this->getDatabase());
90
+
91
+		$request->setName(WebRequest::postString('name'));
92
+		$request->setEmail(WebRequest::postEmail('email'));
93
+
94
+		$request->setIp(WebRequest::remoteAddress());
95
+		$request->setForwardedIp(WebRequest::forwardedAddress());
96
+
97
+		$request->setUserAgent(WebRequest::userAgent());
98
+
99
+		return $request;
100
+	}
101
+
102
+	/**
103
+	 * @return Comment|null
104
+	 */
105
+	private function createComment()
106
+	{
107
+		$commentText = WebRequest::postString('comments');
108
+		if ($commentText === null || trim($commentText) === '') {
109
+			return null;
110
+		}
111
+
112
+		$comment = new Comment();
113
+		$comment->setDatabase($this->getDatabase());
114
+
115
+		$comment->setVisibility('requester');
116
+		$comment->setUser(null);
117
+		$comment->setComment($commentText);
118
+
119
+		return $comment;
120
+	}
121
+
122
+	/**
123
+	 * @param Request $request
124
+	 *
125
+	 * @return ValidationError[]
126
+	 */
127
+	protected function validateRequest($request)
128
+	{
129
+		$validationHelper = new RequestValidationHelper(
130
+			new BanHelper($this->getDatabase()),
131
+			$request,
132
+			WebRequest::postEmail('emailconfirm'),
133
+			$this->getDatabase(),
134
+			$this->getAntiSpoofProvider(),
135
+			$this->getXffTrustProvider(),
136
+			$this->getHttpHelper(),
137
+			$this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
138
+			$this->getSiteConfiguration()->getTitleBlacklistEnabled(),
139
+			$this->getTorExitProvider());
140
+
141
+		// These are arrays of ValidationError.
142
+		$nameValidation = $validationHelper->validateName();
143
+		$emailValidation = $validationHelper->validateEmail();
144
+		$otherValidation = $validationHelper->validateOther();
145
+
146
+		$validationErrors = array_merge($nameValidation, $emailValidation, $otherValidation);
147
+
148
+		return $validationErrors;
149
+	}
150
+
151
+	/**
152
+	 * @param Request      $request
153
+	 *
154
+	 * @param Comment|null $comment
155
+	 *
156
+	 * @throws OptimisticLockFailedException
157
+	 * @throws Exception
158
+	 */
159
+	protected function saveAsEmailConfirmation(Request $request, $comment)
160
+	{
161
+		$request->generateEmailConfirmationHash();
162
+		$request->save();
163
+
164
+		if ($comment !== null) {
165
+			$comment->setRequest($request->getId());
166
+			$comment->save();
167
+		}
168
+
169
+		$trustedIp = $this->getXffTrustProvider()->getTrustedClientIp(
170
+			$request->getIp(),
171
+			$request->getForwardedIp());
172
+
173
+		$this->assign("ip", $trustedIp);
174
+		$this->assign("id", $request->getId());
175
+		$this->assign("hash", $request->getEmailConfirm());
176
+
177
+		// Sends the confirmation email to the user.
178
+		$this->getEmailHelper()->sendMail(
179
+			$request->getEmail(),
180
+			"[ACC #{$request->getId()}] English Wikipedia Account Request",
181
+			$this->fetchTemplate('request/confirmation-mail.tpl'));
182
+
183
+		$this->redirect('emailConfirmationRequired');
184
+	}
185
+
186
+	/**
187
+	 * @param Request      $request
188
+	 *
189
+	 * @param Comment|null $comment
190
+	 *
191
+	 * @throws OptimisticLockFailedException
192
+	 * @throws Exception
193
+	 */
194
+	protected function saveWithoutEmailConfirmation(Request $request, $comment)
195
+	{
196
+		$request->setEmailConfirm(0); // fixme Since it can't be null
197
+		$request->save();
198
+
199
+		if ($comment !== null) {
200
+			$comment->setRequest($request->getId());
201
+			$comment->save();
202
+		}
203
+
204
+		$this->getNotificationHelper()->requestReceived($request);
205
+
206
+		$this->redirect('requestSubmitted');
207
+	}
208 208
 }
209 209
\ No newline at end of file
Please login to merge, or discard this patch.
Braces   +2 added lines, -4 removed lines patch added patch discarded remove patch
@@ -59,12 +59,10 @@
 block discarded – undo
59 59
             // actually save the request to the database
60 60
             if ($this->getSiteConfiguration()->getEmailConfirmationEnabled()) {
61 61
                 $this->saveAsEmailConfirmation($request, $comment);
62
-            }
63
-            else {
62
+            } else {
64 63
                 $this->saveWithoutEmailConfirmation($request, $comment);
65 64
             }
66
-        }
67
-        else {
65
+        } else {
68 66
             // set the form values from the session context
69 67
             $context = WebRequest::getSessionContext('accountReq');
70 68
             if ($context !== null && is_array($context)) {
Please login to merge, or discard this patch.
includes/ConsoleTasks/OldRequestCleanupTask.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -12,9 +12,9 @@  discard block
 block discarded – undo
12 12
 
13 13
 class OldRequestCleanupTask extends ConsoleTaskBase
14 14
 {
15
-    public function execute()
16
-    {
17
-        $statement = $this->getDatabase()->prepare(<<<SQL
15
+	public function execute()
16
+	{
17
+		$statement = $this->getDatabase()->prepare(<<<SQL
18 18
             DELETE FROM request
19 19
             WHERE
20 20
                 request.date < DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL :expiry DAY)
@@ -22,10 +22,10 @@  discard block
 block discarded – undo
22 22
                 AND request.emailconfirm != ''
23 23
                 AND NOT exists (SELECT 1 FROM comment c WHERE c.request = request.id)
24 24
 SQL
25
-        );
25
+		);
26 26
 
27
-        $expiryTime = $this->getSiteConfiguration()->getEmailConfirmationExpiryDays();
28
-        $statement->bindValue(':expiry', $expiryTime);
29
-        $statement->execute();
30
-    }
27
+		$expiryTime = $this->getSiteConfiguration()->getEmailConfirmationExpiryDays();
28
+		$statement->bindValue(':expiry', $expiryTime);
29
+		$statement->execute();
30
+	}
31 31
 }
32 32
\ No newline at end of file
Please login to merge, or discard this patch.
includes/ConsoleTasks/RefreshOAuthDataTask.php 1 patch
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -18,53 +18,53 @@
 block discarded – undo
18 18
 
19 19
 class RefreshOAuthDataTask extends ConsoleTaskBase
20 20
 {
21
-    public function execute()
22
-    {
23
-        $database = $this->getDatabase();
21
+	public function execute()
22
+	{
23
+		$database = $this->getDatabase();
24 24
 
25
-        $idList = $database
26
-            ->query('SELECT user FROM oauthtoken WHERE type = \'access\' AND expiry IS NULL')
27
-            ->fetchAll(PDO::FETCH_COLUMN);
25
+		$idList = $database
26
+			->query('SELECT user FROM oauthtoken WHERE type = \'access\' AND expiry IS NULL')
27
+			->fetchAll(PDO::FETCH_COLUMN);
28 28
 
29
-        if (count($idList) > 0) {
30
-            /** @var User[] $users */
31
-            $users = UserSearchHelper::get($database)->inIds($idList)->fetch();
29
+		if (count($idList) > 0) {
30
+			/** @var User[] $users */
31
+			$users = UserSearchHelper::get($database)->inIds($idList)->fetch();
32 32
 
33
-            $expiredStatement = $database
34
-                ->prepare('UPDATE oauthtoken SET expiry = CURRENT_TIMESTAMP() WHERE user = :u AND type = \'access\'');
33
+			$expiredStatement = $database
34
+				->prepare('UPDATE oauthtoken SET expiry = CURRENT_TIMESTAMP() WHERE user = :u AND type = \'access\'');
35 35
 
36
-            foreach ($users as $u) {
37
-                try {
38
-                    $database->beginTransaction();
36
+			foreach ($users as $u) {
37
+				try {
38
+					$database->beginTransaction();
39 39
 
40
-                    $oauth = new OAuthUserHelper($u, $database, $this->getOAuthProtocolHelper(),
41
-                        $this->getSiteConfiguration());
40
+					$oauth = new OAuthUserHelper($u, $database, $this->getOAuthProtocolHelper(),
41
+						$this->getSiteConfiguration());
42 42
 
43
-                    try {
44
-                        $oauth->refreshIdentity();
45
-                    }
46
-                    catch (OAuthException $ex) {
47
-                        $expiredStatement->execute(array(':u' => $u->getId()));
48
-                    }
43
+					try {
44
+						$oauth->refreshIdentity();
45
+					}
46
+					catch (OAuthException $ex) {
47
+						$expiredStatement->execute(array(':u' => $u->getId()));
48
+					}
49 49
 
50
-                    $database->commit();
51
-                }
52
-                catch (Exception $ex) {
53
-                    $database->rollBack();
50
+					$database->commit();
51
+				}
52
+				catch (Exception $ex) {
53
+					$database->rollBack();
54 54
 
55
-                    printf("\n\nFailed updating OAuth data for %s\n", $u->getUsername());
56
-                    printf($ex->getMessage());
57
-                }
58
-                finally {
59
-                    if ($database->hasActiveTransaction()) {
60
-                        $database->rollBack();
61
-                    }
62
-                }
63
-            }
64
-        }
55
+					printf("\n\nFailed updating OAuth data for %s\n", $u->getUsername());
56
+					printf($ex->getMessage());
57
+				}
58
+				finally {
59
+					if ($database->hasActiveTransaction()) {
60
+						$database->rollBack();
61
+					}
62
+				}
63
+			}
64
+		}
65 65
 
66
-        $database->beginTransaction();
67
-        $database->exec('DELETE FROM oauthtoken WHERE expiry IS NOT NULL AND expiry < NOW() AND type = \'request\'');
68
-        $database->commit();
69
-    }
66
+		$database->beginTransaction();
67
+		$database->exec('DELETE FROM oauthtoken WHERE expiry IS NOT NULL AND expiry < NOW() AND type = \'request\'');
68
+		$database->commit();
69
+	}
70 70
 }
71 71
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Providers/XffTrustProvider.php 1 patch
Indentation   +152 added lines, -152 removed lines patch added patch discarded remove patch
@@ -22,156 +22,156 @@
 block discarded – undo
22 22
  */
23 23
 class XffTrustProvider implements IXffTrustProvider
24 24
 {
25
-    /**
26
-     * Array of IP addresses which are TRUSTED proxies
27
-     * @var string[]
28
-     */
29
-    private $trustedCache;
30
-    /**
31
-     * Array of IP addresses which are UNTRUSTED proxies
32
-     * @var string[]
33
-     */
34
-    private $untrustedCache = array();
35
-    /** @var PDOStatement */
36
-    private $trustedQuery;
37
-    /**
38
-     * @var PdoDatabase
39
-     */
40
-    private $database;
41
-
42
-    /**
43
-     * Creates a new instance of the trust provider
44
-     *
45
-     * @param string[]    $squidIpList List of IP addresses to pre-approve
46
-     * @param PdoDatabase $database
47
-     */
48
-    public function __construct($squidIpList, PdoDatabase $database)
49
-    {
50
-        $this->trustedCache = $squidIpList;
51
-        $this->database = $database;
52
-    }
53
-
54
-    /**
55
-     * Returns a value if the IP address is a trusted proxy
56
-     *
57
-     * @param string $ip
58
-     *
59
-     * @return bool
60
-     */
61
-    public function isTrusted($ip)
62
-    {
63
-        if (in_array($ip, $this->trustedCache)) {
64
-            return true;
65
-        }
66
-
67
-        if (in_array($ip, $this->untrustedCache)) {
68
-            return false;
69
-        }
70
-
71
-        if ($this->trustedQuery === null) {
72
-            $query = "SELECT COUNT(id) FROM xfftrustcache WHERE ip = :ip;";
73
-            $this->trustedQuery = $this->database->prepare($query);
74
-        }
75
-
76
-        $this->trustedQuery->execute(array(":ip" => $ip));
77
-        $result = $this->trustedQuery->fetchColumn();
78
-        $this->trustedQuery->closeCursor();
79
-
80
-        if ($result == 0) {
81
-            $this->untrustedCache[] = $ip;
82
-
83
-            return false;
84
-        }
85
-
86
-        if ($result >= 1) {
87
-            $this->trustedCache[] = $ip;
88
-
89
-            return true;
90
-        }
91
-
92
-        // something weird has happened if we've got here.
93
-        // default to untrusted.
94
-        return false;
95
-    }
96
-
97
-    /**
98
-     * Gets the last trusted IP in the proxy chain.
99
-     *
100
-     * @param string $ip      The IP address from REMOTE_ADDR
101
-     * @param string $proxyIp The contents of the XFF header.
102
-     *
103
-     * @return string Trusted source IP address
104
-     */
105
-    public function getTrustedClientIp($ip, $proxyIp)
106
-    {
107
-        $clientIpAddress = $ip;
108
-        if ($proxyIp) {
109
-            $ipList = explode(",", $proxyIp);
110
-            $ipList[] = $clientIpAddress;
111
-            $ipList = array_reverse($ipList);
112
-
113
-            foreach ($ipList as $ipNumber => $ipAddress) {
114
-                if ($this->isTrusted(trim($ipAddress)) && $ipNumber < (count($ipList) - 1)) {
115
-                    continue;
116
-                }
117
-
118
-                $clientIpAddress = $ipAddress;
119
-                break;
120
-            }
121
-        }
122
-
123
-        return trim($clientIpAddress);
124
-    }
125
-
126
-    /**
127
-     * Takes an array( "low" => "high" ) values, and returns true if $needle is in at least one of them.
128
-     *
129
-     * @param array  $haystack
130
-     * @param string $ip
131
-     *
132
-     * @return bool
133
-     */
134
-    public function ipInRange($haystack, $ip)
135
-    {
136
-        $needle = ip2long($ip);
137
-
138
-        foreach ($haystack as $low => $high) {
139
-            if (ip2long($low) <= $needle && ip2long($high) >= $needle) {
140
-                return true;
141
-            }
142
-        }
143
-
144
-        return false;
145
-    }
146
-
147
-    /**
148
-     * Explodes a CIDR range into an array of addresses
149
-     *
150
-     * @param string $range A CIDR-format range
151
-     *
152
-     * @return array An array containing every IP address in the range
153
-     */
154
-    public function explodeCidr($range)
155
-    {
156
-        $cidrData = explode('/', $range);
157
-
158
-        if (!isset($cidrData[1])) {
159
-            return array($range);
160
-        }
161
-
162
-        $blow = (
163
-            str_pad(decbin(ip2long($cidrData[0])), 32, "0", STR_PAD_LEFT) &
164
-            str_pad(str_pad("", $cidrData[1], "1"), 32, "0")
165
-        );
166
-        $bhigh = ($blow | str_pad(str_pad("", $cidrData[1], "0"), 32, "1"));
167
-
168
-        $list = array();
169
-
170
-        $bindecBHigh = bindec($bhigh);
171
-        for ($x = bindec($blow); $x <= $bindecBHigh; $x++) {
172
-            $list[] = long2ip($x);
173
-        }
174
-
175
-        return $list;
176
-    }
25
+	/**
26
+	 * Array of IP addresses which are TRUSTED proxies
27
+	 * @var string[]
28
+	 */
29
+	private $trustedCache;
30
+	/**
31
+	 * Array of IP addresses which are UNTRUSTED proxies
32
+	 * @var string[]
33
+	 */
34
+	private $untrustedCache = array();
35
+	/** @var PDOStatement */
36
+	private $trustedQuery;
37
+	/**
38
+	 * @var PdoDatabase
39
+	 */
40
+	private $database;
41
+
42
+	/**
43
+	 * Creates a new instance of the trust provider
44
+	 *
45
+	 * @param string[]    $squidIpList List of IP addresses to pre-approve
46
+	 * @param PdoDatabase $database
47
+	 */
48
+	public function __construct($squidIpList, PdoDatabase $database)
49
+	{
50
+		$this->trustedCache = $squidIpList;
51
+		$this->database = $database;
52
+	}
53
+
54
+	/**
55
+	 * Returns a value if the IP address is a trusted proxy
56
+	 *
57
+	 * @param string $ip
58
+	 *
59
+	 * @return bool
60
+	 */
61
+	public function isTrusted($ip)
62
+	{
63
+		if (in_array($ip, $this->trustedCache)) {
64
+			return true;
65
+		}
66
+
67
+		if (in_array($ip, $this->untrustedCache)) {
68
+			return false;
69
+		}
70
+
71
+		if ($this->trustedQuery === null) {
72
+			$query = "SELECT COUNT(id) FROM xfftrustcache WHERE ip = :ip;";
73
+			$this->trustedQuery = $this->database->prepare($query);
74
+		}
75
+
76
+		$this->trustedQuery->execute(array(":ip" => $ip));
77
+		$result = $this->trustedQuery->fetchColumn();
78
+		$this->trustedQuery->closeCursor();
79
+
80
+		if ($result == 0) {
81
+			$this->untrustedCache[] = $ip;
82
+
83
+			return false;
84
+		}
85
+
86
+		if ($result >= 1) {
87
+			$this->trustedCache[] = $ip;
88
+
89
+			return true;
90
+		}
91
+
92
+		// something weird has happened if we've got here.
93
+		// default to untrusted.
94
+		return false;
95
+	}
96
+
97
+	/**
98
+	 * Gets the last trusted IP in the proxy chain.
99
+	 *
100
+	 * @param string $ip      The IP address from REMOTE_ADDR
101
+	 * @param string $proxyIp The contents of the XFF header.
102
+	 *
103
+	 * @return string Trusted source IP address
104
+	 */
105
+	public function getTrustedClientIp($ip, $proxyIp)
106
+	{
107
+		$clientIpAddress = $ip;
108
+		if ($proxyIp) {
109
+			$ipList = explode(",", $proxyIp);
110
+			$ipList[] = $clientIpAddress;
111
+			$ipList = array_reverse($ipList);
112
+
113
+			foreach ($ipList as $ipNumber => $ipAddress) {
114
+				if ($this->isTrusted(trim($ipAddress)) && $ipNumber < (count($ipList) - 1)) {
115
+					continue;
116
+				}
117
+
118
+				$clientIpAddress = $ipAddress;
119
+				break;
120
+			}
121
+		}
122
+
123
+		return trim($clientIpAddress);
124
+	}
125
+
126
+	/**
127
+	 * Takes an array( "low" => "high" ) values, and returns true if $needle is in at least one of them.
128
+	 *
129
+	 * @param array  $haystack
130
+	 * @param string $ip
131
+	 *
132
+	 * @return bool
133
+	 */
134
+	public function ipInRange($haystack, $ip)
135
+	{
136
+		$needle = ip2long($ip);
137
+
138
+		foreach ($haystack as $low => $high) {
139
+			if (ip2long($low) <= $needle && ip2long($high) >= $needle) {
140
+				return true;
141
+			}
142
+		}
143
+
144
+		return false;
145
+	}
146
+
147
+	/**
148
+	 * Explodes a CIDR range into an array of addresses
149
+	 *
150
+	 * @param string $range A CIDR-format range
151
+	 *
152
+	 * @return array An array containing every IP address in the range
153
+	 */
154
+	public function explodeCidr($range)
155
+	{
156
+		$cidrData = explode('/', $range);
157
+
158
+		if (!isset($cidrData[1])) {
159
+			return array($range);
160
+		}
161
+
162
+		$blow = (
163
+			str_pad(decbin(ip2long($cidrData[0])), 32, "0", STR_PAD_LEFT) &
164
+			str_pad(str_pad("", $cidrData[1], "1"), 32, "0")
165
+		);
166
+		$bhigh = ($blow | str_pad(str_pad("", $cidrData[1], "0"), 32, "1"));
167
+
168
+		$list = array();
169
+
170
+		$bindecBHigh = bindec($bhigh);
171
+		for ($x = bindec($blow); $x <= $bindecBHigh; $x++) {
172
+			$list[] = long2ip($x);
173
+		}
174
+
175
+		return $list;
176
+	}
177 177
 }
Please login to merge, or discard this patch.
includes/Security/CredentialProviders/PasswordCredentialProvider.php 1 patch
Indentation   +109 added lines, -109 removed lines patch added patch discarded remove patch
@@ -19,123 +19,123 @@
 block discarded – undo
19 19
 
20 20
 class PasswordCredentialProvider extends CredentialProviderBase
21 21
 {
22
-    const PASSWORD_COST = 10;
23
-    const PASSWORD_ALGO = PASSWORD_BCRYPT;
24
-
25
-    public function __construct(PdoDatabase $database, SiteConfiguration $configuration)
26
-    {
27
-        parent::__construct($database, $configuration, 'password');
28
-    }
29
-
30
-    public function authenticate(User $user, $data)
31
-    {
32
-        $storedData = $this->getCredentialData($user->getId());
33
-        if($storedData === null)
34
-        {
35
-            // No available credential matching these parameters
36
-            return false;
37
-        }
38
-
39
-        if($storedData->getVersion() !== 2) {
40
-            // Non-2 versions are not supported.
41
-            return false;
42
-        }
43
-
44
-        if (!password_verify($data, $storedData->getData())) {
45
-            return false;
46
-        }
47
-
48
-        if (password_needs_rehash($storedData->getData(), self::PASSWORD_ALGO,
49
-            array('cost' => self::PASSWORD_COST))) {
50
-            try {
51
-                $this->reallySetCredential($user, $storedData->getFactor(), $data);
52
-            }
53
-            catch (OptimisticLockFailedException $e) {
54
-                // optimistic lock failed, but no biggie. We'll catch it on the next login.
55
-            }
56
-        }
57
-
58
-        $strengthTester = new Zxcvbn();
59
-        $strength = $strengthTester->passwordStrength($data, [$user->getUsername(), $user->getOnWikiName(), $user->getEmail()]);
60
-
61
-        /*  0 means the password is extremely guessable (within 10^3 guesses), dictionary words like 'password' or 'mother' score a 0
22
+	const PASSWORD_COST = 10;
23
+	const PASSWORD_ALGO = PASSWORD_BCRYPT;
24
+
25
+	public function __construct(PdoDatabase $database, SiteConfiguration $configuration)
26
+	{
27
+		parent::__construct($database, $configuration, 'password');
28
+	}
29
+
30
+	public function authenticate(User $user, $data)
31
+	{
32
+		$storedData = $this->getCredentialData($user->getId());
33
+		if($storedData === null)
34
+		{
35
+			// No available credential matching these parameters
36
+			return false;
37
+		}
38
+
39
+		if($storedData->getVersion() !== 2) {
40
+			// Non-2 versions are not supported.
41
+			return false;
42
+		}
43
+
44
+		if (!password_verify($data, $storedData->getData())) {
45
+			return false;
46
+		}
47
+
48
+		if (password_needs_rehash($storedData->getData(), self::PASSWORD_ALGO,
49
+			array('cost' => self::PASSWORD_COST))) {
50
+			try {
51
+				$this->reallySetCredential($user, $storedData->getFactor(), $data);
52
+			}
53
+			catch (OptimisticLockFailedException $e) {
54
+				// optimistic lock failed, but no biggie. We'll catch it on the next login.
55
+			}
56
+		}
57
+
58
+		$strengthTester = new Zxcvbn();
59
+		$strength = $strengthTester->passwordStrength($data, [$user->getUsername(), $user->getOnWikiName(), $user->getEmail()]);
60
+
61
+		/*  0 means the password is extremely guessable (within 10^3 guesses), dictionary words like 'password' or 'mother' score a 0
62 62
             1 is still very guessable (guesses < 10^6), an extra character on a dictionary word can score a 1
63 63
             2 is somewhat guessable (guesses < 10^8), provides some protection from unthrottled online attacks
64 64
             3 is safely unguessable (guesses < 10^10), offers moderate protection from offline slow-hash scenario
65 65
             4 is very unguessable (guesses >= 10^10) and provides strong protection from offline slow-hash scenario         */
66 66
 
67
-        if ($strength['score'] <= 1 || CommonPasswords::isCommon($data) || mb_strlen($data) < 8) {
68
-            // prevent login for extremely weak passwords
69
-            // at this point the user has authenticated via password, so they *know* it's weak.
70
-            SessionAlert::error('Your password is too weak to permit login. Please choose the "forgotten your password" option below and set a new one.', null);
71
-            return false;
72
-        }
73
-
74
-        return true;
75
-    }
76
-
77
-    /**
78
-     * @param User   $user
79
-     * @param int    $factor
80
-     * @param string $password
81
-     *
82
-     * @throws OptimisticLockFailedException
83
-     */
84
-    private function reallySetCredential(User $user, int $factor, string $password) : void {
85
-        $storedData = $this->getCredentialData($user->getId());
86
-
87
-        if ($storedData === null) {
88
-            $storedData = $this->createNewCredential($user);
89
-        }
90
-
91
-        $storedData->setData(password_hash($password, self::PASSWORD_ALGO, array('cost' => self::PASSWORD_COST)));
92
-        $storedData->setFactor($factor);
93
-        $storedData->setVersion(2);
94
-
95
-        $storedData->save();
96
-    }
97
-
98
-    /**
99
-     * @param User   $user
100
-     * @param int    $factor
101
-     * @param string $password
102
-     *
103
-     * @throws ApplicationLogicException
104
-     * @throws OptimisticLockFailedException
105
-     */
106
-    public function setCredential(User $user, $factor, $password)
107
-    {
108
-        if (CommonPasswords::isCommon($password)) {
109
-            throw new ApplicationLogicException("Your new password is listed in the top 100,000 passwords. Please choose a stronger one.", null);
110
-        }
111
-
112
-        $strengthTester = new Zxcvbn();
113
-        $strength = $strengthTester->passwordStrength($password, [$user->getUsername(), $user->getOnWikiName(), $user->getEmail()]);
114
-
115
-        /*  0 means the password is extremely guessable (within 10^3 guesses), dictionary words like 'password' or 'mother' score a 0
67
+		if ($strength['score'] <= 1 || CommonPasswords::isCommon($data) || mb_strlen($data) < 8) {
68
+			// prevent login for extremely weak passwords
69
+			// at this point the user has authenticated via password, so they *know* it's weak.
70
+			SessionAlert::error('Your password is too weak to permit login. Please choose the "forgotten your password" option below and set a new one.', null);
71
+			return false;
72
+		}
73
+
74
+		return true;
75
+	}
76
+
77
+	/**
78
+	 * @param User   $user
79
+	 * @param int    $factor
80
+	 * @param string $password
81
+	 *
82
+	 * @throws OptimisticLockFailedException
83
+	 */
84
+	private function reallySetCredential(User $user, int $factor, string $password) : void {
85
+		$storedData = $this->getCredentialData($user->getId());
86
+
87
+		if ($storedData === null) {
88
+			$storedData = $this->createNewCredential($user);
89
+		}
90
+
91
+		$storedData->setData(password_hash($password, self::PASSWORD_ALGO, array('cost' => self::PASSWORD_COST)));
92
+		$storedData->setFactor($factor);
93
+		$storedData->setVersion(2);
94
+
95
+		$storedData->save();
96
+	}
97
+
98
+	/**
99
+	 * @param User   $user
100
+	 * @param int    $factor
101
+	 * @param string $password
102
+	 *
103
+	 * @throws ApplicationLogicException
104
+	 * @throws OptimisticLockFailedException
105
+	 */
106
+	public function setCredential(User $user, $factor, $password)
107
+	{
108
+		if (CommonPasswords::isCommon($password)) {
109
+			throw new ApplicationLogicException("Your new password is listed in the top 100,000 passwords. Please choose a stronger one.", null);
110
+		}
111
+
112
+		$strengthTester = new Zxcvbn();
113
+		$strength = $strengthTester->passwordStrength($password, [$user->getUsername(), $user->getOnWikiName(), $user->getEmail()]);
114
+
115
+		/*  0 means the password is extremely guessable (within 10^3 guesses), dictionary words like 'password' or 'mother' score a 0
116 116
             1 is still very guessable (guesses < 10^6), an extra character on a dictionary word can score a 1
117 117
             2 is somewhat guessable (guesses < 10^8), provides some protection from unthrottled online attacks
118 118
             3 is safely unguessable (guesses < 10^10), offers moderate protection from offline slow-hash scenario
119 119
             4 is very unguessable (guesses >= 10^10) and provides strong protection from offline slow-hash scenario         */
120 120
 
121
-        if ($strength['score'] <= 2 || mb_strlen($password) < 8) {
122
-            throw new ApplicationLogicException("Your new password is too weak. Please choose a stronger one.", null);
123
-        }
124
-
125
-        if ($strength['score'] <= 3) {
126
-            SessionAlert::warning("Your new password is not as strong as it could be. Consider replacing it with a stronger password.", null);
127
-        }
128
-
129
-        $this->reallySetCredential($user, $factor, $password);
130
-    }
131
-
132
-    /**
133
-     * @param User $user
134
-     *
135
-     * @throws ApplicationLogicException
136
-     */
137
-    public function deleteCredential(User $user)
138
-    {
139
-        throw new ApplicationLogicException('Deletion of password credential is not allowed.');
140
-    }
121
+		if ($strength['score'] <= 2 || mb_strlen($password) < 8) {
122
+			throw new ApplicationLogicException("Your new password is too weak. Please choose a stronger one.", null);
123
+		}
124
+
125
+		if ($strength['score'] <= 3) {
126
+			SessionAlert::warning("Your new password is not as strong as it could be. Consider replacing it with a stronger password.", null);
127
+		}
128
+
129
+		$this->reallySetCredential($user, $factor, $password);
130
+	}
131
+
132
+	/**
133
+	 * @param User $user
134
+	 *
135
+	 * @throws ApplicationLogicException
136
+	 */
137
+	public function deleteCredential(User $user)
138
+	{
139
+		throw new ApplicationLogicException('Deletion of password credential is not allowed.');
140
+	}
141 141
 }
Please login to merge, or discard this patch.
includes/Security/RoleConfiguration.php 1 patch
Indentation   +361 added lines, -361 removed lines patch added patch discarded remove patch
@@ -47,392 +47,392 @@
 block discarded – undo
47 47
 
48 48
 class RoleConfiguration
49 49
 {
50
-    const ACCESS_ALLOW = 1;
51
-    const ACCESS_DENY = -1;
52
-    const ACCESS_DEFAULT = 0;
53
-    const MAIN = 'main';
54
-    const ALL = '*';
55
-    /**
56
-     * A map of roles to rights
57
-     *
58
-     * For example:
59
-     *
60
-     * array(
61
-     *   'myrole' => array(
62
-     *       PageMyPage::class => array(
63
-     *           'edit' => self::ACCESS_ALLOW,
64
-     *           'create' => self::ACCESS_DENY,
65
-     *       )
66
-     *   )
67
-     * )
68
-     *
69
-     * Note that DENY takes precedence over everything else when roles are combined, followed by ALLOW, followed by
70
-     * DEFAULT. Thus, if you have the following ([A]llow, [D]eny, [-] (default)) grants in different roles, this should
71
-     * be the expected result:
72
-     *
73
-     * - (-,-,-) = - (default because nothing to explicitly say allowed or denied equates to a denial)
74
-     * - (A,-,-) = A
75
-     * - (D,-,-) = D
76
-     * - (A,D,-) = D (deny takes precedence over allow)
77
-     * - (A,A,A) = A (repetition has no effect)
78
-     *
79
-     * The public role is special, and is applied to all users automatically. Avoid using deny on this role.
80
-     *
81
-     * @var array
82
-     */
83
-    private $roleConfig = array(
84
-        'public'            => array(
85
-            /*
50
+	const ACCESS_ALLOW = 1;
51
+	const ACCESS_DENY = -1;
52
+	const ACCESS_DEFAULT = 0;
53
+	const MAIN = 'main';
54
+	const ALL = '*';
55
+	/**
56
+	 * A map of roles to rights
57
+	 *
58
+	 * For example:
59
+	 *
60
+	 * array(
61
+	 *   'myrole' => array(
62
+	 *       PageMyPage::class => array(
63
+	 *           'edit' => self::ACCESS_ALLOW,
64
+	 *           'create' => self::ACCESS_DENY,
65
+	 *       )
66
+	 *   )
67
+	 * )
68
+	 *
69
+	 * Note that DENY takes precedence over everything else when roles are combined, followed by ALLOW, followed by
70
+	 * DEFAULT. Thus, if you have the following ([A]llow, [D]eny, [-] (default)) grants in different roles, this should
71
+	 * be the expected result:
72
+	 *
73
+	 * - (-,-,-) = - (default because nothing to explicitly say allowed or denied equates to a denial)
74
+	 * - (A,-,-) = A
75
+	 * - (D,-,-) = D
76
+	 * - (A,D,-) = D (deny takes precedence over allow)
77
+	 * - (A,A,A) = A (repetition has no effect)
78
+	 *
79
+	 * The public role is special, and is applied to all users automatically. Avoid using deny on this role.
80
+	 *
81
+	 * @var array
82
+	 */
83
+	private $roleConfig = array(
84
+		'public'            => array(
85
+			/*
86 86
              * THIS ROLE IS GRANTED TO ALL LOGGED *OUT* USERS IMPLICITLY.
87 87
              *
88 88
              * USERS IN THIS ROLE DO NOT HAVE TO BE IDENTIFIED TO GET THE RIGHTS CONFERRED HERE.
89 89
              * DO NOT ADD ANY SECURITY-SENSITIVE RIGHTS HERE.
90 90
              */
91
-            '_childRoles'   => array(
92
-                'publicStats',
93
-            ),
94
-            PageTeam::class => array(
95
-                self::MAIN => self::ACCESS_ALLOW,
96
-            ),
97
-            PageXffDemo::class        => array(
98
-                self::MAIN  => self::ACCESS_ALLOW,
99
-            )
100
-        ),
101
-        'loggedIn'          => array(
102
-            /*
91
+			'_childRoles'   => array(
92
+				'publicStats',
93
+			),
94
+			PageTeam::class => array(
95
+				self::MAIN => self::ACCESS_ALLOW,
96
+			),
97
+			PageXffDemo::class        => array(
98
+				self::MAIN  => self::ACCESS_ALLOW,
99
+			)
100
+		),
101
+		'loggedIn'          => array(
102
+			/*
103 103
              * THIS ROLE IS GRANTED TO ALL LOGGED IN USERS IMPLICITLY.
104 104
              *
105 105
              * USERS IN THIS ROLE DO NOT HAVE TO BE IDENTIFIED TO GET THE RIGHTS CONFERRED HERE.
106 106
              * DO NOT ADD ANY SECURITY-SENSITIVE RIGHTS HERE.
107 107
              */
108
-            '_childRoles'             => array(
109
-                'public',
110
-            ),
111
-            PagePreferences::class    => array(
112
-                self::MAIN => self::ACCESS_ALLOW,
113
-                'refreshOAuth' => self::ACCESS_ALLOW,
114
-            ),
115
-            PageChangePassword::class => array(
116
-                self::MAIN => self::ACCESS_ALLOW,
117
-            ),
118
-            PageMultiFactor::class    => array(
119
-                self::MAIN          => self::ACCESS_ALLOW,
120
-                'scratch'           => self::ACCESS_ALLOW,
121
-                'enableYubikeyOtp'  => self::ACCESS_ALLOW,
122
-                'disableYubikeyOtp' => self::ACCESS_ALLOW,
123
-                'enableTotp'        => self::ACCESS_ALLOW,
124
-                'disableTotp'       => self::ACCESS_ALLOW,
125
-            ),
126
-            PageOAuth::class          => array(
127
-                'attach' => self::ACCESS_ALLOW,
128
-                'detach' => self::ACCESS_ALLOW,
129
-            ),
130
-        ),
131
-        'user'              => array(
132
-            '_description'                       => 'A standard tool user.',
133
-            '_editableBy'                        => array('admin', 'toolRoot'),
134
-            '_childRoles'                        => array(
135
-                'internalStats',
136
-            ),
137
-            PageMain::class                      => array(
138
-                self::MAIN => self::ACCESS_ALLOW,
139
-            ),
140
-            PageBan::class                       => array(
141
-                self::MAIN => self::ACCESS_ALLOW,
142
-            ),
143
-            PageEditComment::class               => array(
144
-                self::MAIN => self::ACCESS_ALLOW,
145
-            ),
146
-            PageEmailManagement::class           => array(
147
-                self::MAIN => self::ACCESS_ALLOW,
148
-                'view'     => self::ACCESS_ALLOW,
149
-            ),
150
-            PageExpandedRequestList::class       => array(
151
-                self::MAIN => self::ACCESS_ALLOW,
152
-            ),
153
-            PageLog::class                       => array(
154
-                self::MAIN => self::ACCESS_ALLOW,
155
-            ),
156
-            PageSearch::class                    => array(
157
-                self::MAIN => self::ACCESS_ALLOW,
158
-            ),
159
-            PageWelcomeTemplateManagement::class => array(
160
-                self::MAIN => self::ACCESS_ALLOW,
161
-                'select'   => self::ACCESS_ALLOW,
162
-                'view'     => self::ACCESS_ALLOW,
163
-            ),
164
-            PageViewRequest::class               => array(
165
-                self::MAIN       => self::ACCESS_ALLOW,
166
-                'seeAllRequests' => self::ACCESS_ALLOW,
167
-            ),
168
-            'RequestData'                        => array(
169
-                'seePrivateDataWhenReserved' => self::ACCESS_ALLOW,
170
-                'seePrivateDataWithHash'     => self::ACCESS_ALLOW,
171
-                'seeRelatedRequests'         => self::ACCESS_ALLOW,
172
-            ),
173
-            PageCustomClose::class               => array(
174
-                self::MAIN => self::ACCESS_ALLOW,
175
-            ),
176
-            PageComment::class                   => array(
177
-                self::MAIN => self::ACCESS_ALLOW,
178
-            ),
179
-            PageCloseRequest::class              => array(
180
-                self::MAIN => self::ACCESS_ALLOW,
181
-            ),
182
-            PageCreateRequest::class             => array(
183
-                self::MAIN => self::ACCESS_ALLOW,
184
-            ),
185
-            PageDeferRequest::class              => array(
186
-                self::MAIN => self::ACCESS_ALLOW,
187
-            ),
188
-            PageDropRequest::class               => array(
189
-                self::MAIN => self::ACCESS_ALLOW,
190
-            ),
191
-            PageReservation::class               => array(
192
-                self::MAIN => self::ACCESS_ALLOW,
193
-            ),
194
-            PageSendToUser::class                => array(
195
-                self::MAIN => self::ACCESS_ALLOW,
196
-            ),
197
-            PageBreakReservation::class          => array(
198
-                self::MAIN => self::ACCESS_ALLOW,
199
-            ),
200
-            PageJobQueue::class                  => array(
201
-                self::MAIN => self::ACCESS_ALLOW,
202
-                'view'     => self::ACCESS_ALLOW,
203
-                'all'      => self::ACCESS_ALLOW,
204
-            ),
205
-            'RequestCreation'                    => array(
206
-                User::CREATION_MANUAL => self::ACCESS_ALLOW,
207
-            ),
208
-            'GlobalInfo'                         => array(
209
-                'viewSiteNotice' => self::ACCESS_ALLOW,
210
-                'viewOnlineUsers' => self::ACCESS_ALLOW,
211
-            ),
212
-        ),
213
-        'admin'             => array(
214
-            '_description'                       => 'A tool administrator.',
215
-            '_editableBy'                        => array('admin', 'toolRoot'),
216
-            '_childRoles'                        => array(
217
-                'user',
218
-                'requestAdminTools',
219
-            ),
220
-            PageEmailManagement::class           => array(
221
-                'edit'   => self::ACCESS_ALLOW,
222
-                'create' => self::ACCESS_ALLOW,
223
-            ),
224
-            PageSiteNotice::class                => array(
225
-                self::MAIN => self::ACCESS_ALLOW,
226
-            ),
227
-            PageUserManagement::class            => array(
228
-                self::MAIN  => self::ACCESS_ALLOW,
229
-                'approve'   => self::ACCESS_ALLOW,
230
-                'decline'   => self::ACCESS_ALLOW,
231
-                'rename'    => self::ACCESS_ALLOW,
232
-                'editUser'  => self::ACCESS_ALLOW,
233
-                'suspend'   => self::ACCESS_ALLOW,
234
-                'editRoles' => self::ACCESS_ALLOW,
235
-            ),
236
-            PageWelcomeTemplateManagement::class => array(
237
-                'edit'   => self::ACCESS_ALLOW,
238
-                'delete' => self::ACCESS_ALLOW,
239
-                'add'    => self::ACCESS_ALLOW,
240
-            ),
241
-            PageJobQueue::class                  => array(
242
-                'acknowledge' => self::ACCESS_ALLOW,
243
-                'requeue'     => self::ACCESS_ALLOW,
244
-            ),
245
-        ),
246
-        'checkuser'         => array(
247
-            '_description'            => 'A user with CheckUser access',
248
-            '_editableBy'             => array('checkuser', 'toolRoot'),
249
-            '_childRoles'             => array(
250
-                'user',
251
-                'requestAdminTools',
252
-            ),
253
-            PageUserManagement::class => array(
254
-                self::MAIN  => self::ACCESS_ALLOW,
255
-                'suspend'   => self::ACCESS_ALLOW,
256
-                'editRoles' => self::ACCESS_ALLOW,
257
-            ),
258
-            'RequestData'             => array(
259
-                'seeUserAgentData' => self::ACCESS_ALLOW,
260
-            ),
261
-        ),
262
-        'toolRoot'          => array(
263
-            '_description' => 'A user with shell access to the servers running the tool',
264
-            '_editableBy'  => array('toolRoot'),
265
-            '_childRoles'  => array(
266
-                'admin',
267
-            ),
268
-            PageMultiFactor::class => array(
269
-                'enableU2F'         => self::ACCESS_ALLOW,
270
-                'disableU2F'        => self::ACCESS_ALLOW,
271
-            )
272
-        ),
273
-        'botCreation'       => array(
274
-            '_description'    => 'A user allowed to use the bot to perform account creations',
275
-            '_editableBy'     => array('admin', 'toolRoot'),
276
-            '_childRoles'     => array(),
277
-            'RequestCreation' => array(
278
-                User::CREATION_BOT => self::ACCESS_ALLOW,
279
-            ),
280
-        ),
281
-        'oauthCreation'       => array(
282
-            '_description'    => 'A user allowed to use the OAuth to perform account creations',
283
-            '_editableBy'     => array('admin', 'toolRoot'),
284
-            '_childRoles'     => array(),
285
-            'RequestCreation'                    => array(
286
-                User::CREATION_OAUTH  => self::ACCESS_ALLOW,
287
-            ),
288
-        ),
108
+			'_childRoles'             => array(
109
+				'public',
110
+			),
111
+			PagePreferences::class    => array(
112
+				self::MAIN => self::ACCESS_ALLOW,
113
+				'refreshOAuth' => self::ACCESS_ALLOW,
114
+			),
115
+			PageChangePassword::class => array(
116
+				self::MAIN => self::ACCESS_ALLOW,
117
+			),
118
+			PageMultiFactor::class    => array(
119
+				self::MAIN          => self::ACCESS_ALLOW,
120
+				'scratch'           => self::ACCESS_ALLOW,
121
+				'enableYubikeyOtp'  => self::ACCESS_ALLOW,
122
+				'disableYubikeyOtp' => self::ACCESS_ALLOW,
123
+				'enableTotp'        => self::ACCESS_ALLOW,
124
+				'disableTotp'       => self::ACCESS_ALLOW,
125
+			),
126
+			PageOAuth::class          => array(
127
+				'attach' => self::ACCESS_ALLOW,
128
+				'detach' => self::ACCESS_ALLOW,
129
+			),
130
+		),
131
+		'user'              => array(
132
+			'_description'                       => 'A standard tool user.',
133
+			'_editableBy'                        => array('admin', 'toolRoot'),
134
+			'_childRoles'                        => array(
135
+				'internalStats',
136
+			),
137
+			PageMain::class                      => array(
138
+				self::MAIN => self::ACCESS_ALLOW,
139
+			),
140
+			PageBan::class                       => array(
141
+				self::MAIN => self::ACCESS_ALLOW,
142
+			),
143
+			PageEditComment::class               => array(
144
+				self::MAIN => self::ACCESS_ALLOW,
145
+			),
146
+			PageEmailManagement::class           => array(
147
+				self::MAIN => self::ACCESS_ALLOW,
148
+				'view'     => self::ACCESS_ALLOW,
149
+			),
150
+			PageExpandedRequestList::class       => array(
151
+				self::MAIN => self::ACCESS_ALLOW,
152
+			),
153
+			PageLog::class                       => array(
154
+				self::MAIN => self::ACCESS_ALLOW,
155
+			),
156
+			PageSearch::class                    => array(
157
+				self::MAIN => self::ACCESS_ALLOW,
158
+			),
159
+			PageWelcomeTemplateManagement::class => array(
160
+				self::MAIN => self::ACCESS_ALLOW,
161
+				'select'   => self::ACCESS_ALLOW,
162
+				'view'     => self::ACCESS_ALLOW,
163
+			),
164
+			PageViewRequest::class               => array(
165
+				self::MAIN       => self::ACCESS_ALLOW,
166
+				'seeAllRequests' => self::ACCESS_ALLOW,
167
+			),
168
+			'RequestData'                        => array(
169
+				'seePrivateDataWhenReserved' => self::ACCESS_ALLOW,
170
+				'seePrivateDataWithHash'     => self::ACCESS_ALLOW,
171
+				'seeRelatedRequests'         => self::ACCESS_ALLOW,
172
+			),
173
+			PageCustomClose::class               => array(
174
+				self::MAIN => self::ACCESS_ALLOW,
175
+			),
176
+			PageComment::class                   => array(
177
+				self::MAIN => self::ACCESS_ALLOW,
178
+			),
179
+			PageCloseRequest::class              => array(
180
+				self::MAIN => self::ACCESS_ALLOW,
181
+			),
182
+			PageCreateRequest::class             => array(
183
+				self::MAIN => self::ACCESS_ALLOW,
184
+			),
185
+			PageDeferRequest::class              => array(
186
+				self::MAIN => self::ACCESS_ALLOW,
187
+			),
188
+			PageDropRequest::class               => array(
189
+				self::MAIN => self::ACCESS_ALLOW,
190
+			),
191
+			PageReservation::class               => array(
192
+				self::MAIN => self::ACCESS_ALLOW,
193
+			),
194
+			PageSendToUser::class                => array(
195
+				self::MAIN => self::ACCESS_ALLOW,
196
+			),
197
+			PageBreakReservation::class          => array(
198
+				self::MAIN => self::ACCESS_ALLOW,
199
+			),
200
+			PageJobQueue::class                  => array(
201
+				self::MAIN => self::ACCESS_ALLOW,
202
+				'view'     => self::ACCESS_ALLOW,
203
+				'all'      => self::ACCESS_ALLOW,
204
+			),
205
+			'RequestCreation'                    => array(
206
+				User::CREATION_MANUAL => self::ACCESS_ALLOW,
207
+			),
208
+			'GlobalInfo'                         => array(
209
+				'viewSiteNotice' => self::ACCESS_ALLOW,
210
+				'viewOnlineUsers' => self::ACCESS_ALLOW,
211
+			),
212
+		),
213
+		'admin'             => array(
214
+			'_description'                       => 'A tool administrator.',
215
+			'_editableBy'                        => array('admin', 'toolRoot'),
216
+			'_childRoles'                        => array(
217
+				'user',
218
+				'requestAdminTools',
219
+			),
220
+			PageEmailManagement::class           => array(
221
+				'edit'   => self::ACCESS_ALLOW,
222
+				'create' => self::ACCESS_ALLOW,
223
+			),
224
+			PageSiteNotice::class                => array(
225
+				self::MAIN => self::ACCESS_ALLOW,
226
+			),
227
+			PageUserManagement::class            => array(
228
+				self::MAIN  => self::ACCESS_ALLOW,
229
+				'approve'   => self::ACCESS_ALLOW,
230
+				'decline'   => self::ACCESS_ALLOW,
231
+				'rename'    => self::ACCESS_ALLOW,
232
+				'editUser'  => self::ACCESS_ALLOW,
233
+				'suspend'   => self::ACCESS_ALLOW,
234
+				'editRoles' => self::ACCESS_ALLOW,
235
+			),
236
+			PageWelcomeTemplateManagement::class => array(
237
+				'edit'   => self::ACCESS_ALLOW,
238
+				'delete' => self::ACCESS_ALLOW,
239
+				'add'    => self::ACCESS_ALLOW,
240
+			),
241
+			PageJobQueue::class                  => array(
242
+				'acknowledge' => self::ACCESS_ALLOW,
243
+				'requeue'     => self::ACCESS_ALLOW,
244
+			),
245
+		),
246
+		'checkuser'         => array(
247
+			'_description'            => 'A user with CheckUser access',
248
+			'_editableBy'             => array('checkuser', 'toolRoot'),
249
+			'_childRoles'             => array(
250
+				'user',
251
+				'requestAdminTools',
252
+			),
253
+			PageUserManagement::class => array(
254
+				self::MAIN  => self::ACCESS_ALLOW,
255
+				'suspend'   => self::ACCESS_ALLOW,
256
+				'editRoles' => self::ACCESS_ALLOW,
257
+			),
258
+			'RequestData'             => array(
259
+				'seeUserAgentData' => self::ACCESS_ALLOW,
260
+			),
261
+		),
262
+		'toolRoot'          => array(
263
+			'_description' => 'A user with shell access to the servers running the tool',
264
+			'_editableBy'  => array('toolRoot'),
265
+			'_childRoles'  => array(
266
+				'admin',
267
+			),
268
+			PageMultiFactor::class => array(
269
+				'enableU2F'         => self::ACCESS_ALLOW,
270
+				'disableU2F'        => self::ACCESS_ALLOW,
271
+			)
272
+		),
273
+		'botCreation'       => array(
274
+			'_description'    => 'A user allowed to use the bot to perform account creations',
275
+			'_editableBy'     => array('admin', 'toolRoot'),
276
+			'_childRoles'     => array(),
277
+			'RequestCreation' => array(
278
+				User::CREATION_BOT => self::ACCESS_ALLOW,
279
+			),
280
+		),
281
+		'oauthCreation'       => array(
282
+			'_description'    => 'A user allowed to use the OAuth to perform account creations',
283
+			'_editableBy'     => array('admin', 'toolRoot'),
284
+			'_childRoles'     => array(),
285
+			'RequestCreation'                    => array(
286
+				User::CREATION_OAUTH  => self::ACCESS_ALLOW,
287
+			),
288
+		),
289 289
 
290 290
 
291
-        // Child roles go below this point
292
-        'publicStats'       => array(
293
-            '_hidden'               => true,
294
-            StatsUsers::class       => array(
295
-                self::MAIN => self::ACCESS_ALLOW,
296
-                'detail'   => self::ACCESS_ALLOW,
297
-            ),
298
-            StatsTopCreators::class => array(
299
-                self::MAIN => self::ACCESS_ALLOW,
300
-            ),
301
-        ),
302
-        'internalStats'     => array(
303
-            '_hidden'                    => true,
304
-            StatsMain::class             => array(
305
-                self::MAIN => self::ACCESS_ALLOW,
306
-            ),
307
-            StatsFastCloses::class       => array(
308
-                self::MAIN => self::ACCESS_ALLOW,
309
-            ),
310
-            StatsInactiveUsers::class    => array(
311
-                self::MAIN => self::ACCESS_ALLOW,
312
-            ),
313
-            StatsMonthlyStats::class     => array(
314
-                self::MAIN => self::ACCESS_ALLOW,
315
-            ),
316
-            StatsReservedRequests::class => array(
317
-                self::MAIN => self::ACCESS_ALLOW,
318
-            ),
319
-            StatsTemplateStats::class    => array(
320
-                self::MAIN => self::ACCESS_ALLOW,
321
-            ),
322
-        ),
323
-        'requestAdminTools' => array(
324
-            '_hidden'                   => true,
325
-            PageBan::class              => array(
326
-                self::MAIN => self::ACCESS_ALLOW,
327
-                'set'      => self::ACCESS_ALLOW,
328
-                'remove'   => self::ACCESS_ALLOW,
329
-            ),
330
-            PageEditComment::class      => array(
331
-                'editOthers' => self::ACCESS_ALLOW,
332
-            ),
333
-            PageBreakReservation::class => array(
334
-                'force' => self::ACCESS_ALLOW,
335
-            ),
336
-            PageCustomClose::class      => array(
337
-                'skipCcMailingList' => self::ACCESS_ALLOW,
338
-            ),
339
-            'RequestData'               => array(
340
-                'reopenOldRequest'      => self::ACCESS_ALLOW,
341
-                'alwaysSeePrivateData'  => self::ACCESS_ALLOW,
342
-                'alwaysSeeHash'         => self::ACCESS_ALLOW,
343
-                'seeRestrictedComments' => self::ACCESS_ALLOW,
344
-            ),
345
-        ),
346
-    );
347
-    /** @var array
348
-     * List of roles which are *exempt* from the identification requirements
349
-     *
350
-     * Think twice about adding roles to this list.
351
-     *
352
-     * @category Security-Critical
353
-     */
354
-    private $identificationExempt = array('public', 'loggedIn');
291
+		// Child roles go below this point
292
+		'publicStats'       => array(
293
+			'_hidden'               => true,
294
+			StatsUsers::class       => array(
295
+				self::MAIN => self::ACCESS_ALLOW,
296
+				'detail'   => self::ACCESS_ALLOW,
297
+			),
298
+			StatsTopCreators::class => array(
299
+				self::MAIN => self::ACCESS_ALLOW,
300
+			),
301
+		),
302
+		'internalStats'     => array(
303
+			'_hidden'                    => true,
304
+			StatsMain::class             => array(
305
+				self::MAIN => self::ACCESS_ALLOW,
306
+			),
307
+			StatsFastCloses::class       => array(
308
+				self::MAIN => self::ACCESS_ALLOW,
309
+			),
310
+			StatsInactiveUsers::class    => array(
311
+				self::MAIN => self::ACCESS_ALLOW,
312
+			),
313
+			StatsMonthlyStats::class     => array(
314
+				self::MAIN => self::ACCESS_ALLOW,
315
+			),
316
+			StatsReservedRequests::class => array(
317
+				self::MAIN => self::ACCESS_ALLOW,
318
+			),
319
+			StatsTemplateStats::class    => array(
320
+				self::MAIN => self::ACCESS_ALLOW,
321
+			),
322
+		),
323
+		'requestAdminTools' => array(
324
+			'_hidden'                   => true,
325
+			PageBan::class              => array(
326
+				self::MAIN => self::ACCESS_ALLOW,
327
+				'set'      => self::ACCESS_ALLOW,
328
+				'remove'   => self::ACCESS_ALLOW,
329
+			),
330
+			PageEditComment::class      => array(
331
+				'editOthers' => self::ACCESS_ALLOW,
332
+			),
333
+			PageBreakReservation::class => array(
334
+				'force' => self::ACCESS_ALLOW,
335
+			),
336
+			PageCustomClose::class      => array(
337
+				'skipCcMailingList' => self::ACCESS_ALLOW,
338
+			),
339
+			'RequestData'               => array(
340
+				'reopenOldRequest'      => self::ACCESS_ALLOW,
341
+				'alwaysSeePrivateData'  => self::ACCESS_ALLOW,
342
+				'alwaysSeeHash'         => self::ACCESS_ALLOW,
343
+				'seeRestrictedComments' => self::ACCESS_ALLOW,
344
+			),
345
+		),
346
+	);
347
+	/** @var array
348
+	 * List of roles which are *exempt* from the identification requirements
349
+	 *
350
+	 * Think twice about adding roles to this list.
351
+	 *
352
+	 * @category Security-Critical
353
+	 */
354
+	private $identificationExempt = array('public', 'loggedIn');
355 355
 
356
-    /**
357
-     * RoleConfiguration constructor.
358
-     *
359
-     * @param array $roleConfig           Set to non-null to override the default configuration.
360
-     * @param array $identificationExempt Set to non-null to override the default configuration.
361
-     */
362
-    public function __construct(array $roleConfig = null, array $identificationExempt = null)
363
-    {
364
-        if ($roleConfig !== null) {
365
-            $this->roleConfig = $roleConfig;
366
-        }
356
+	/**
357
+	 * RoleConfiguration constructor.
358
+	 *
359
+	 * @param array $roleConfig           Set to non-null to override the default configuration.
360
+	 * @param array $identificationExempt Set to non-null to override the default configuration.
361
+	 */
362
+	public function __construct(array $roleConfig = null, array $identificationExempt = null)
363
+	{
364
+		if ($roleConfig !== null) {
365
+			$this->roleConfig = $roleConfig;
366
+		}
367 367
 
368
-        if ($identificationExempt !== null) {
369
-            $this->identificationExempt = $identificationExempt;
370
-        }
371
-    }
368
+		if ($identificationExempt !== null) {
369
+			$this->identificationExempt = $identificationExempt;
370
+		}
371
+	}
372 372
 
373
-    /**
374
-     * @param array $roles The roles to check
375
-     *
376
-     * @return array
377
-     */
378
-    public function getApplicableRoles(array $roles)
379
-    {
380
-        $available = array();
373
+	/**
374
+	 * @param array $roles The roles to check
375
+	 *
376
+	 * @return array
377
+	 */
378
+	public function getApplicableRoles(array $roles)
379
+	{
380
+		$available = array();
381 381
 
382
-        foreach ($roles as $role) {
383
-            if (!isset($this->roleConfig[$role])) {
384
-                // wat
385
-                continue;
386
-            }
382
+		foreach ($roles as $role) {
383
+			if (!isset($this->roleConfig[$role])) {
384
+				// wat
385
+				continue;
386
+			}
387 387
 
388
-            $available[$role] = $this->roleConfig[$role];
388
+			$available[$role] = $this->roleConfig[$role];
389 389
 
390
-            if (isset($available[$role]['_childRoles'])) {
391
-                $childRoles = $this->getApplicableRoles($available[$role]['_childRoles']);
392
-                $available = array_merge($available, $childRoles);
390
+			if (isset($available[$role]['_childRoles'])) {
391
+				$childRoles = $this->getApplicableRoles($available[$role]['_childRoles']);
392
+				$available = array_merge($available, $childRoles);
393 393
 
394
-                unset($available[$role]['_childRoles']);
395
-            }
394
+				unset($available[$role]['_childRoles']);
395
+			}
396 396
 
397
-            foreach (array('_hidden', '_editableBy', '_description') as $item) {
398
-                if (isset($available[$role][$item])) {
399
-                    unset($available[$role][$item]);
400
-                }
401
-            }
402
-        }
397
+			foreach (array('_hidden', '_editableBy', '_description') as $item) {
398
+				if (isset($available[$role][$item])) {
399
+					unset($available[$role][$item]);
400
+				}
401
+			}
402
+		}
403 403
 
404
-        return $available;
405
-    }
404
+		return $available;
405
+	}
406 406
 
407
-    public function getAvailableRoles()
408
-    {
409
-        $possible = array_diff(array_keys($this->roleConfig), array('public', 'loggedIn'));
407
+	public function getAvailableRoles()
408
+	{
409
+		$possible = array_diff(array_keys($this->roleConfig), array('public', 'loggedIn'));
410 410
 
411
-        $actual = array();
411
+		$actual = array();
412 412
 
413
-        foreach ($possible as $role) {
414
-            if (!isset($this->roleConfig[$role]['_hidden'])) {
415
-                $actual[$role] = array(
416
-                    'description' => $this->roleConfig[$role]['_description'],
417
-                    'editableBy'  => $this->roleConfig[$role]['_editableBy'],
418
-                );
419
-            }
420
-        }
413
+		foreach ($possible as $role) {
414
+			if (!isset($this->roleConfig[$role]['_hidden'])) {
415
+				$actual[$role] = array(
416
+					'description' => $this->roleConfig[$role]['_description'],
417
+					'editableBy'  => $this->roleConfig[$role]['_editableBy'],
418
+				);
419
+			}
420
+		}
421 421
 
422
-        return $actual;
423
-    }
422
+		return $actual;
423
+	}
424 424
 
425
-    /**
426
-     * @param string $role
427
-     *
428
-     * @return bool
429
-     */
430
-    public function roleNeedsIdentification($role)
431
-    {
432
-        if (in_array($role, $this->identificationExempt)) {
433
-            return false;
434
-        }
425
+	/**
426
+	 * @param string $role
427
+	 *
428
+	 * @return bool
429
+	 */
430
+	public function roleNeedsIdentification($role)
431
+	{
432
+		if (in_array($role, $this->identificationExempt)) {
433
+			return false;
434
+		}
435 435
 
436
-        return true;
437
-    }
436
+		return true;
437
+	}
438 438
 }
Please login to merge, or discard this patch.
includes/Pages/UserAuth/MultiFactor/PageMultiFactor.php 1 patch
Indentation   +389 added lines, -389 removed lines patch added patch discarded remove patch
@@ -27,249 +27,249 @@  discard block
 block discarded – undo
27 27
 
28 28
 class PageMultiFactor extends InternalPageBase
29 29
 {
30
-    /**
31
-     * Main function for this page, when no specific actions are called.
32
-     * @return void
33
-     */
34
-    protected function main()
35
-    {
36
-        $database = $this->getDatabase();
37
-        $currentUser = User::getCurrent($database);
38
-
39
-        $yubikeyOtpCredentialProvider = new YubikeyOtpCredentialProvider($database, $this->getSiteConfiguration(),
40
-            $this->getHttpHelper());
41
-        $this->assign('yubikeyOtpIdentity', $yubikeyOtpCredentialProvider->getYubikeyData($currentUser->getId()));
42
-        $this->assign('yubikeyOtpEnrolled', $yubikeyOtpCredentialProvider->userIsEnrolled($currentUser->getId()));
43
-
44
-        $totpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
45
-        $this->assign('totpEnrolled', $totpCredentialProvider->userIsEnrolled($currentUser->getId()));
46
-
47
-        $u2fCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
48
-        $this->assign('u2fEnrolled', $u2fCredentialProvider->userIsEnrolled($currentUser->getId()));
49
-
50
-        $scratchCredentialProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
51
-        $this->assign('scratchEnrolled', $scratchCredentialProvider->userIsEnrolled($currentUser->getId()));
52
-        $this->assign('scratchRemaining', $scratchCredentialProvider->getRemaining($currentUser->getId()));
53
-
54
-        $this->assign('allowedTotp', $this->barrierTest('enableTotp', $currentUser));
55
-        $this->assign('allowedYubikey', $this->barrierTest('enableYubikeyOtp', $currentUser));
56
-        $this->assign('allowedU2f', $this->barrierTest('enableU2F', $currentUser));
57
-
58
-        $this->setTemplate('mfa/mfa.tpl');
59
-    }
60
-
61
-    protected function enableYubikeyOtp()
62
-    {
63
-        $database = $this->getDatabase();
64
-        $currentUser = User::getCurrent($database);
65
-
66
-        $otpCredentialProvider = new YubikeyOtpCredentialProvider($database,
67
-            $this->getSiteConfiguration(), $this->getHttpHelper());
68
-
69
-        if (WebRequest::wasPosted()) {
70
-            $this->validateCSRFToken();
71
-
72
-            $passwordCredentialProvider = new PasswordCredentialProvider($database,
73
-                $this->getSiteConfiguration());
74
-
75
-            $password = WebRequest::postString('password');
76
-            $otp = WebRequest::postString('otp');
77
-
78
-            $result = $passwordCredentialProvider->authenticate($currentUser, $password);
79
-
80
-            if ($result) {
81
-                try {
82
-                    $otpCredentialProvider->setCredential($currentUser, 2, $otp);
83
-                    SessionAlert::success('Enabled YubiKey OTP.');
84
-
85
-                    $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
86
-                    if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
87
-                        $scratchProvider->setCredential($currentUser, 2, null);
88
-                        $tokens = $scratchProvider->getTokens();
89
-                        $this->assign('tokens', $tokens);
90
-                        $this->setTemplate('mfa/regenScratchTokens.tpl');
91
-                        return;
92
-                    }
93
-                }
94
-                catch (ApplicationLogicException $ex) {
95
-                    SessionAlert::error('Error enabling YubiKey OTP: ' . $ex->getMessage());
96
-                }
97
-
98
-                $this->redirect('multiFactor');
99
-            }
100
-            else {
101
-                SessionAlert::error('Error enabling YubiKey OTP - invalid credentials.');
102
-                $this->redirect('multiFactor');
103
-            }
104
-        }
105
-        else {
106
-            if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
107
-                // user is not enrolled, we shouldn't have got here.
108
-                throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
109
-            }
110
-
111
-            $this->assignCSRFToken();
112
-            $this->setTemplate('mfa/enableYubikey.tpl');
113
-        }
114
-    }
115
-
116
-    protected function disableYubikeyOtp()
117
-    {
118
-        $database = $this->getDatabase();
119
-        $currentUser = User::getCurrent($database);
120
-
121
-        $otpCredentialProvider = new YubikeyOtpCredentialProvider($database,
122
-            $this->getSiteConfiguration(), $this->getHttpHelper());
123
-
124
-        $factorType = 'YubiKey OTP';
125
-
126
-        $this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
127
-    }
128
-
129
-    protected function enableTotp()
130
-    {
131
-        $database = $this->getDatabase();
132
-        $currentUser = User::getCurrent($database);
133
-
134
-        $otpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
135
-
136
-        if (WebRequest::wasPosted()) {
137
-            $this->validateCSRFToken();
138
-
139
-            // used for routing only, not security
140
-            $stage = WebRequest::postString('stage');
141
-
142
-            if ($stage === "auth") {
143
-                $password = WebRequest::postString('password');
144
-
145
-                $passwordCredentialProvider = new PasswordCredentialProvider($database,
146
-                    $this->getSiteConfiguration());
147
-                $result = $passwordCredentialProvider->authenticate($currentUser, $password);
148
-
149
-                if ($result) {
150
-                    $otpCredentialProvider->setCredential($currentUser, 2, null);
151
-
152
-                    $provisioningUrl = $otpCredentialProvider->getProvisioningUrl($currentUser);
153
-
154
-                    $renderer = new ImageRenderer(
155
-                        new RendererStyle(256),
156
-                        new SvgImageBackEnd()
157
-                    );
158
-
159
-                    $writer = new Writer($renderer);
160
-                    $svg = $writer->writeString($provisioningUrl);
161
-
162
-                    $this->assign('svg', $svg);
163
-                    $this->assign('secret', $otpCredentialProvider->getSecret($currentUser));
164
-
165
-                    $this->assignCSRFToken();
166
-                    $this->setTemplate('mfa/enableTotpEnroll.tpl');
167
-
168
-                    return;
169
-                }
170
-                else {
171
-                    SessionAlert::error('Error enabling TOTP - invalid credentials.');
172
-                    $this->redirect('multiFactor');
173
-
174
-                    return;
175
-                }
176
-            }
177
-
178
-            if ($stage === "enroll") {
179
-                // we *must* have a defined credential already here,
180
-                if ($otpCredentialProvider->isPartiallyEnrolled($currentUser)) {
181
-                    $otp = WebRequest::postString('otp');
182
-                    $result = $otpCredentialProvider->verifyEnable($currentUser, $otp);
183
-
184
-                    if ($result) {
185
-                        SessionAlert::success('Enabled TOTP.');
186
-
187
-                        $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
188
-                        if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
189
-                            $scratchProvider->setCredential($currentUser, 2, null);
190
-                            $tokens = $scratchProvider->getTokens();
191
-                            $this->assign('tokens', $tokens);
192
-                            $this->setTemplate('mfa/regenScratchTokens.tpl');
193
-                            return;
194
-                        }
195
-                    }
196
-                    else {
197
-                        $otpCredentialProvider->deleteCredential($currentUser);
198
-                        SessionAlert::error('Error enabling TOTP: invalid token provided');
199
-                    }
200
-
201
-
202
-                    $this->redirect('multiFactor');
203
-                    return;
204
-                }
205
-                else {
206
-                    SessionAlert::error('Error enabling TOTP - no enrollment found or enrollment expired.');
207
-                    $this->redirect('multiFactor');
30
+	/**
31
+	 * Main function for this page, when no specific actions are called.
32
+	 * @return void
33
+	 */
34
+	protected function main()
35
+	{
36
+		$database = $this->getDatabase();
37
+		$currentUser = User::getCurrent($database);
38
+
39
+		$yubikeyOtpCredentialProvider = new YubikeyOtpCredentialProvider($database, $this->getSiteConfiguration(),
40
+			$this->getHttpHelper());
41
+		$this->assign('yubikeyOtpIdentity', $yubikeyOtpCredentialProvider->getYubikeyData($currentUser->getId()));
42
+		$this->assign('yubikeyOtpEnrolled', $yubikeyOtpCredentialProvider->userIsEnrolled($currentUser->getId()));
43
+
44
+		$totpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
45
+		$this->assign('totpEnrolled', $totpCredentialProvider->userIsEnrolled($currentUser->getId()));
46
+
47
+		$u2fCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
48
+		$this->assign('u2fEnrolled', $u2fCredentialProvider->userIsEnrolled($currentUser->getId()));
49
+
50
+		$scratchCredentialProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
51
+		$this->assign('scratchEnrolled', $scratchCredentialProvider->userIsEnrolled($currentUser->getId()));
52
+		$this->assign('scratchRemaining', $scratchCredentialProvider->getRemaining($currentUser->getId()));
53
+
54
+		$this->assign('allowedTotp', $this->barrierTest('enableTotp', $currentUser));
55
+		$this->assign('allowedYubikey', $this->barrierTest('enableYubikeyOtp', $currentUser));
56
+		$this->assign('allowedU2f', $this->barrierTest('enableU2F', $currentUser));
57
+
58
+		$this->setTemplate('mfa/mfa.tpl');
59
+	}
60
+
61
+	protected function enableYubikeyOtp()
62
+	{
63
+		$database = $this->getDatabase();
64
+		$currentUser = User::getCurrent($database);
65
+
66
+		$otpCredentialProvider = new YubikeyOtpCredentialProvider($database,
67
+			$this->getSiteConfiguration(), $this->getHttpHelper());
68
+
69
+		if (WebRequest::wasPosted()) {
70
+			$this->validateCSRFToken();
71
+
72
+			$passwordCredentialProvider = new PasswordCredentialProvider($database,
73
+				$this->getSiteConfiguration());
74
+
75
+			$password = WebRequest::postString('password');
76
+			$otp = WebRequest::postString('otp');
77
+
78
+			$result = $passwordCredentialProvider->authenticate($currentUser, $password);
79
+
80
+			if ($result) {
81
+				try {
82
+					$otpCredentialProvider->setCredential($currentUser, 2, $otp);
83
+					SessionAlert::success('Enabled YubiKey OTP.');
84
+
85
+					$scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
86
+					if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
87
+						$scratchProvider->setCredential($currentUser, 2, null);
88
+						$tokens = $scratchProvider->getTokens();
89
+						$this->assign('tokens', $tokens);
90
+						$this->setTemplate('mfa/regenScratchTokens.tpl');
91
+						return;
92
+					}
93
+				}
94
+				catch (ApplicationLogicException $ex) {
95
+					SessionAlert::error('Error enabling YubiKey OTP: ' . $ex->getMessage());
96
+				}
97
+
98
+				$this->redirect('multiFactor');
99
+			}
100
+			else {
101
+				SessionAlert::error('Error enabling YubiKey OTP - invalid credentials.');
102
+				$this->redirect('multiFactor');
103
+			}
104
+		}
105
+		else {
106
+			if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
107
+				// user is not enrolled, we shouldn't have got here.
108
+				throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
109
+			}
110
+
111
+			$this->assignCSRFToken();
112
+			$this->setTemplate('mfa/enableYubikey.tpl');
113
+		}
114
+	}
115
+
116
+	protected function disableYubikeyOtp()
117
+	{
118
+		$database = $this->getDatabase();
119
+		$currentUser = User::getCurrent($database);
120
+
121
+		$otpCredentialProvider = new YubikeyOtpCredentialProvider($database,
122
+			$this->getSiteConfiguration(), $this->getHttpHelper());
123
+
124
+		$factorType = 'YubiKey OTP';
125
+
126
+		$this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
127
+	}
208 128
 
209
-                    return;
210
-                }
211
-            }
129
+	protected function enableTotp()
130
+	{
131
+		$database = $this->getDatabase();
132
+		$currentUser = User::getCurrent($database);
133
+
134
+		$otpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
135
+
136
+		if (WebRequest::wasPosted()) {
137
+			$this->validateCSRFToken();
138
+
139
+			// used for routing only, not security
140
+			$stage = WebRequest::postString('stage');
141
+
142
+			if ($stage === "auth") {
143
+				$password = WebRequest::postString('password');
144
+
145
+				$passwordCredentialProvider = new PasswordCredentialProvider($database,
146
+					$this->getSiteConfiguration());
147
+				$result = $passwordCredentialProvider->authenticate($currentUser, $password);
148
+
149
+				if ($result) {
150
+					$otpCredentialProvider->setCredential($currentUser, 2, null);
151
+
152
+					$provisioningUrl = $otpCredentialProvider->getProvisioningUrl($currentUser);
153
+
154
+					$renderer = new ImageRenderer(
155
+						new RendererStyle(256),
156
+						new SvgImageBackEnd()
157
+					);
158
+
159
+					$writer = new Writer($renderer);
160
+					$svg = $writer->writeString($provisioningUrl);
161
+
162
+					$this->assign('svg', $svg);
163
+					$this->assign('secret', $otpCredentialProvider->getSecret($currentUser));
164
+
165
+					$this->assignCSRFToken();
166
+					$this->setTemplate('mfa/enableTotpEnroll.tpl');
167
+
168
+					return;
169
+				}
170
+				else {
171
+					SessionAlert::error('Error enabling TOTP - invalid credentials.');
172
+					$this->redirect('multiFactor');
173
+
174
+					return;
175
+				}
176
+			}
177
+
178
+			if ($stage === "enroll") {
179
+				// we *must* have a defined credential already here,
180
+				if ($otpCredentialProvider->isPartiallyEnrolled($currentUser)) {
181
+					$otp = WebRequest::postString('otp');
182
+					$result = $otpCredentialProvider->verifyEnable($currentUser, $otp);
183
+
184
+					if ($result) {
185
+						SessionAlert::success('Enabled TOTP.');
186
+
187
+						$scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
188
+						if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
189
+							$scratchProvider->setCredential($currentUser, 2, null);
190
+							$tokens = $scratchProvider->getTokens();
191
+							$this->assign('tokens', $tokens);
192
+							$this->setTemplate('mfa/regenScratchTokens.tpl');
193
+							return;
194
+						}
195
+					}
196
+					else {
197
+						$otpCredentialProvider->deleteCredential($currentUser);
198
+						SessionAlert::error('Error enabling TOTP: invalid token provided');
199
+					}
200
+
201
+
202
+					$this->redirect('multiFactor');
203
+					return;
204
+				}
205
+				else {
206
+					SessionAlert::error('Error enabling TOTP - no enrollment found or enrollment expired.');
207
+					$this->redirect('multiFactor');
208
+
209
+					return;
210
+				}
211
+			}
212
+
213
+			// urgh, dunno what happened, but it's not something expected.
214
+			throw new ApplicationLogicException();
215
+		}
216
+		else {
217
+			if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
218
+				// user is not enrolled, we shouldn't have got here.
219
+				throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
220
+			}
221
+
222
+			$this->assignCSRFToken();
223
+
224
+			$this->assign('alertmessage', 'To enable your multi-factor credentials, please prove you are who you say you are by providing the information below.');
225
+			$this->assign('alertheader', 'Provide credentials');
226
+			$this->assign('continueText', 'Verify password');
227
+			$this->setTemplate('mfa/enableAuth.tpl');
228
+		}
229
+	}
230
+
231
+	protected function disableTotp()
232
+	{
233
+		$database = $this->getDatabase();
234
+		$currentUser = User::getCurrent($database);
235
+
236
+		$otpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
237
+
238
+		$factorType = 'TOTP';
212 239
 
213
-            // urgh, dunno what happened, but it's not something expected.
214
-            throw new ApplicationLogicException();
215
-        }
216
-        else {
217
-            if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
218
-                // user is not enrolled, we shouldn't have got here.
219
-                throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
220
-            }
240
+		$this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
241
+	}
221 242
 
222
-            $this->assignCSRFToken();
243
+	protected function enableU2F() {
244
+		$database = $this->getDatabase();
245
+		$currentUser = User::getCurrent($database);
223 246
 
224
-            $this->assign('alertmessage', 'To enable your multi-factor credentials, please prove you are who you say you are by providing the information below.');
225
-            $this->assign('alertheader', 'Provide credentials');
226
-            $this->assign('continueText', 'Verify password');
227
-            $this->setTemplate('mfa/enableAuth.tpl');
228
-        }
229
-    }
247
+		$otpCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
230 248
 
231
-    protected function disableTotp()
232
-    {
233
-        $database = $this->getDatabase();
234
-        $currentUser = User::getCurrent($database);
249
+		if (WebRequest::wasPosted()) {
250
+			$this->validateCSRFToken();
235 251
 
236
-        $otpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
252
+			// used for routing only, not security
253
+			$stage = WebRequest::postString('stage');
237 254
 
238
-        $factorType = 'TOTP';
255
+			if ($stage === "auth") {
256
+				$password = WebRequest::postString('password');
239 257
 
240
-        $this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
241
-    }
258
+				$passwordCredentialProvider = new PasswordCredentialProvider($database,
259
+					$this->getSiteConfiguration());
260
+				$result = $passwordCredentialProvider->authenticate($currentUser, $password);
242 261
 
243
-    protected function enableU2F() {
244
-        $database = $this->getDatabase();
245
-        $currentUser = User::getCurrent($database);
262
+				if ($result) {
263
+					$otpCredentialProvider->setCredential($currentUser, 2, null);
264
+					$this->assignCSRFToken();
246 265
 
247
-        $otpCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
266
+					list($data, $reqs) = $otpCredentialProvider->getRegistrationData();
248 267
 
249
-        if (WebRequest::wasPosted()) {
250
-            $this->validateCSRFToken();
268
+					$u2fRequest =json_encode($data);
269
+					$u2fSigns = json_encode($reqs);
251 270
 
252
-            // used for routing only, not security
253
-            $stage = WebRequest::postString('stage');
254
-
255
-            if ($stage === "auth") {
256
-                $password = WebRequest::postString('password');
257
-
258
-                $passwordCredentialProvider = new PasswordCredentialProvider($database,
259
-                    $this->getSiteConfiguration());
260
-                $result = $passwordCredentialProvider->authenticate($currentUser, $password);
261
-
262
-                if ($result) {
263
-                    $otpCredentialProvider->setCredential($currentUser, 2, null);
264
-                    $this->assignCSRFToken();
265
-
266
-                    list($data, $reqs) = $otpCredentialProvider->getRegistrationData();
267
-
268
-                    $u2fRequest =json_encode($data);
269
-                    $u2fSigns = json_encode($reqs);
270
-
271
-                    $this->addJs('/vendor/yubico/u2flib-server/examples/assets/u2f-api.js');
272
-                    $this->setTailScript($this->getCspManager()->getNonce(), <<<JS
271
+					$this->addJs('/vendor/yubico/u2flib-server/examples/assets/u2f-api.js');
272
+					$this->setTailScript($this->getCspManager()->getNonce(), <<<JS
273 273
 var request = ${u2fRequest};
274 274
 var signs = ${u2fSigns};
275 275
 
@@ -288,162 +288,162 @@  discard block
 block discarded – undo
288 288
 	form.submit();
289 289
 });
290 290
 JS
291
-                    );
292
-
293
-                    $this->setTemplate('mfa/enableU2FEnroll.tpl');
294
-
295
-                    return;
296
-                }
297
-                else {
298
-                    SessionAlert::error('Error enabling TOTP - invalid credentials.');
299
-                    $this->redirect('multiFactor');
300
-
301
-                    return;
302
-                }
303
-            }
304
-
305
-            if ($stage === "enroll") {
306
-                // we *must* have a defined credential already here,
307
-                if ($otpCredentialProvider->isPartiallyEnrolled($currentUser)) {
308
-
309
-                    $request = json_decode(WebRequest::postString('u2fRequest'));
310
-                    $u2fData = json_decode(WebRequest::postString('u2fData'));
311
-
312
-                    $otpCredentialProvider->enable($currentUser, $request, $u2fData);
313
-
314
-                    SessionAlert::success('Enabled U2F.');
315
-
316
-                    $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
317
-                    if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
318
-                        $scratchProvider->setCredential($currentUser, 2, null);
319
-                        $tokens = $scratchProvider->getTokens();
320
-                        $this->assign('tokens', $tokens);
321
-                        $this->setTemplate('mfa/regenScratchTokens.tpl');
322
-                        return;
323
-                    }
324
-
325
-                    $this->redirect('multiFactor');
326
-                    return;
327
-                }
328
-                else {
329
-                    SessionAlert::error('Error enabling TOTP - no enrollment found or enrollment expired.');
330
-                    $this->redirect('multiFactor');
331
-
332
-                    return;
333
-                }
334
-            }
335
-
336
-            // urgh, dunno what happened, but it's not something expected.
337
-            throw new ApplicationLogicException();
338
-        }
339
-        else {
340
-            if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
341
-                // user is not enrolled, we shouldn't have got here.
342
-                throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
343
-            }
344
-
345
-            $this->assignCSRFToken();
346
-
347
-            $this->assign('alertmessage', 'To enable your multi-factor credentials, please prove you are who you say you are by providing the information below.');
348
-            $this->assign('alertheader', 'Provide credentials');
349
-            $this->assign('continueText', 'Verify password');
350
-            $this->setTemplate('mfa/enableAuth.tpl');
351
-        }
352
-    }
353
-
354
-    protected function disableU2F() {
355
-        $database = $this->getDatabase();
356
-        $currentUser = User::getCurrent($database);
357
-
358
-        $otpCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
359
-
360
-        $factorType = 'U2F';
361
-
362
-        $this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
363
-    }
364
-
365
-    protected function scratch()
366
-    {
367
-        $database = $this->getDatabase();
368
-        $currentUser = User::getCurrent($database);
369
-
370
-        if (WebRequest::wasPosted()) {
371
-            $this->validateCSRFToken();
372
-
373
-            $passwordCredentialProvider = new PasswordCredentialProvider($database,
374
-                $this->getSiteConfiguration());
375
-
376
-            $otpCredentialProvider = new ScratchTokenCredentialProvider($database,
377
-                $this->getSiteConfiguration());
378
-
379
-            $password = WebRequest::postString('password');
380
-
381
-            $result = $passwordCredentialProvider->authenticate($currentUser, $password);
382
-
383
-            if ($result) {
384
-                $otpCredentialProvider->setCredential($currentUser, 2, null);
385
-                $tokens = $otpCredentialProvider->getTokens();
386
-                $this->assign('tokens', $tokens);
387
-                $this->setTemplate('mfa/regenScratchTokens.tpl');
388
-            }
389
-            else {
390
-                SessionAlert::error('Error refreshing scratch tokens - invalid credentials.');
391
-                $this->redirect('multiFactor');
392
-            }
393
-        }
394
-        else {
395
-            $this->assignCSRFToken();
396
-
397
-            $this->assign('alertmessage', 'To regenerate your emergency scratch tokens, please prove you are who you say you are by providing the information below. Note that continuing will invalidate all remaining scratch tokens, and provide a set of new ones.');
398
-            $this->assign('alertheader', 'Re-generate scratch tokens');
399
-            $this->assign('continueText', 'Regenerate Scratch Tokens');
400
-
401
-            $this->setTemplate('mfa/enableAuth.tpl');
402
-        }
403
-    }
404
-
405
-    /**
406
-     * @param PdoDatabase         $database
407
-     * @param User                $currentUser
408
-     * @param ICredentialProvider $otpCredentialProvider
409
-     * @param string              $factorType
410
-     *
411
-     * @throws ApplicationLogicException
412
-     */
413
-    private function deleteCredential(
414
-        PdoDatabase $database,
415
-        User $currentUser,
416
-        ICredentialProvider $otpCredentialProvider,
417
-        $factorType
418
-    ) {
419
-        if (WebRequest::wasPosted()) {
420
-            $passwordCredentialProvider = new PasswordCredentialProvider($database,
421
-                $this->getSiteConfiguration());
422
-
423
-            $this->validateCSRFToken();
424
-
425
-            $password = WebRequest::postString('password');
426
-            $result = $passwordCredentialProvider->authenticate($currentUser, $password);
427
-
428
-            if ($result) {
429
-                $otpCredentialProvider->deleteCredential($currentUser);
430
-                SessionAlert::success('Disabled ' . $factorType . '.');
431
-                $this->redirect('multiFactor');
432
-            }
433
-            else {
434
-                SessionAlert::error('Error disabling ' . $factorType . ' - invalid credentials.');
435
-                $this->redirect('multiFactor');
436
-            }
437
-        }
438
-        else {
439
-            if (!$otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
440
-                // user is not enrolled, we shouldn't have got here.
441
-                throw new ApplicationLogicException('User is not enrolled in the selected MFA mechanism');
442
-            }
443
-
444
-            $this->assignCSRFToken();
445
-            $this->assign('otpType', $factorType);
446
-            $this->setTemplate('mfa/disableOtp.tpl');
447
-        }
448
-    }
291
+					);
292
+
293
+					$this->setTemplate('mfa/enableU2FEnroll.tpl');
294
+
295
+					return;
296
+				}
297
+				else {
298
+					SessionAlert::error('Error enabling TOTP - invalid credentials.');
299
+					$this->redirect('multiFactor');
300
+
301
+					return;
302
+				}
303
+			}
304
+
305
+			if ($stage === "enroll") {
306
+				// we *must* have a defined credential already here,
307
+				if ($otpCredentialProvider->isPartiallyEnrolled($currentUser)) {
308
+
309
+					$request = json_decode(WebRequest::postString('u2fRequest'));
310
+					$u2fData = json_decode(WebRequest::postString('u2fData'));
311
+
312
+					$otpCredentialProvider->enable($currentUser, $request, $u2fData);
313
+
314
+					SessionAlert::success('Enabled U2F.');
315
+
316
+					$scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
317
+					if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
318
+						$scratchProvider->setCredential($currentUser, 2, null);
319
+						$tokens = $scratchProvider->getTokens();
320
+						$this->assign('tokens', $tokens);
321
+						$this->setTemplate('mfa/regenScratchTokens.tpl');
322
+						return;
323
+					}
324
+
325
+					$this->redirect('multiFactor');
326
+					return;
327
+				}
328
+				else {
329
+					SessionAlert::error('Error enabling TOTP - no enrollment found or enrollment expired.');
330
+					$this->redirect('multiFactor');
331
+
332
+					return;
333
+				}
334
+			}
335
+
336
+			// urgh, dunno what happened, but it's not something expected.
337
+			throw new ApplicationLogicException();
338
+		}
339
+		else {
340
+			if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
341
+				// user is not enrolled, we shouldn't have got here.
342
+				throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
343
+			}
344
+
345
+			$this->assignCSRFToken();
346
+
347
+			$this->assign('alertmessage', 'To enable your multi-factor credentials, please prove you are who you say you are by providing the information below.');
348
+			$this->assign('alertheader', 'Provide credentials');
349
+			$this->assign('continueText', 'Verify password');
350
+			$this->setTemplate('mfa/enableAuth.tpl');
351
+		}
352
+	}
353
+
354
+	protected function disableU2F() {
355
+		$database = $this->getDatabase();
356
+		$currentUser = User::getCurrent($database);
357
+
358
+		$otpCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
359
+
360
+		$factorType = 'U2F';
361
+
362
+		$this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
363
+	}
364
+
365
+	protected function scratch()
366
+	{
367
+		$database = $this->getDatabase();
368
+		$currentUser = User::getCurrent($database);
369
+
370
+		if (WebRequest::wasPosted()) {
371
+			$this->validateCSRFToken();
372
+
373
+			$passwordCredentialProvider = new PasswordCredentialProvider($database,
374
+				$this->getSiteConfiguration());
375
+
376
+			$otpCredentialProvider = new ScratchTokenCredentialProvider($database,
377
+				$this->getSiteConfiguration());
378
+
379
+			$password = WebRequest::postString('password');
380
+
381
+			$result = $passwordCredentialProvider->authenticate($currentUser, $password);
382
+
383
+			if ($result) {
384
+				$otpCredentialProvider->setCredential($currentUser, 2, null);
385
+				$tokens = $otpCredentialProvider->getTokens();
386
+				$this->assign('tokens', $tokens);
387
+				$this->setTemplate('mfa/regenScratchTokens.tpl');
388
+			}
389
+			else {
390
+				SessionAlert::error('Error refreshing scratch tokens - invalid credentials.');
391
+				$this->redirect('multiFactor');
392
+			}
393
+		}
394
+		else {
395
+			$this->assignCSRFToken();
396
+
397
+			$this->assign('alertmessage', 'To regenerate your emergency scratch tokens, please prove you are who you say you are by providing the information below. Note that continuing will invalidate all remaining scratch tokens, and provide a set of new ones.');
398
+			$this->assign('alertheader', 'Re-generate scratch tokens');
399
+			$this->assign('continueText', 'Regenerate Scratch Tokens');
400
+
401
+			$this->setTemplate('mfa/enableAuth.tpl');
402
+		}
403
+	}
404
+
405
+	/**
406
+	 * @param PdoDatabase         $database
407
+	 * @param User                $currentUser
408
+	 * @param ICredentialProvider $otpCredentialProvider
409
+	 * @param string              $factorType
410
+	 *
411
+	 * @throws ApplicationLogicException
412
+	 */
413
+	private function deleteCredential(
414
+		PdoDatabase $database,
415
+		User $currentUser,
416
+		ICredentialProvider $otpCredentialProvider,
417
+		$factorType
418
+	) {
419
+		if (WebRequest::wasPosted()) {
420
+			$passwordCredentialProvider = new PasswordCredentialProvider($database,
421
+				$this->getSiteConfiguration());
422
+
423
+			$this->validateCSRFToken();
424
+
425
+			$password = WebRequest::postString('password');
426
+			$result = $passwordCredentialProvider->authenticate($currentUser, $password);
427
+
428
+			if ($result) {
429
+				$otpCredentialProvider->deleteCredential($currentUser);
430
+				SessionAlert::success('Disabled ' . $factorType . '.');
431
+				$this->redirect('multiFactor');
432
+			}
433
+			else {
434
+				SessionAlert::error('Error disabling ' . $factorType . ' - invalid credentials.');
435
+				$this->redirect('multiFactor');
436
+			}
437
+		}
438
+		else {
439
+			if (!$otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
440
+				// user is not enrolled, we shouldn't have got here.
441
+				throw new ApplicationLogicException('User is not enrolled in the selected MFA mechanism');
442
+			}
443
+
444
+			$this->assignCSRFToken();
445
+			$this->assign('otpType', $factorType);
446
+			$this->setTemplate('mfa/disableOtp.tpl');
447
+		}
448
+	}
449 449
 }
Please login to merge, or discard this patch.