Completed
Push — newinternal-releasecandidate ( ebb0fc...327c61 )
by Simon
09:24
created
includes/Security/RoleConfiguration.php 1 patch
Indentation   +355 added lines, -355 removed lines patch added patch discarded remove patch
@@ -47,386 +47,386 @@
 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
-            ),
114
-            PageChangePassword::class => array(
115
-                self::MAIN => self::ACCESS_ALLOW,
116
-            ),
117
-            PageMultiFactor::class    => array(
118
-                self::MAIN          => self::ACCESS_ALLOW,
119
-                'scratch'           => self::ACCESS_ALLOW,
120
-                'enableYubikeyOtp'  => self::ACCESS_ALLOW,
121
-                'disableYubikeyOtp' => self::ACCESS_ALLOW,
122
-                'enableTotp'        => self::ACCESS_ALLOW,
123
-                'disableTotp'       => self::ACCESS_ALLOW,
124
-            ),
125
-            PageOAuth::class          => array(
126
-                'attach' => self::ACCESS_ALLOW,
127
-                'detach' => self::ACCESS_ALLOW,
128
-            ),
129
-        ),
130
-        'user'              => array(
131
-            '_description'                       => 'A standard tool user.',
132
-            '_editableBy'                        => array('admin', 'toolRoot'),
133
-            '_childRoles'                        => array(
134
-                'internalStats',
135
-            ),
136
-            PageMain::class                      => array(
137
-                self::MAIN => self::ACCESS_ALLOW,
138
-            ),
139
-            PageBan::class                       => array(
140
-                self::MAIN => self::ACCESS_ALLOW,
141
-            ),
142
-            PageEditComment::class               => array(
143
-                self::MAIN => self::ACCESS_ALLOW,
144
-            ),
145
-            PageEmailManagement::class           => array(
146
-                self::MAIN => self::ACCESS_ALLOW,
147
-                'view'     => self::ACCESS_ALLOW,
148
-            ),
149
-            PageExpandedRequestList::class       => array(
150
-                self::MAIN => self::ACCESS_ALLOW,
151
-            ),
152
-            PageLog::class                       => array(
153
-                self::MAIN => self::ACCESS_ALLOW,
154
-            ),
155
-            PageSearch::class                    => array(
156
-                self::MAIN => self::ACCESS_ALLOW,
157
-            ),
158
-            PageWelcomeTemplateManagement::class => array(
159
-                self::MAIN => self::ACCESS_ALLOW,
160
-                'select'   => self::ACCESS_ALLOW,
161
-                'view'     => self::ACCESS_ALLOW,
162
-            ),
163
-            PageViewRequest::class               => array(
164
-                self::MAIN       => self::ACCESS_ALLOW,
165
-                'seeAllRequests' => self::ACCESS_ALLOW,
166
-            ),
167
-            'RequestData'                        => array(
168
-                'seePrivateDataWhenReserved' => self::ACCESS_ALLOW,
169
-                'seePrivateDataWithHash'     => self::ACCESS_ALLOW,
170
-            ),
171
-            PageCustomClose::class               => array(
172
-                self::MAIN => self::ACCESS_ALLOW,
173
-            ),
174
-            PageComment::class                   => array(
175
-                self::MAIN => self::ACCESS_ALLOW,
176
-            ),
177
-            PageCloseRequest::class              => array(
178
-                self::MAIN => self::ACCESS_ALLOW,
179
-            ),
180
-            PageCreateRequest::class             => array(
181
-                self::MAIN => self::ACCESS_ALLOW,
182
-            ),
183
-            PageDeferRequest::class              => array(
184
-                self::MAIN => self::ACCESS_ALLOW,
185
-            ),
186
-            PageDropRequest::class               => array(
187
-                self::MAIN => self::ACCESS_ALLOW,
188
-            ),
189
-            PageReservation::class               => array(
190
-                self::MAIN => self::ACCESS_ALLOW,
191
-            ),
192
-            PageSendToUser::class                => array(
193
-                self::MAIN => self::ACCESS_ALLOW,
194
-            ),
195
-            PageBreakReservation::class          => array(
196
-                self::MAIN => self::ACCESS_ALLOW,
197
-            ),
198
-            PageJobQueue::class                  => array(
199
-                self::MAIN => self::ACCESS_ALLOW,
200
-                'view'     => self::ACCESS_ALLOW,
201
-                'all'      => self::ACCESS_ALLOW,
202
-            ),
203
-            'RequestCreation'                    => array(
204
-                User::CREATION_MANUAL => self::ACCESS_ALLOW,
205
-            ),
206
-        ),
207
-        'admin'             => array(
208
-            '_description'                       => 'A tool administrator.',
209
-            '_editableBy'                        => array('admin', 'toolRoot'),
210
-            '_childRoles'                        => array(
211
-                'user',
212
-                'requestAdminTools',
213
-            ),
214
-            PageEmailManagement::class           => array(
215
-                'edit'   => self::ACCESS_ALLOW,
216
-                'create' => self::ACCESS_ALLOW,
217
-            ),
218
-            PageSiteNotice::class                => array(
219
-                self::MAIN => self::ACCESS_ALLOW,
220
-            ),
221
-            PageUserManagement::class            => array(
222
-                self::MAIN  => self::ACCESS_ALLOW,
223
-                'approve'   => self::ACCESS_ALLOW,
224
-                'decline'   => self::ACCESS_ALLOW,
225
-                'rename'    => self::ACCESS_ALLOW,
226
-                'editUser'  => self::ACCESS_ALLOW,
227
-                'suspend'   => self::ACCESS_ALLOW,
228
-                'editRoles' => self::ACCESS_ALLOW,
229
-            ),
230
-            PageWelcomeTemplateManagement::class => array(
231
-                'edit'   => self::ACCESS_ALLOW,
232
-                'delete' => self::ACCESS_ALLOW,
233
-                'add'    => self::ACCESS_ALLOW,
234
-            ),
235
-            PageJobQueue::class                  => array(
236
-                'acknowledge' => self::ACCESS_ALLOW,
237
-                'requeue'     => self::ACCESS_ALLOW,
238
-            ),
239
-        ),
240
-        'checkuser'         => array(
241
-            '_description'            => 'A user with CheckUser access',
242
-            '_editableBy'             => array('checkuser', 'toolRoot'),
243
-            '_childRoles'             => array(
244
-                'user',
245
-                'requestAdminTools',
246
-            ),
247
-            PageUserManagement::class => array(
248
-                self::MAIN  => self::ACCESS_ALLOW,
249
-                'suspend'   => self::ACCESS_ALLOW,
250
-                'editRoles' => self::ACCESS_ALLOW,
251
-            ),
252
-            'RequestData'             => array(
253
-                'seeUserAgentData' => self::ACCESS_ALLOW,
254
-            ),
255
-        ),
256
-        'toolRoot'          => array(
257
-            '_description' => 'A user with shell access to the servers running the tool',
258
-            '_editableBy'  => array('toolRoot'),
259
-            '_childRoles'  => array(
260
-                'admin',
261
-            ),
262
-            PageMultiFactor::class => array(
263
-                'enableU2F'         => self::ACCESS_ALLOW,
264
-                'disableU2F'        => self::ACCESS_ALLOW,
265
-            )
266
-        ),
267
-        'botCreation'       => array(
268
-            '_description'    => 'A user allowed to use the bot to perform account creations',
269
-            '_editableBy'     => array('admin', 'toolRoot'),
270
-            '_childRoles'     => array(),
271
-            'RequestCreation' => array(
272
-                User::CREATION_BOT => self::ACCESS_ALLOW,
273
-            ),
274
-        ),
275
-        'oauthCreation'       => array(
276
-            '_description'    => 'A user allowed to use the OAuth to perform account creations',
277
-            '_editableBy'     => array('admin', 'toolRoot'),
278
-            '_childRoles'     => array(),
279
-            'RequestCreation'                    => array(
280
-                User::CREATION_OAUTH  => self::ACCESS_ALLOW,
281
-            ),
282
-        ),
108
+			'_childRoles'             => array(
109
+				'public',
110
+			),
111
+			PagePreferences::class    => array(
112
+				self::MAIN => self::ACCESS_ALLOW,
113
+			),
114
+			PageChangePassword::class => array(
115
+				self::MAIN => self::ACCESS_ALLOW,
116
+			),
117
+			PageMultiFactor::class    => array(
118
+				self::MAIN          => self::ACCESS_ALLOW,
119
+				'scratch'           => self::ACCESS_ALLOW,
120
+				'enableYubikeyOtp'  => self::ACCESS_ALLOW,
121
+				'disableYubikeyOtp' => self::ACCESS_ALLOW,
122
+				'enableTotp'        => self::ACCESS_ALLOW,
123
+				'disableTotp'       => self::ACCESS_ALLOW,
124
+			),
125
+			PageOAuth::class          => array(
126
+				'attach' => self::ACCESS_ALLOW,
127
+				'detach' => self::ACCESS_ALLOW,
128
+			),
129
+		),
130
+		'user'              => array(
131
+			'_description'                       => 'A standard tool user.',
132
+			'_editableBy'                        => array('admin', 'toolRoot'),
133
+			'_childRoles'                        => array(
134
+				'internalStats',
135
+			),
136
+			PageMain::class                      => array(
137
+				self::MAIN => self::ACCESS_ALLOW,
138
+			),
139
+			PageBan::class                       => array(
140
+				self::MAIN => self::ACCESS_ALLOW,
141
+			),
142
+			PageEditComment::class               => array(
143
+				self::MAIN => self::ACCESS_ALLOW,
144
+			),
145
+			PageEmailManagement::class           => array(
146
+				self::MAIN => self::ACCESS_ALLOW,
147
+				'view'     => self::ACCESS_ALLOW,
148
+			),
149
+			PageExpandedRequestList::class       => array(
150
+				self::MAIN => self::ACCESS_ALLOW,
151
+			),
152
+			PageLog::class                       => array(
153
+				self::MAIN => self::ACCESS_ALLOW,
154
+			),
155
+			PageSearch::class                    => array(
156
+				self::MAIN => self::ACCESS_ALLOW,
157
+			),
158
+			PageWelcomeTemplateManagement::class => array(
159
+				self::MAIN => self::ACCESS_ALLOW,
160
+				'select'   => self::ACCESS_ALLOW,
161
+				'view'     => self::ACCESS_ALLOW,
162
+			),
163
+			PageViewRequest::class               => array(
164
+				self::MAIN       => self::ACCESS_ALLOW,
165
+				'seeAllRequests' => self::ACCESS_ALLOW,
166
+			),
167
+			'RequestData'                        => array(
168
+				'seePrivateDataWhenReserved' => self::ACCESS_ALLOW,
169
+				'seePrivateDataWithHash'     => self::ACCESS_ALLOW,
170
+			),
171
+			PageCustomClose::class               => array(
172
+				self::MAIN => self::ACCESS_ALLOW,
173
+			),
174
+			PageComment::class                   => array(
175
+				self::MAIN => self::ACCESS_ALLOW,
176
+			),
177
+			PageCloseRequest::class              => array(
178
+				self::MAIN => self::ACCESS_ALLOW,
179
+			),
180
+			PageCreateRequest::class             => array(
181
+				self::MAIN => self::ACCESS_ALLOW,
182
+			),
183
+			PageDeferRequest::class              => array(
184
+				self::MAIN => self::ACCESS_ALLOW,
185
+			),
186
+			PageDropRequest::class               => array(
187
+				self::MAIN => self::ACCESS_ALLOW,
188
+			),
189
+			PageReservation::class               => array(
190
+				self::MAIN => self::ACCESS_ALLOW,
191
+			),
192
+			PageSendToUser::class                => array(
193
+				self::MAIN => self::ACCESS_ALLOW,
194
+			),
195
+			PageBreakReservation::class          => array(
196
+				self::MAIN => self::ACCESS_ALLOW,
197
+			),
198
+			PageJobQueue::class                  => array(
199
+				self::MAIN => self::ACCESS_ALLOW,
200
+				'view'     => self::ACCESS_ALLOW,
201
+				'all'      => self::ACCESS_ALLOW,
202
+			),
203
+			'RequestCreation'                    => array(
204
+				User::CREATION_MANUAL => self::ACCESS_ALLOW,
205
+			),
206
+		),
207
+		'admin'             => array(
208
+			'_description'                       => 'A tool administrator.',
209
+			'_editableBy'                        => array('admin', 'toolRoot'),
210
+			'_childRoles'                        => array(
211
+				'user',
212
+				'requestAdminTools',
213
+			),
214
+			PageEmailManagement::class           => array(
215
+				'edit'   => self::ACCESS_ALLOW,
216
+				'create' => self::ACCESS_ALLOW,
217
+			),
218
+			PageSiteNotice::class                => array(
219
+				self::MAIN => self::ACCESS_ALLOW,
220
+			),
221
+			PageUserManagement::class            => array(
222
+				self::MAIN  => self::ACCESS_ALLOW,
223
+				'approve'   => self::ACCESS_ALLOW,
224
+				'decline'   => self::ACCESS_ALLOW,
225
+				'rename'    => self::ACCESS_ALLOW,
226
+				'editUser'  => self::ACCESS_ALLOW,
227
+				'suspend'   => self::ACCESS_ALLOW,
228
+				'editRoles' => self::ACCESS_ALLOW,
229
+			),
230
+			PageWelcomeTemplateManagement::class => array(
231
+				'edit'   => self::ACCESS_ALLOW,
232
+				'delete' => self::ACCESS_ALLOW,
233
+				'add'    => self::ACCESS_ALLOW,
234
+			),
235
+			PageJobQueue::class                  => array(
236
+				'acknowledge' => self::ACCESS_ALLOW,
237
+				'requeue'     => self::ACCESS_ALLOW,
238
+			),
239
+		),
240
+		'checkuser'         => array(
241
+			'_description'            => 'A user with CheckUser access',
242
+			'_editableBy'             => array('checkuser', 'toolRoot'),
243
+			'_childRoles'             => array(
244
+				'user',
245
+				'requestAdminTools',
246
+			),
247
+			PageUserManagement::class => array(
248
+				self::MAIN  => self::ACCESS_ALLOW,
249
+				'suspend'   => self::ACCESS_ALLOW,
250
+				'editRoles' => self::ACCESS_ALLOW,
251
+			),
252
+			'RequestData'             => array(
253
+				'seeUserAgentData' => self::ACCESS_ALLOW,
254
+			),
255
+		),
256
+		'toolRoot'          => array(
257
+			'_description' => 'A user with shell access to the servers running the tool',
258
+			'_editableBy'  => array('toolRoot'),
259
+			'_childRoles'  => array(
260
+				'admin',
261
+			),
262
+			PageMultiFactor::class => array(
263
+				'enableU2F'         => self::ACCESS_ALLOW,
264
+				'disableU2F'        => self::ACCESS_ALLOW,
265
+			)
266
+		),
267
+		'botCreation'       => array(
268
+			'_description'    => 'A user allowed to use the bot to perform account creations',
269
+			'_editableBy'     => array('admin', 'toolRoot'),
270
+			'_childRoles'     => array(),
271
+			'RequestCreation' => array(
272
+				User::CREATION_BOT => self::ACCESS_ALLOW,
273
+			),
274
+		),
275
+		'oauthCreation'       => array(
276
+			'_description'    => 'A user allowed to use the OAuth to perform account creations',
277
+			'_editableBy'     => array('admin', 'toolRoot'),
278
+			'_childRoles'     => array(),
279
+			'RequestCreation'                    => array(
280
+				User::CREATION_OAUTH  => self::ACCESS_ALLOW,
281
+			),
282
+		),
283 283
 
284 284
 
285
-        // Child roles go below this point
286
-        'publicStats'       => array(
287
-            '_hidden'               => true,
288
-            StatsUsers::class       => array(
289
-                self::MAIN => self::ACCESS_ALLOW,
290
-                'detail'   => self::ACCESS_ALLOW,
291
-            ),
292
-            StatsTopCreators::class => array(
293
-                self::MAIN => self::ACCESS_ALLOW,
294
-            ),
295
-        ),
296
-        'internalStats'     => array(
297
-            '_hidden'                    => true,
298
-            StatsMain::class             => array(
299
-                self::MAIN => self::ACCESS_ALLOW,
300
-            ),
301
-            StatsFastCloses::class       => array(
302
-                self::MAIN => self::ACCESS_ALLOW,
303
-            ),
304
-            StatsInactiveUsers::class    => array(
305
-                self::MAIN => self::ACCESS_ALLOW,
306
-            ),
307
-            StatsMonthlyStats::class     => array(
308
-                self::MAIN => self::ACCESS_ALLOW,
309
-            ),
310
-            StatsReservedRequests::class => array(
311
-                self::MAIN => self::ACCESS_ALLOW,
312
-            ),
313
-            StatsTemplateStats::class    => array(
314
-                self::MAIN => self::ACCESS_ALLOW,
315
-            ),
316
-        ),
317
-        'requestAdminTools' => array(
318
-            '_hidden'                   => true,
319
-            PageBan::class              => array(
320
-                self::MAIN => self::ACCESS_ALLOW,
321
-                'set'      => self::ACCESS_ALLOW,
322
-                'remove'   => self::ACCESS_ALLOW,
323
-            ),
324
-            PageEditComment::class      => array(
325
-                'editOthers' => self::ACCESS_ALLOW,
326
-            ),
327
-            PageBreakReservation::class => array(
328
-                'force' => self::ACCESS_ALLOW,
329
-            ),
330
-            PageCustomClose::class      => array(
331
-                'skipCcMailingList' => self::ACCESS_ALLOW,
332
-            ),
333
-            'RequestData'               => array(
334
-                'reopenOldRequest'      => self::ACCESS_ALLOW,
335
-                'alwaysSeePrivateData'  => self::ACCESS_ALLOW,
336
-                'alwaysSeeHash'         => self::ACCESS_ALLOW,
337
-                'seeRestrictedComments' => self::ACCESS_ALLOW,
338
-            ),
339
-        ),
340
-    );
341
-    /** @var array
342
-     * List of roles which are *exempt* from the identification requirements
343
-     *
344
-     * Think twice about adding roles to this list.
345
-     *
346
-     * @category Security-Critical
347
-     */
348
-    private $identificationExempt = array('public', 'loggedIn');
285
+		// Child roles go below this point
286
+		'publicStats'       => array(
287
+			'_hidden'               => true,
288
+			StatsUsers::class       => array(
289
+				self::MAIN => self::ACCESS_ALLOW,
290
+				'detail'   => self::ACCESS_ALLOW,
291
+			),
292
+			StatsTopCreators::class => array(
293
+				self::MAIN => self::ACCESS_ALLOW,
294
+			),
295
+		),
296
+		'internalStats'     => array(
297
+			'_hidden'                    => true,
298
+			StatsMain::class             => array(
299
+				self::MAIN => self::ACCESS_ALLOW,
300
+			),
301
+			StatsFastCloses::class       => array(
302
+				self::MAIN => self::ACCESS_ALLOW,
303
+			),
304
+			StatsInactiveUsers::class    => array(
305
+				self::MAIN => self::ACCESS_ALLOW,
306
+			),
307
+			StatsMonthlyStats::class     => array(
308
+				self::MAIN => self::ACCESS_ALLOW,
309
+			),
310
+			StatsReservedRequests::class => array(
311
+				self::MAIN => self::ACCESS_ALLOW,
312
+			),
313
+			StatsTemplateStats::class    => array(
314
+				self::MAIN => self::ACCESS_ALLOW,
315
+			),
316
+		),
317
+		'requestAdminTools' => array(
318
+			'_hidden'                   => true,
319
+			PageBan::class              => array(
320
+				self::MAIN => self::ACCESS_ALLOW,
321
+				'set'      => self::ACCESS_ALLOW,
322
+				'remove'   => self::ACCESS_ALLOW,
323
+			),
324
+			PageEditComment::class      => array(
325
+				'editOthers' => self::ACCESS_ALLOW,
326
+			),
327
+			PageBreakReservation::class => array(
328
+				'force' => self::ACCESS_ALLOW,
329
+			),
330
+			PageCustomClose::class      => array(
331
+				'skipCcMailingList' => self::ACCESS_ALLOW,
332
+			),
333
+			'RequestData'               => array(
334
+				'reopenOldRequest'      => self::ACCESS_ALLOW,
335
+				'alwaysSeePrivateData'  => self::ACCESS_ALLOW,
336
+				'alwaysSeeHash'         => self::ACCESS_ALLOW,
337
+				'seeRestrictedComments' => self::ACCESS_ALLOW,
338
+			),
339
+		),
340
+	);
341
+	/** @var array
342
+	 * List of roles which are *exempt* from the identification requirements
343
+	 *
344
+	 * Think twice about adding roles to this list.
345
+	 *
346
+	 * @category Security-Critical
347
+	 */
348
+	private $identificationExempt = array('public', 'loggedIn');
349 349
 
350
-    /**
351
-     * RoleConfiguration constructor.
352
-     *
353
-     * @param array $roleConfig           Set to non-null to override the default configuration.
354
-     * @param array $identificationExempt Set to non-null to override the default configuration.
355
-     */
356
-    public function __construct(array $roleConfig = null, array $identificationExempt = null)
357
-    {
358
-        if ($roleConfig !== null) {
359
-            $this->roleConfig = $roleConfig;
360
-        }
350
+	/**
351
+	 * RoleConfiguration constructor.
352
+	 *
353
+	 * @param array $roleConfig           Set to non-null to override the default configuration.
354
+	 * @param array $identificationExempt Set to non-null to override the default configuration.
355
+	 */
356
+	public function __construct(array $roleConfig = null, array $identificationExempt = null)
357
+	{
358
+		if ($roleConfig !== null) {
359
+			$this->roleConfig = $roleConfig;
360
+		}
361 361
 
362
-        if ($identificationExempt !== null) {
363
-            $this->identificationExempt = $identificationExempt;
364
-        }
365
-    }
362
+		if ($identificationExempt !== null) {
363
+			$this->identificationExempt = $identificationExempt;
364
+		}
365
+	}
366 366
 
367
-    /**
368
-     * @param array $roles The roles to check
369
-     *
370
-     * @return array
371
-     */
372
-    public function getApplicableRoles(array $roles)
373
-    {
374
-        $available = array();
367
+	/**
368
+	 * @param array $roles The roles to check
369
+	 *
370
+	 * @return array
371
+	 */
372
+	public function getApplicableRoles(array $roles)
373
+	{
374
+		$available = array();
375 375
 
376
-        foreach ($roles as $role) {
377
-            if (!isset($this->roleConfig[$role])) {
378
-                // wat
379
-                continue;
380
-            }
376
+		foreach ($roles as $role) {
377
+			if (!isset($this->roleConfig[$role])) {
378
+				// wat
379
+				continue;
380
+			}
381 381
 
382
-            $available[$role] = $this->roleConfig[$role];
382
+			$available[$role] = $this->roleConfig[$role];
383 383
 
384
-            if (isset($available[$role]['_childRoles'])) {
385
-                $childRoles = self::getApplicableRoles($available[$role]['_childRoles']);
386
-                $available = array_merge($available, $childRoles);
384
+			if (isset($available[$role]['_childRoles'])) {
385
+				$childRoles = self::getApplicableRoles($available[$role]['_childRoles']);
386
+				$available = array_merge($available, $childRoles);
387 387
 
388
-                unset($available[$role]['_childRoles']);
389
-            }
388
+				unset($available[$role]['_childRoles']);
389
+			}
390 390
 
391
-            foreach (array('_hidden', '_editableBy', '_description') as $item) {
392
-                if (isset($available[$role][$item])) {
393
-                    unset($available[$role][$item]);
394
-                }
395
-            }
396
-        }
391
+			foreach (array('_hidden', '_editableBy', '_description') as $item) {
392
+				if (isset($available[$role][$item])) {
393
+					unset($available[$role][$item]);
394
+				}
395
+			}
396
+		}
397 397
 
398
-        return $available;
399
-    }
398
+		return $available;
399
+	}
400 400
 
401
-    public function getAvailableRoles()
402
-    {
403
-        $possible = array_diff(array_keys($this->roleConfig), array('public', 'loggedIn'));
401
+	public function getAvailableRoles()
402
+	{
403
+		$possible = array_diff(array_keys($this->roleConfig), array('public', 'loggedIn'));
404 404
 
405
-        $actual = array();
405
+		$actual = array();
406 406
 
407
-        foreach ($possible as $role) {
408
-            if (!isset($this->roleConfig[$role]['_hidden'])) {
409
-                $actual[$role] = array(
410
-                    'description' => $this->roleConfig[$role]['_description'],
411
-                    'editableBy'  => $this->roleConfig[$role]['_editableBy'],
412
-                );
413
-            }
414
-        }
407
+		foreach ($possible as $role) {
408
+			if (!isset($this->roleConfig[$role]['_hidden'])) {
409
+				$actual[$role] = array(
410
+					'description' => $this->roleConfig[$role]['_description'],
411
+					'editableBy'  => $this->roleConfig[$role]['_editableBy'],
412
+				);
413
+			}
414
+		}
415 415
 
416
-        return $actual;
417
-    }
416
+		return $actual;
417
+	}
418 418
 
419
-    /**
420
-     * @param string $role
421
-     *
422
-     * @return bool
423
-     */
424
-    public function roleNeedsIdentification($role)
425
-    {
426
-        if (in_array($role, $this->identificationExempt)) {
427
-            return false;
428
-        }
419
+	/**
420
+	 * @param string $role
421
+	 *
422
+	 * @return bool
423
+	 */
424
+	public function roleNeedsIdentification($role)
425
+	{
426
+		if (in_array($role, $this->identificationExempt)) {
427
+			return false;
428
+		}
429 429
 
430
-        return true;
431
-    }
430
+		return true;
431
+	}
432 432
 }
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
@@ -25,247 +25,247 @@  discard block
 block discarded – undo
25 25
 
26 26
 class PageMultiFactor extends InternalPageBase
27 27
 {
28
-    /**
29
-     * Main function for this page, when no specific actions are called.
30
-     * @return void
31
-     */
32
-    protected function main()
33
-    {
34
-        $database = $this->getDatabase();
35
-        $currentUser = User::getCurrent($database);
36
-
37
-        $yubikeyOtpCredentialProvider = new YubikeyOtpCredentialProvider($database, $this->getSiteConfiguration(),
38
-            $this->getHttpHelper());
39
-        $this->assign('yubikeyOtpIdentity', $yubikeyOtpCredentialProvider->getYubikeyData($currentUser->getId()));
40
-        $this->assign('yubikeyOtpEnrolled', $yubikeyOtpCredentialProvider->userIsEnrolled($currentUser->getId()));
41
-
42
-        $totpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
43
-        $this->assign('totpEnrolled', $totpCredentialProvider->userIsEnrolled($currentUser->getId()));
44
-
45
-        $u2fCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
46
-        $this->assign('u2fEnrolled', $u2fCredentialProvider->userIsEnrolled($currentUser->getId()));
47
-
48
-        $scratchCredentialProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
49
-        $this->assign('scratchEnrolled', $scratchCredentialProvider->userIsEnrolled($currentUser->getId()));
50
-        $this->assign('scratchRemaining', $scratchCredentialProvider->getRemaining($currentUser->getId()));
51
-
52
-        $this->assign('allowedTotp', $this->barrierTest('enableTotp', $currentUser));
53
-        $this->assign('allowedYubikey', $this->barrierTest('enableYubikeyOtp', $currentUser));
54
-        $this->assign('allowedU2f', $this->barrierTest('enableU2F', $currentUser));
55
-
56
-        $this->setTemplate('mfa/mfa.tpl');
57
-    }
58
-
59
-    protected function enableYubikeyOtp()
60
-    {
61
-        $database = $this->getDatabase();
62
-        $currentUser = User::getCurrent($database);
63
-
64
-        $otpCredentialProvider = new YubikeyOtpCredentialProvider($database,
65
-            $this->getSiteConfiguration(), $this->getHttpHelper());
66
-
67
-        if (WebRequest::wasPosted()) {
68
-            $this->validateCSRFToken();
69
-
70
-            $passwordCredentialProvider = new PasswordCredentialProvider($database,
71
-                $this->getSiteConfiguration());
72
-
73
-            $password = WebRequest::postString('password');
74
-            $otp = WebRequest::postString('otp');
75
-
76
-            $result = $passwordCredentialProvider->authenticate($currentUser, $password);
77
-
78
-            if ($result) {
79
-                try {
80
-                    $otpCredentialProvider->setCredential($currentUser, 2, $otp);
81
-                    SessionAlert::success('Enabled YubiKey OTP.');
82
-
83
-                    $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
84
-                    if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
85
-                        $scratchProvider->setCredential($currentUser, 2, null);
86
-                        $tokens = $scratchProvider->getTokens();
87
-                        $this->assign('tokens', $tokens);
88
-                        $this->setTemplate('mfa/regenScratchTokens.tpl');
89
-                        return;
90
-                    }
91
-                }
92
-                catch (ApplicationLogicException $ex) {
93
-                    SessionAlert::error('Error enabling YubiKey OTP: ' . $ex->getMessage());
94
-                }
95
-
96
-                $this->redirect('multiFactor');
97
-            }
98
-            else {
99
-                SessionAlert::error('Error enabling YubiKey OTP - invalid credentials.');
100
-                $this->redirect('multiFactor');
101
-            }
102
-        }
103
-        else {
104
-            if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
105
-                // user is not enrolled, we shouldn't have got here.
106
-                throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
107
-            }
108
-
109
-            $this->assignCSRFToken();
110
-            $this->setTemplate('mfa/enableYubikey.tpl');
111
-        }
112
-    }
113
-
114
-    protected function disableYubikeyOtp()
115
-    {
116
-        $database = $this->getDatabase();
117
-        $currentUser = User::getCurrent($database);
118
-
119
-        $otpCredentialProvider = new YubikeyOtpCredentialProvider($database,
120
-            $this->getSiteConfiguration(), $this->getHttpHelper());
121
-
122
-        $factorType = 'YubiKey OTP';
123
-
124
-        $this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
125
-    }
126
-
127
-    protected function enableTotp()
128
-    {
129
-        $database = $this->getDatabase();
130
-        $currentUser = User::getCurrent($database);
131
-
132
-        $otpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
133
-
134
-        if (WebRequest::wasPosted()) {
135
-            $this->validateCSRFToken();
136
-
137
-            // used for routing only, not security
138
-            $stage = WebRequest::postString('stage');
139
-
140
-            if ($stage === "auth") {
141
-                $password = WebRequest::postString('password');
142
-
143
-                $passwordCredentialProvider = new PasswordCredentialProvider($database,
144
-                    $this->getSiteConfiguration());
145
-                $result = $passwordCredentialProvider->authenticate($currentUser, $password);
146
-
147
-                if ($result) {
148
-                    $otpCredentialProvider->setCredential($currentUser, 2, null);
149
-
150
-                    $provisioningUrl = $otpCredentialProvider->getProvisioningUrl($currentUser);
151
-
152
-                    $renderer = new Svg();
153
-                    $renderer->setHeight(256);
154
-                    $renderer->setWidth(256);
155
-                    $writer = new Writer($renderer);
156
-                    $svg = $writer->writeString($provisioningUrl);
157
-
158
-                    $this->assign('svg', $svg);
159
-                    $this->assign('secret', $otpCredentialProvider->getSecret($currentUser));
160
-
161
-                    $this->assignCSRFToken();
162
-                    $this->setTemplate('mfa/enableTotpEnroll.tpl');
163
-
164
-                    return;
165
-                }
166
-                else {
167
-                    SessionAlert::error('Error enabling TOTP - invalid credentials.');
168
-                    $this->redirect('multiFactor');
169
-
170
-                    return;
171
-                }
172
-            }
173
-
174
-            if ($stage === "enroll") {
175
-                // we *must* have a defined credential already here,
176
-                if ($otpCredentialProvider->isPartiallyEnrolled($currentUser)) {
177
-                    $otp = WebRequest::postString('otp');
178
-                    $result = $otpCredentialProvider->verifyEnable($currentUser, $otp);
179
-
180
-                    if ($result) {
181
-                        SessionAlert::success('Enabled TOTP.');
182
-
183
-                        $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
184
-                        if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
185
-                            $scratchProvider->setCredential($currentUser, 2, null);
186
-                            $tokens = $scratchProvider->getTokens();
187
-                            $this->assign('tokens', $tokens);
188
-                            $this->setTemplate('mfa/regenScratchTokens.tpl');
189
-                            return;
190
-                        }
191
-                    }
192
-                    else {
193
-                        $otpCredentialProvider->deleteCredential($currentUser);
194
-                        SessionAlert::error('Error enabling TOTP: invalid token provided');
195
-                    }
196
-
197
-
198
-                    $this->redirect('multiFactor');
199
-                    return;
200
-                }
201
-                else {
202
-                    SessionAlert::error('Error enabling TOTP - no enrollment found or enrollment expired.');
203
-                    $this->redirect('multiFactor');
28
+	/**
29
+	 * Main function for this page, when no specific actions are called.
30
+	 * @return void
31
+	 */
32
+	protected function main()
33
+	{
34
+		$database = $this->getDatabase();
35
+		$currentUser = User::getCurrent($database);
36
+
37
+		$yubikeyOtpCredentialProvider = new YubikeyOtpCredentialProvider($database, $this->getSiteConfiguration(),
38
+			$this->getHttpHelper());
39
+		$this->assign('yubikeyOtpIdentity', $yubikeyOtpCredentialProvider->getYubikeyData($currentUser->getId()));
40
+		$this->assign('yubikeyOtpEnrolled', $yubikeyOtpCredentialProvider->userIsEnrolled($currentUser->getId()));
41
+
42
+		$totpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
43
+		$this->assign('totpEnrolled', $totpCredentialProvider->userIsEnrolled($currentUser->getId()));
44
+
45
+		$u2fCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
46
+		$this->assign('u2fEnrolled', $u2fCredentialProvider->userIsEnrolled($currentUser->getId()));
47
+
48
+		$scratchCredentialProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
49
+		$this->assign('scratchEnrolled', $scratchCredentialProvider->userIsEnrolled($currentUser->getId()));
50
+		$this->assign('scratchRemaining', $scratchCredentialProvider->getRemaining($currentUser->getId()));
51
+
52
+		$this->assign('allowedTotp', $this->barrierTest('enableTotp', $currentUser));
53
+		$this->assign('allowedYubikey', $this->barrierTest('enableYubikeyOtp', $currentUser));
54
+		$this->assign('allowedU2f', $this->barrierTest('enableU2F', $currentUser));
55
+
56
+		$this->setTemplate('mfa/mfa.tpl');
57
+	}
204 58
 
205
-                    return;
206
-                }
207
-            }
59
+	protected function enableYubikeyOtp()
60
+	{
61
+		$database = $this->getDatabase();
62
+		$currentUser = User::getCurrent($database);
63
+
64
+		$otpCredentialProvider = new YubikeyOtpCredentialProvider($database,
65
+			$this->getSiteConfiguration(), $this->getHttpHelper());
66
+
67
+		if (WebRequest::wasPosted()) {
68
+			$this->validateCSRFToken();
69
+
70
+			$passwordCredentialProvider = new PasswordCredentialProvider($database,
71
+				$this->getSiteConfiguration());
72
+
73
+			$password = WebRequest::postString('password');
74
+			$otp = WebRequest::postString('otp');
75
+
76
+			$result = $passwordCredentialProvider->authenticate($currentUser, $password);
77
+
78
+			if ($result) {
79
+				try {
80
+					$otpCredentialProvider->setCredential($currentUser, 2, $otp);
81
+					SessionAlert::success('Enabled YubiKey OTP.');
82
+
83
+					$scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
84
+					if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
85
+						$scratchProvider->setCredential($currentUser, 2, null);
86
+						$tokens = $scratchProvider->getTokens();
87
+						$this->assign('tokens', $tokens);
88
+						$this->setTemplate('mfa/regenScratchTokens.tpl');
89
+						return;
90
+					}
91
+				}
92
+				catch (ApplicationLogicException $ex) {
93
+					SessionAlert::error('Error enabling YubiKey OTP: ' . $ex->getMessage());
94
+				}
95
+
96
+				$this->redirect('multiFactor');
97
+			}
98
+			else {
99
+				SessionAlert::error('Error enabling YubiKey OTP - invalid credentials.');
100
+				$this->redirect('multiFactor');
101
+			}
102
+		}
103
+		else {
104
+			if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
105
+				// user is not enrolled, we shouldn't have got here.
106
+				throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
107
+			}
108
+
109
+			$this->assignCSRFToken();
110
+			$this->setTemplate('mfa/enableYubikey.tpl');
111
+		}
112
+	}
208 113
 
209
-            // urgh, dunno what happened, but it's not something expected.
210
-            throw new ApplicationLogicException();
211
-        }
212
-        else {
213
-            if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
214
-                // user is not enrolled, we shouldn't have got here.
215
-                throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
216
-            }
114
+	protected function disableYubikeyOtp()
115
+	{
116
+		$database = $this->getDatabase();
117
+		$currentUser = User::getCurrent($database);
217 118
 
218
-            $this->assignCSRFToken();
119
+		$otpCredentialProvider = new YubikeyOtpCredentialProvider($database,
120
+			$this->getSiteConfiguration(), $this->getHttpHelper());
219 121
 
220
-            $this->assign('alertmessage', 'To enable your multi-factor credentials, please prove you are who you say you are by providing the information below.');
221
-            $this->assign('alertheader', 'Provide credentials');
222
-            $this->assign('continueText', 'Verify password');
223
-            $this->setTemplate('mfa/enableAuth.tpl');
224
-        }
225
-    }
122
+		$factorType = 'YubiKey OTP';
226 123
 
227
-    protected function disableTotp()
228
-    {
229
-        $database = $this->getDatabase();
230
-        $currentUser = User::getCurrent($database);
124
+		$this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
125
+	}
126
+
127
+	protected function enableTotp()
128
+	{
129
+		$database = $this->getDatabase();
130
+		$currentUser = User::getCurrent($database);
131
+
132
+		$otpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
133
+
134
+		if (WebRequest::wasPosted()) {
135
+			$this->validateCSRFToken();
136
+
137
+			// used for routing only, not security
138
+			$stage = WebRequest::postString('stage');
139
+
140
+			if ($stage === "auth") {
141
+				$password = WebRequest::postString('password');
142
+
143
+				$passwordCredentialProvider = new PasswordCredentialProvider($database,
144
+					$this->getSiteConfiguration());
145
+				$result = $passwordCredentialProvider->authenticate($currentUser, $password);
146
+
147
+				if ($result) {
148
+					$otpCredentialProvider->setCredential($currentUser, 2, null);
149
+
150
+					$provisioningUrl = $otpCredentialProvider->getProvisioningUrl($currentUser);
151
+
152
+					$renderer = new Svg();
153
+					$renderer->setHeight(256);
154
+					$renderer->setWidth(256);
155
+					$writer = new Writer($renderer);
156
+					$svg = $writer->writeString($provisioningUrl);
157
+
158
+					$this->assign('svg', $svg);
159
+					$this->assign('secret', $otpCredentialProvider->getSecret($currentUser));
160
+
161
+					$this->assignCSRFToken();
162
+					$this->setTemplate('mfa/enableTotpEnroll.tpl');
163
+
164
+					return;
165
+				}
166
+				else {
167
+					SessionAlert::error('Error enabling TOTP - invalid credentials.');
168
+					$this->redirect('multiFactor');
169
+
170
+					return;
171
+				}
172
+			}
173
+
174
+			if ($stage === "enroll") {
175
+				// we *must* have a defined credential already here,
176
+				if ($otpCredentialProvider->isPartiallyEnrolled($currentUser)) {
177
+					$otp = WebRequest::postString('otp');
178
+					$result = $otpCredentialProvider->verifyEnable($currentUser, $otp);
179
+
180
+					if ($result) {
181
+						SessionAlert::success('Enabled TOTP.');
182
+
183
+						$scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
184
+						if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
185
+							$scratchProvider->setCredential($currentUser, 2, null);
186
+							$tokens = $scratchProvider->getTokens();
187
+							$this->assign('tokens', $tokens);
188
+							$this->setTemplate('mfa/regenScratchTokens.tpl');
189
+							return;
190
+						}
191
+					}
192
+					else {
193
+						$otpCredentialProvider->deleteCredential($currentUser);
194
+						SessionAlert::error('Error enabling TOTP: invalid token provided');
195
+					}
196
+
197
+
198
+					$this->redirect('multiFactor');
199
+					return;
200
+				}
201
+				else {
202
+					SessionAlert::error('Error enabling TOTP - no enrollment found or enrollment expired.');
203
+					$this->redirect('multiFactor');
204
+
205
+					return;
206
+				}
207
+			}
208
+
209
+			// urgh, dunno what happened, but it's not something expected.
210
+			throw new ApplicationLogicException();
211
+		}
212
+		else {
213
+			if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
214
+				// user is not enrolled, we shouldn't have got here.
215
+				throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
216
+			}
217
+
218
+			$this->assignCSRFToken();
219
+
220
+			$this->assign('alertmessage', 'To enable your multi-factor credentials, please prove you are who you say you are by providing the information below.');
221
+			$this->assign('alertheader', 'Provide credentials');
222
+			$this->assign('continueText', 'Verify password');
223
+			$this->setTemplate('mfa/enableAuth.tpl');
224
+		}
225
+	}
231 226
 
232
-        $otpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
227
+	protected function disableTotp()
228
+	{
229
+		$database = $this->getDatabase();
230
+		$currentUser = User::getCurrent($database);
231
+
232
+		$otpCredentialProvider = new TotpCredentialProvider($database, $this->getSiteConfiguration());
233
+
234
+		$factorType = 'TOTP';
235
+
236
+		$this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
237
+	}
233 238
 
234
-        $factorType = 'TOTP';
239
+	protected function enableU2F() {
240
+		$database = $this->getDatabase();
241
+		$currentUser = User::getCurrent($database);
235 242
 
236
-        $this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
237
-    }
243
+		$otpCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
238 244
 
239
-    protected function enableU2F() {
240
-        $database = $this->getDatabase();
241
-        $currentUser = User::getCurrent($database);
245
+		if (WebRequest::wasPosted()) {
246
+			$this->validateCSRFToken();
242 247
 
243
-        $otpCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
244
-
245
-        if (WebRequest::wasPosted()) {
246
-            $this->validateCSRFToken();
247
-
248
-            // used for routing only, not security
249
-            $stage = WebRequest::postString('stage');
250
-
251
-            if ($stage === "auth") {
252
-                $password = WebRequest::postString('password');
253
-
254
-                $passwordCredentialProvider = new PasswordCredentialProvider($database,
255
-                    $this->getSiteConfiguration());
256
-                $result = $passwordCredentialProvider->authenticate($currentUser, $password);
257
-
258
-                if ($result) {
259
-                    $otpCredentialProvider->setCredential($currentUser, 2, null);
260
-                    $this->assignCSRFToken();
261
-
262
-                    list($data, $reqs) = $otpCredentialProvider->getRegistrationData();
263
-
264
-                    $u2fRequest =json_encode($data);
265
-                    $u2fSigns = json_encode($reqs);
266
-
267
-                    $this->addJs('/vendor/yubico/u2flib-server/examples/assets/u2f-api.js');
268
-                    $this->setTailScript($this->getCspManager()->getNonce(), <<<JS
248
+			// used for routing only, not security
249
+			$stage = WebRequest::postString('stage');
250
+
251
+			if ($stage === "auth") {
252
+				$password = WebRequest::postString('password');
253
+
254
+				$passwordCredentialProvider = new PasswordCredentialProvider($database,
255
+					$this->getSiteConfiguration());
256
+				$result = $passwordCredentialProvider->authenticate($currentUser, $password);
257
+
258
+				if ($result) {
259
+					$otpCredentialProvider->setCredential($currentUser, 2, null);
260
+					$this->assignCSRFToken();
261
+
262
+					list($data, $reqs) = $otpCredentialProvider->getRegistrationData();
263
+
264
+					$u2fRequest =json_encode($data);
265
+					$u2fSigns = json_encode($reqs);
266
+
267
+					$this->addJs('/vendor/yubico/u2flib-server/examples/assets/u2f-api.js');
268
+					$this->setTailScript($this->getCspManager()->getNonce(), <<<JS
269 269
 var request = ${u2fRequest};
270 270
 var signs = ${u2fSigns};
271 271
 
@@ -284,162 +284,162 @@  discard block
 block discarded – undo
284 284
 	form.submit();
285 285
 });
286 286
 JS
287
-                    );
288
-
289
-                    $this->setTemplate('mfa/enableU2FEnroll.tpl');
290
-
291
-                    return;
292
-                }
293
-                else {
294
-                    SessionAlert::error('Error enabling TOTP - invalid credentials.');
295
-                    $this->redirect('multiFactor');
296
-
297
-                    return;
298
-                }
299
-            }
300
-
301
-            if ($stage === "enroll") {
302
-                // we *must* have a defined credential already here,
303
-                if ($otpCredentialProvider->isPartiallyEnrolled($currentUser)) {
304
-
305
-                    $request = json_decode(WebRequest::postString('u2fRequest'));
306
-                    $u2fData = json_decode(WebRequest::postString('u2fData'));
307
-
308
-                    $otpCredentialProvider->enable($currentUser, $request, $u2fData);
309
-
310
-                    SessionAlert::success('Enabled U2F.');
311
-
312
-                    $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
313
-                    if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
314
-                        $scratchProvider->setCredential($currentUser, 2, null);
315
-                        $tokens = $scratchProvider->getTokens();
316
-                        $this->assign('tokens', $tokens);
317
-                        $this->setTemplate('mfa/regenScratchTokens.tpl');
318
-                        return;
319
-                    }
320
-
321
-                    $this->redirect('multiFactor');
322
-                    return;
323
-                }
324
-                else {
325
-                    SessionAlert::error('Error enabling TOTP - no enrollment found or enrollment expired.');
326
-                    $this->redirect('multiFactor');
327
-
328
-                    return;
329
-                }
330
-            }
331
-
332
-            // urgh, dunno what happened, but it's not something expected.
333
-            throw new ApplicationLogicException();
334
-        }
335
-        else {
336
-            if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
337
-                // user is not enrolled, we shouldn't have got here.
338
-                throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
339
-            }
340
-
341
-            $this->assignCSRFToken();
342
-
343
-            $this->assign('alertmessage', 'To enable your multi-factor credentials, please prove you are who you say you are by providing the information below.');
344
-            $this->assign('alertheader', 'Provide credentials');
345
-            $this->assign('continueText', 'Verify password');
346
-            $this->setTemplate('mfa/enableAuth.tpl');
347
-        }
348
-    }
349
-
350
-    protected function disableU2F() {
351
-        $database = $this->getDatabase();
352
-        $currentUser = User::getCurrent($database);
353
-
354
-        $otpCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
355
-
356
-        $factorType = 'U2F';
357
-
358
-        $this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
359
-    }
360
-
361
-    protected function scratch()
362
-    {
363
-        $database = $this->getDatabase();
364
-        $currentUser = User::getCurrent($database);
365
-
366
-        if (WebRequest::wasPosted()) {
367
-            $this->validateCSRFToken();
368
-
369
-            $passwordCredentialProvider = new PasswordCredentialProvider($database,
370
-                $this->getSiteConfiguration());
371
-
372
-            $otpCredentialProvider = new ScratchTokenCredentialProvider($database,
373
-                $this->getSiteConfiguration());
374
-
375
-            $password = WebRequest::postString('password');
376
-
377
-            $result = $passwordCredentialProvider->authenticate($currentUser, $password);
378
-
379
-            if ($result) {
380
-                $otpCredentialProvider->setCredential($currentUser, 2, null);
381
-                $tokens = $otpCredentialProvider->getTokens();
382
-                $this->assign('tokens', $tokens);
383
-                $this->setTemplate('mfa/regenScratchTokens.tpl');
384
-            }
385
-            else {
386
-                SessionAlert::error('Error refreshing scratch tokens - invalid credentials.');
387
-                $this->redirect('multiFactor');
388
-            }
389
-        }
390
-        else {
391
-            $this->assignCSRFToken();
392
-
393
-            $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.');
394
-            $this->assign('alertheader', 'Re-generate scratch tokens');
395
-            $this->assign('continueText', 'Regenerate Scratch Tokens');
396
-
397
-            $this->setTemplate('mfa/enableAuth.tpl');
398
-        }
399
-    }
400
-
401
-    /**
402
-     * @param PdoDatabase         $database
403
-     * @param User                $currentUser
404
-     * @param ICredentialProvider $otpCredentialProvider
405
-     * @param string              $factorType
406
-     *
407
-     * @throws ApplicationLogicException
408
-     */
409
-    private function deleteCredential(
410
-        PdoDatabase $database,
411
-        User $currentUser,
412
-        ICredentialProvider $otpCredentialProvider,
413
-        $factorType
414
-    ) {
415
-        if (WebRequest::wasPosted()) {
416
-            $passwordCredentialProvider = new PasswordCredentialProvider($database,
417
-                $this->getSiteConfiguration());
418
-
419
-            $this->validateCSRFToken();
420
-
421
-            $password = WebRequest::postString('password');
422
-            $result = $passwordCredentialProvider->authenticate($currentUser, $password);
423
-
424
-            if ($result) {
425
-                $otpCredentialProvider->deleteCredential($currentUser);
426
-                SessionAlert::success('Disabled ' . $factorType . '.');
427
-                $this->redirect('multiFactor');
428
-            }
429
-            else {
430
-                SessionAlert::error('Error disabling ' . $factorType . ' - invalid credentials.');
431
-                $this->redirect('multiFactor');
432
-            }
433
-        }
434
-        else {
435
-            if (!$otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
436
-                // user is not enrolled, we shouldn't have got here.
437
-                throw new ApplicationLogicException('User is not enrolled in the selected MFA mechanism');
438
-            }
439
-
440
-            $this->assignCSRFToken();
441
-            $this->assign('otpType', $factorType);
442
-            $this->setTemplate('mfa/disableOtp.tpl');
443
-        }
444
-    }
287
+					);
288
+
289
+					$this->setTemplate('mfa/enableU2FEnroll.tpl');
290
+
291
+					return;
292
+				}
293
+				else {
294
+					SessionAlert::error('Error enabling TOTP - invalid credentials.');
295
+					$this->redirect('multiFactor');
296
+
297
+					return;
298
+				}
299
+			}
300
+
301
+			if ($stage === "enroll") {
302
+				// we *must* have a defined credential already here,
303
+				if ($otpCredentialProvider->isPartiallyEnrolled($currentUser)) {
304
+
305
+					$request = json_decode(WebRequest::postString('u2fRequest'));
306
+					$u2fData = json_decode(WebRequest::postString('u2fData'));
307
+
308
+					$otpCredentialProvider->enable($currentUser, $request, $u2fData);
309
+
310
+					SessionAlert::success('Enabled U2F.');
311
+
312
+					$scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
313
+					if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
314
+						$scratchProvider->setCredential($currentUser, 2, null);
315
+						$tokens = $scratchProvider->getTokens();
316
+						$this->assign('tokens', $tokens);
317
+						$this->setTemplate('mfa/regenScratchTokens.tpl');
318
+						return;
319
+					}
320
+
321
+					$this->redirect('multiFactor');
322
+					return;
323
+				}
324
+				else {
325
+					SessionAlert::error('Error enabling TOTP - no enrollment found or enrollment expired.');
326
+					$this->redirect('multiFactor');
327
+
328
+					return;
329
+				}
330
+			}
331
+
332
+			// urgh, dunno what happened, but it's not something expected.
333
+			throw new ApplicationLogicException();
334
+		}
335
+		else {
336
+			if ($otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
337
+				// user is not enrolled, we shouldn't have got here.
338
+				throw new ApplicationLogicException('User is already enrolled in the selected MFA mechanism');
339
+			}
340
+
341
+			$this->assignCSRFToken();
342
+
343
+			$this->assign('alertmessage', 'To enable your multi-factor credentials, please prove you are who you say you are by providing the information below.');
344
+			$this->assign('alertheader', 'Provide credentials');
345
+			$this->assign('continueText', 'Verify password');
346
+			$this->setTemplate('mfa/enableAuth.tpl');
347
+		}
348
+	}
349
+
350
+	protected function disableU2F() {
351
+		$database = $this->getDatabase();
352
+		$currentUser = User::getCurrent($database);
353
+
354
+		$otpCredentialProvider = new U2FCredentialProvider($database, $this->getSiteConfiguration());
355
+
356
+		$factorType = 'U2F';
357
+
358
+		$this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
359
+	}
360
+
361
+	protected function scratch()
362
+	{
363
+		$database = $this->getDatabase();
364
+		$currentUser = User::getCurrent($database);
365
+
366
+		if (WebRequest::wasPosted()) {
367
+			$this->validateCSRFToken();
368
+
369
+			$passwordCredentialProvider = new PasswordCredentialProvider($database,
370
+				$this->getSiteConfiguration());
371
+
372
+			$otpCredentialProvider = new ScratchTokenCredentialProvider($database,
373
+				$this->getSiteConfiguration());
374
+
375
+			$password = WebRequest::postString('password');
376
+
377
+			$result = $passwordCredentialProvider->authenticate($currentUser, $password);
378
+
379
+			if ($result) {
380
+				$otpCredentialProvider->setCredential($currentUser, 2, null);
381
+				$tokens = $otpCredentialProvider->getTokens();
382
+				$this->assign('tokens', $tokens);
383
+				$this->setTemplate('mfa/regenScratchTokens.tpl');
384
+			}
385
+			else {
386
+				SessionAlert::error('Error refreshing scratch tokens - invalid credentials.');
387
+				$this->redirect('multiFactor');
388
+			}
389
+		}
390
+		else {
391
+			$this->assignCSRFToken();
392
+
393
+			$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.');
394
+			$this->assign('alertheader', 'Re-generate scratch tokens');
395
+			$this->assign('continueText', 'Regenerate Scratch Tokens');
396
+
397
+			$this->setTemplate('mfa/enableAuth.tpl');
398
+		}
399
+	}
400
+
401
+	/**
402
+	 * @param PdoDatabase         $database
403
+	 * @param User                $currentUser
404
+	 * @param ICredentialProvider $otpCredentialProvider
405
+	 * @param string              $factorType
406
+	 *
407
+	 * @throws ApplicationLogicException
408
+	 */
409
+	private function deleteCredential(
410
+		PdoDatabase $database,
411
+		User $currentUser,
412
+		ICredentialProvider $otpCredentialProvider,
413
+		$factorType
414
+	) {
415
+		if (WebRequest::wasPosted()) {
416
+			$passwordCredentialProvider = new PasswordCredentialProvider($database,
417
+				$this->getSiteConfiguration());
418
+
419
+			$this->validateCSRFToken();
420
+
421
+			$password = WebRequest::postString('password');
422
+			$result = $passwordCredentialProvider->authenticate($currentUser, $password);
423
+
424
+			if ($result) {
425
+				$otpCredentialProvider->deleteCredential($currentUser);
426
+				SessionAlert::success('Disabled ' . $factorType . '.');
427
+				$this->redirect('multiFactor');
428
+			}
429
+			else {
430
+				SessionAlert::error('Error disabling ' . $factorType . ' - invalid credentials.');
431
+				$this->redirect('multiFactor');
432
+			}
433
+		}
434
+		else {
435
+			if (!$otpCredentialProvider->userIsEnrolled($currentUser->getId())) {
436
+				// user is not enrolled, we shouldn't have got here.
437
+				throw new ApplicationLogicException('User is not enrolled in the selected MFA mechanism');
438
+			}
439
+
440
+			$this->assignCSRFToken();
441
+			$this->assign('otpType', $factorType);
442
+			$this->setTemplate('mfa/disableOtp.tpl');
443
+		}
444
+	}
445 445
 }
Please login to merge, or discard this patch.