Failed Conditions
Push — newinternal-releasecandidate ( a30d14...06bb07 )
by Simon
08:31
created
includes/Pages/PageViewRequest.php 3 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -130,7 +130,7 @@  discard block
 block discarded – undo
130 130
             }
131 131
         }
132 132
 
133
-        $this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
133
+        $this->setHtmlTitle($statusSymbol.' #'.$request->getId());
134 134
     }
135 135
 
136 136
     /**
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
 
228 228
                 $entryComment = $entry->getComment();
229 229
 
230
-                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
230
+                if ($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest') {
231 231
                     $data = unserialize($entry->getComment());
232 232
                     /** @var JobQueue $job */
233 233
                     $job = JobQueue::getById($data['job'], $database);
Please login to merge, or discard this patch.
Braces   +3 added lines, -2 removed lines patch added patch discarded remove patch
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
 
228 228
                 $entryComment = $entry->getComment();
229 229
 
230
-                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
230
+                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest') {
231 231
                     $data = unserialize($entry->getComment());
232 232
                     /** @var JobQueue $job */
233 233
                     $job = JobQueue::getById($data['job'], $database);
@@ -243,7 +243,8 @@  discard block
 block discarded – undo
243 243
                         'jobId'    => $job->getId(),
244 244
                         'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
245 245
                     );
246
-                } else {
246
+                }
247
+                else {
247 248
                     $requestLogs[] = array(
248 249
                         'type'     => 'log',
249 250
                         'security' => 'user',
Please login to merge, or discard this patch.
Indentation   +276 added lines, -276 removed lines patch added patch discarded remove patch
@@ -25,280 +25,280 @@
 block discarded – undo
25 25
 
26 26
 class PageViewRequest extends InternalPageBase
27 27
 {
28
-    use RequestData;
29
-    const STATUS_SYMBOL_OPEN = '&#x2610';
30
-    const STATUS_SYMBOL_ACCEPTED = '&#x2611';
31
-    const STATUS_SYMBOL_REJECTED = '&#x2612';
32
-
33
-    /**
34
-     * Main function for this page, when no specific actions are called.
35
-     * @throws ApplicationLogicException
36
-     */
37
-    protected function main()
38
-    {
39
-        // set up csrf protection
40
-        $this->assignCSRFToken();
41
-
42
-        // get some useful objects
43
-        $database = $this->getDatabase();
44
-        $request = $this->getRequest($database, WebRequest::getInt('id'));
45
-        $config = $this->getSiteConfiguration();
46
-        $currentUser = User::getCurrent($database);
47
-
48
-        // Test we should be able to look at this request
49
-        if ($config->getEmailConfirmationEnabled()) {
50
-            if ($request->getEmailConfirm() !== 'Confirmed') {
51
-                // Not allowed to look at this yet.
52
-                throw new ApplicationLogicException('The email address has not yet been confirmed for this request.');
53
-            }
54
-        }
55
-
56
-        $this->setupBasicData($request, $config);
57
-
58
-        $this->setupUsernameData($request);
59
-
60
-        $this->setupTitle($request);
61
-
62
-        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
63
-        $this->setupGeneralData($database);
64
-
65
-        $this->assign('requestDataCleared', false);
66
-        if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
67
-            $this->assign('requestDataCleared', true);
68
-        }
69
-
70
-        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
71
-
72
-        $this->setupCreationTypes($currentUser);
73
-
74
-        $this->setupLogData($request, $database);
75
-
76
-        $this->addJs("/api.php?action=templates&targetVariable=templateconfirms");
77
-
78
-        if ($allowedPrivateData) {
79
-            $this->setTemplate('view-request/main-with-data.tpl');
80
-            $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
81
-
82
-            $this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
83
-            $this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
84
-
85
-            if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
86
-                $this->setTemplate('view-request/main-with-checkuser-data.tpl');
87
-                $this->setupCheckUserData($request);
88
-            }
89
-        }
90
-        else {
91
-            $this->setTemplate('view-request/main.tpl');
92
-        }
93
-    }
94
-
95
-    /**
96
-     * @param Request $request
97
-     */
98
-    protected function setupTitle(Request $request)
99
-    {
100
-        $statusSymbol = self::STATUS_SYMBOL_OPEN;
101
-        if ($request->getStatus() === 'Closed') {
102
-            if ($request->getWasCreated()) {
103
-                $statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
104
-            }
105
-            else {
106
-                $statusSymbol = self::STATUS_SYMBOL_REJECTED;
107
-            }
108
-        }
109
-
110
-        $this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
111
-    }
112
-
113
-    /**
114
-     * Sets up data unrelated to the request, such as the email template information
115
-     *
116
-     * @param PdoDatabase $database
117
-     */
118
-    protected function setupGeneralData(PdoDatabase $database)
119
-    {
120
-        $config = $this->getSiteConfiguration();
121
-
122
-        $this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
123
-
124
-        $this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
125
-
126
-        $this->assign('requestStates', $config->getRequestStates());
127
-
128
-        /** @var EmailTemplate $createdTemplate */
129
-        $createdTemplate = EmailTemplate::getById($config->getDefaultCreatedTemplateId(), $database);
130
-
131
-        $this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
132
-        $this->assign('createdId', $createdTemplate->getId());
133
-        $this->assign('createdName', $createdTemplate->getName());
134
-
135
-        $createReasons = EmailTemplate::getActiveTemplates(EmailTemplate::CREATED, $database);
136
-        $this->assign("createReasons", $createReasons);
137
-        $declineReasons = EmailTemplate::getActiveTemplates(EmailTemplate::NOT_CREATED, $database);
138
-        $this->assign("declineReasons", $declineReasons);
139
-
140
-        $allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::CREATED, $database);
141
-        $this->assign("allCreateReasons", $allCreateReasons);
142
-        $allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::NOT_CREATED, $database);
143
-        $this->assign("allDeclineReasons", $allDeclineReasons);
144
-        $allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
145
-        $this->assign("allOtherReasons", $allOtherReasons);
146
-    }
147
-
148
-    private function setupLogData(Request $request, PdoDatabase $database)
149
-    {
150
-        $currentUser = User::getCurrent($database);
151
-
152
-        $logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
153
-        $requestLogs = array();
154
-
155
-        if (trim($request->getComment()) !== "") {
156
-            $requestLogs[] = array(
157
-                'type'     => 'comment',
158
-                'security' => 'user',
159
-                'userid'   => null,
160
-                'user'     => $request->getName(),
161
-                'entry'    => null,
162
-                'time'     => $request->getDate(),
163
-                'canedit'  => false,
164
-                'id'       => $request->getId(),
165
-                'comment'  => $request->getComment(),
166
-            );
167
-        }
168
-
169
-        /** @var User[] $nameCache */
170
-        $nameCache = array();
171
-
172
-        $editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
173
-
174
-        /** @var Log|Comment $entry */
175
-        foreach ($logs as $entry) {
176
-            // both log and comment have a 'user' field
177
-            if (!array_key_exists($entry->getUser(), $nameCache)) {
178
-                $entryUser = User::getById($entry->getUser(), $database);
179
-                $nameCache[$entry->getUser()] = $entryUser;
180
-            }
181
-
182
-            if ($entry instanceof Comment) {
183
-                $requestLogs[] = array(
184
-                    'type'     => 'comment',
185
-                    'security' => $entry->getVisibility(),
186
-                    'user'     => $nameCache[$entry->getUser()]->getUsername(),
187
-                    'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
188
-                    'entry'    => null,
189
-                    'time'     => $entry->getTime(),
190
-                    'canedit'  => ($editableComments || $entry->getUser() == $currentUser->getId()),
191
-                    'id'       => $entry->getId(),
192
-                    'comment'  => $entry->getComment(),
193
-                );
194
-            }
195
-
196
-            if ($entry instanceof Log) {
197
-                $invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
198
-                $entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
199
-
200
-                $entryComment = $entry->getComment();
201
-
202
-                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
203
-                    $data = unserialize($entry->getComment());
204
-                    /** @var JobQueue $job */
205
-                    $job = JobQueue::getById($data['job'], $database);
206
-                    $requestLogs[] = array(
207
-                        'type'     => 'joblog',
208
-                        'security' => 'user',
209
-                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
210
-                        'user'     => $entryUser->getUsername(),
211
-                        'entry'    => LogHelper::getLogDescription($entry),
212
-                        'time'     => $entry->getTimestamp(),
213
-                        'canedit'  => false,
214
-                        'id'       => $entry->getId(),
215
-                        'jobId'    => $job->getId(),
216
-                        'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
217
-                    );
218
-                } else {
219
-                    $requestLogs[] = array(
220
-                        'type'     => 'log',
221
-                        'security' => 'user',
222
-                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
223
-                        'user'     => $entryUser->getUsername(),
224
-                        'entry'    => LogHelper::getLogDescription($entry),
225
-                        'time'     => $entry->getTimestamp(),
226
-                        'canedit'  => false,
227
-                        'id'       => $entry->getId(),
228
-                        'comment'  => $entryComment,
229
-                    );
230
-                }
231
-            }
232
-        }
233
-
234
-        $this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
235
-
236
-        $this->assign("requestLogs", $requestLogs);
237
-    }
238
-
239
-    /**
240
-     * @param Request $request
241
-     */
242
-    protected function setupUsernameData(Request $request)
243
-    {
244
-        $blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
245
-
246
-        $this->assign('requestIsBlacklisted', $blacklistData !== false);
247
-        $this->assign('requestBlacklist', $blacklistData);
248
-
249
-        try {
250
-            $spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
251
-        }
252
-        catch (Exception $ex) {
253
-            $spoofs = $ex->getMessage();
254
-        }
255
-
256
-        $this->assign("spoofs", $spoofs);
257
-    }
258
-
259
-    private function setupCreationTypes(User $user)
260
-    {
261
-        $this->assign('allowWelcomeSkip', false);
262
-        $this->assign('forceWelcomeSkip', false);
263
-
264
-        $oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
265
-
266
-        if ($user->getWelcomeTemplate() != 0) {
267
-            $this->assign('allowWelcomeSkip', true);
268
-
269
-            if (!$oauth->canWelcome()) {
270
-                $this->assign('forceWelcomeSkip', true);
271
-            }
272
-        }
273
-
274
-        // test credentials
275
-        $canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
276
-        $canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
277
-        $canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
278
-
279
-        $this->assign('canManualCreate', $canManualCreate);
280
-        $this->assign('canOauthCreate', $canOauthCreate);
281
-        $this->assign('canBotCreate', $canBotCreate);
282
-
283
-        // show/hide the type radio buttons
284
-        $creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
285
-
286
-        if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
287
-            // user is not allowed to use their default. Force a choice.
288
-            $creationHasChoice = true;
289
-        }
290
-
291
-        $this->assign('creationHasChoice', $creationHasChoice);
292
-
293
-        // determine problems in creation types
294
-        $this->assign('botProblem', false);
295
-        if ($canBotCreate && $this->getSiteConfiguration()->getCreationBotPassword() === null) {
296
-            $this->assign('botProblem', true);
297
-        }
298
-
299
-        $this->assign('oauthProblem', false);
300
-        if ($canOauthCreate && !$oauth->canCreateAccount()) {
301
-            $this->assign('oauthProblem', true);
302
-        }
303
-    }
28
+	use RequestData;
29
+	const STATUS_SYMBOL_OPEN = '&#x2610';
30
+	const STATUS_SYMBOL_ACCEPTED = '&#x2611';
31
+	const STATUS_SYMBOL_REJECTED = '&#x2612';
32
+
33
+	/**
34
+	 * Main function for this page, when no specific actions are called.
35
+	 * @throws ApplicationLogicException
36
+	 */
37
+	protected function main()
38
+	{
39
+		// set up csrf protection
40
+		$this->assignCSRFToken();
41
+
42
+		// get some useful objects
43
+		$database = $this->getDatabase();
44
+		$request = $this->getRequest($database, WebRequest::getInt('id'));
45
+		$config = $this->getSiteConfiguration();
46
+		$currentUser = User::getCurrent($database);
47
+
48
+		// Test we should be able to look at this request
49
+		if ($config->getEmailConfirmationEnabled()) {
50
+			if ($request->getEmailConfirm() !== 'Confirmed') {
51
+				// Not allowed to look at this yet.
52
+				throw new ApplicationLogicException('The email address has not yet been confirmed for this request.');
53
+			}
54
+		}
55
+
56
+		$this->setupBasicData($request, $config);
57
+
58
+		$this->setupUsernameData($request);
59
+
60
+		$this->setupTitle($request);
61
+
62
+		$this->setupReservationDetails($request->getReserved(), $database, $currentUser);
63
+		$this->setupGeneralData($database);
64
+
65
+		$this->assign('requestDataCleared', false);
66
+		if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
67
+			$this->assign('requestDataCleared', true);
68
+		}
69
+
70
+		$allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
71
+
72
+		$this->setupCreationTypes($currentUser);
73
+
74
+		$this->setupLogData($request, $database);
75
+
76
+		$this->addJs("/api.php?action=templates&targetVariable=templateconfirms");
77
+
78
+		if ($allowedPrivateData) {
79
+			$this->setTemplate('view-request/main-with-data.tpl');
80
+			$this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
81
+
82
+			$this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
83
+			$this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
84
+
85
+			if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
86
+				$this->setTemplate('view-request/main-with-checkuser-data.tpl');
87
+				$this->setupCheckUserData($request);
88
+			}
89
+		}
90
+		else {
91
+			$this->setTemplate('view-request/main.tpl');
92
+		}
93
+	}
94
+
95
+	/**
96
+	 * @param Request $request
97
+	 */
98
+	protected function setupTitle(Request $request)
99
+	{
100
+		$statusSymbol = self::STATUS_SYMBOL_OPEN;
101
+		if ($request->getStatus() === 'Closed') {
102
+			if ($request->getWasCreated()) {
103
+				$statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
104
+			}
105
+			else {
106
+				$statusSymbol = self::STATUS_SYMBOL_REJECTED;
107
+			}
108
+		}
109
+
110
+		$this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
111
+	}
112
+
113
+	/**
114
+	 * Sets up data unrelated to the request, such as the email template information
115
+	 *
116
+	 * @param PdoDatabase $database
117
+	 */
118
+	protected function setupGeneralData(PdoDatabase $database)
119
+	{
120
+		$config = $this->getSiteConfiguration();
121
+
122
+		$this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
123
+
124
+		$this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
125
+
126
+		$this->assign('requestStates', $config->getRequestStates());
127
+
128
+		/** @var EmailTemplate $createdTemplate */
129
+		$createdTemplate = EmailTemplate::getById($config->getDefaultCreatedTemplateId(), $database);
130
+
131
+		$this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
132
+		$this->assign('createdId', $createdTemplate->getId());
133
+		$this->assign('createdName', $createdTemplate->getName());
134
+
135
+		$createReasons = EmailTemplate::getActiveTemplates(EmailTemplate::CREATED, $database);
136
+		$this->assign("createReasons", $createReasons);
137
+		$declineReasons = EmailTemplate::getActiveTemplates(EmailTemplate::NOT_CREATED, $database);
138
+		$this->assign("declineReasons", $declineReasons);
139
+
140
+		$allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::CREATED, $database);
141
+		$this->assign("allCreateReasons", $allCreateReasons);
142
+		$allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::NOT_CREATED, $database);
143
+		$this->assign("allDeclineReasons", $allDeclineReasons);
144
+		$allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
145
+		$this->assign("allOtherReasons", $allOtherReasons);
146
+	}
147
+
148
+	private function setupLogData(Request $request, PdoDatabase $database)
149
+	{
150
+		$currentUser = User::getCurrent($database);
151
+
152
+		$logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
153
+		$requestLogs = array();
154
+
155
+		if (trim($request->getComment()) !== "") {
156
+			$requestLogs[] = array(
157
+				'type'     => 'comment',
158
+				'security' => 'user',
159
+				'userid'   => null,
160
+				'user'     => $request->getName(),
161
+				'entry'    => null,
162
+				'time'     => $request->getDate(),
163
+				'canedit'  => false,
164
+				'id'       => $request->getId(),
165
+				'comment'  => $request->getComment(),
166
+			);
167
+		}
168
+
169
+		/** @var User[] $nameCache */
170
+		$nameCache = array();
171
+
172
+		$editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
173
+
174
+		/** @var Log|Comment $entry */
175
+		foreach ($logs as $entry) {
176
+			// both log and comment have a 'user' field
177
+			if (!array_key_exists($entry->getUser(), $nameCache)) {
178
+				$entryUser = User::getById($entry->getUser(), $database);
179
+				$nameCache[$entry->getUser()] = $entryUser;
180
+			}
181
+
182
+			if ($entry instanceof Comment) {
183
+				$requestLogs[] = array(
184
+					'type'     => 'comment',
185
+					'security' => $entry->getVisibility(),
186
+					'user'     => $nameCache[$entry->getUser()]->getUsername(),
187
+					'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
188
+					'entry'    => null,
189
+					'time'     => $entry->getTime(),
190
+					'canedit'  => ($editableComments || $entry->getUser() == $currentUser->getId()),
191
+					'id'       => $entry->getId(),
192
+					'comment'  => $entry->getComment(),
193
+				);
194
+			}
195
+
196
+			if ($entry instanceof Log) {
197
+				$invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
198
+				$entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
199
+
200
+				$entryComment = $entry->getComment();
201
+
202
+				if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
203
+					$data = unserialize($entry->getComment());
204
+					/** @var JobQueue $job */
205
+					$job = JobQueue::getById($data['job'], $database);
206
+					$requestLogs[] = array(
207
+						'type'     => 'joblog',
208
+						'security' => 'user',
209
+						'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
210
+						'user'     => $entryUser->getUsername(),
211
+						'entry'    => LogHelper::getLogDescription($entry),
212
+						'time'     => $entry->getTimestamp(),
213
+						'canedit'  => false,
214
+						'id'       => $entry->getId(),
215
+						'jobId'    => $job->getId(),
216
+						'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
217
+					);
218
+				} else {
219
+					$requestLogs[] = array(
220
+						'type'     => 'log',
221
+						'security' => 'user',
222
+						'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
223
+						'user'     => $entryUser->getUsername(),
224
+						'entry'    => LogHelper::getLogDescription($entry),
225
+						'time'     => $entry->getTimestamp(),
226
+						'canedit'  => false,
227
+						'id'       => $entry->getId(),
228
+						'comment'  => $entryComment,
229
+					);
230
+				}
231
+			}
232
+		}
233
+
234
+		$this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
235
+
236
+		$this->assign("requestLogs", $requestLogs);
237
+	}
238
+
239
+	/**
240
+	 * @param Request $request
241
+	 */
242
+	protected function setupUsernameData(Request $request)
243
+	{
244
+		$blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
245
+
246
+		$this->assign('requestIsBlacklisted', $blacklistData !== false);
247
+		$this->assign('requestBlacklist', $blacklistData);
248
+
249
+		try {
250
+			$spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
251
+		}
252
+		catch (Exception $ex) {
253
+			$spoofs = $ex->getMessage();
254
+		}
255
+
256
+		$this->assign("spoofs", $spoofs);
257
+	}
258
+
259
+	private function setupCreationTypes(User $user)
260
+	{
261
+		$this->assign('allowWelcomeSkip', false);
262
+		$this->assign('forceWelcomeSkip', false);
263
+
264
+		$oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
265
+
266
+		if ($user->getWelcomeTemplate() != 0) {
267
+			$this->assign('allowWelcomeSkip', true);
268
+
269
+			if (!$oauth->canWelcome()) {
270
+				$this->assign('forceWelcomeSkip', true);
271
+			}
272
+		}
273
+
274
+		// test credentials
275
+		$canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
276
+		$canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
277
+		$canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
278
+
279
+		$this->assign('canManualCreate', $canManualCreate);
280
+		$this->assign('canOauthCreate', $canOauthCreate);
281
+		$this->assign('canBotCreate', $canBotCreate);
282
+
283
+		// show/hide the type radio buttons
284
+		$creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
285
+
286
+		if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
287
+			// user is not allowed to use their default. Force a choice.
288
+			$creationHasChoice = true;
289
+		}
290
+
291
+		$this->assign('creationHasChoice', $creationHasChoice);
292
+
293
+		// determine problems in creation types
294
+		$this->assign('botProblem', false);
295
+		if ($canBotCreate && $this->getSiteConfiguration()->getCreationBotPassword() === null) {
296
+			$this->assign('botProblem', true);
297
+		}
298
+
299
+		$this->assign('oauthProblem', false);
300
+		if ($canOauthCreate && !$oauth->canCreateAccount()) {
301
+			$this->assign('oauthProblem', true);
302
+		}
303
+	}
304 304
 }
Please login to merge, or discard this patch.
includes/Pages/UserAuth/PageOAuth.php 1 patch
Indentation   +73 added lines, -73 removed lines patch added patch discarded remove patch
@@ -21,77 +21,77 @@
 block discarded – undo
21 21
 
22 22
 class PageOAuth extends InternalPageBase
23 23
 {
24
-    /**
25
-     * Attach entry point
26
-     *
27
-     * must be posted, or will redirect to preferences
28
-     */
29
-    protected function attach()
30
-    {
31
-        if (!WebRequest::wasPosted()) {
32
-            $this->redirect('preferences');
33
-
34
-            return;
35
-        }
36
-
37
-        $database = $this->getDatabase();
38
-
39
-        $this->validateCSRFToken();
40
-
41
-        $oauthProtocolHelper = $this->getOAuthProtocolHelper();
42
-        $user = User::getCurrent($database);
43
-        $oauth = new OAuthUserHelper($user, $database, $oauthProtocolHelper, $this->getSiteConfiguration());
44
-
45
-        try {
46
-            $authoriseUrl = $oauth->getRequestToken();
47
-            $this->redirectUrl($authoriseUrl);
48
-        }
49
-        catch (CurlException $ex) {
50
-            throw new ApplicationLogicException($ex->getMessage(), 0, $ex);
51
-        }
52
-    }
53
-
54
-    /**
55
-     * Detach account entry point
56
-     */
57
-    protected function detach()
58
-    {
59
-        if ($this->getSiteConfiguration()->getEnforceOAuth()) {
60
-            throw new AccessDeniedException($this->getSecurityManager());
61
-        }
62
-
63
-        $database = $this->getDatabase();
64
-        $user = User::getCurrent($database);
65
-        $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
66
-
67
-        try {
68
-            $oauth->refreshIdentity();
69
-        }
70
-        catch (CurlException $ex) {
71
-            // do nothing. The user's already revoked this access anyway.
72
-        }
73
-        catch (OAuthException $ex) {
74
-            // do nothing. The user's already revoked this access anyway.
75
-        }
76
-
77
-        $oauth->detach();
78
-
79
-        // TODO: figure out why we need to force logout after a detach.
80
-        $user->setForcelogout(true);
81
-        $user->save();
82
-
83
-        // force the user to log out
84
-        Session::destroy();
85
-
86
-        $this->redirect('login');
87
-    }
88
-
89
-    /**
90
-     * Main function for this page, when no specific actions are called.
91
-     * @return void
92
-     */
93
-    protected function main()
94
-    {
95
-        $this->redirect('preferences');
96
-    }
24
+	/**
25
+	 * Attach entry point
26
+	 *
27
+	 * must be posted, or will redirect to preferences
28
+	 */
29
+	protected function attach()
30
+	{
31
+		if (!WebRequest::wasPosted()) {
32
+			$this->redirect('preferences');
33
+
34
+			return;
35
+		}
36
+
37
+		$database = $this->getDatabase();
38
+
39
+		$this->validateCSRFToken();
40
+
41
+		$oauthProtocolHelper = $this->getOAuthProtocolHelper();
42
+		$user = User::getCurrent($database);
43
+		$oauth = new OAuthUserHelper($user, $database, $oauthProtocolHelper, $this->getSiteConfiguration());
44
+
45
+		try {
46
+			$authoriseUrl = $oauth->getRequestToken();
47
+			$this->redirectUrl($authoriseUrl);
48
+		}
49
+		catch (CurlException $ex) {
50
+			throw new ApplicationLogicException($ex->getMessage(), 0, $ex);
51
+		}
52
+	}
53
+
54
+	/**
55
+	 * Detach account entry point
56
+	 */
57
+	protected function detach()
58
+	{
59
+		if ($this->getSiteConfiguration()->getEnforceOAuth()) {
60
+			throw new AccessDeniedException($this->getSecurityManager());
61
+		}
62
+
63
+		$database = $this->getDatabase();
64
+		$user = User::getCurrent($database);
65
+		$oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
66
+
67
+		try {
68
+			$oauth->refreshIdentity();
69
+		}
70
+		catch (CurlException $ex) {
71
+			// do nothing. The user's already revoked this access anyway.
72
+		}
73
+		catch (OAuthException $ex) {
74
+			// do nothing. The user's already revoked this access anyway.
75
+		}
76
+
77
+		$oauth->detach();
78
+
79
+		// TODO: figure out why we need to force logout after a detach.
80
+		$user->setForcelogout(true);
81
+		$user->save();
82
+
83
+		// force the user to log out
84
+		Session::destroy();
85
+
86
+		$this->redirect('login');
87
+	}
88
+
89
+	/**
90
+	 * Main function for this page, when no specific actions are called.
91
+	 * @return void
92
+	 */
93
+	protected function main()
94
+	{
95
+		$this->redirect('preferences');
96
+	}
97 97
 }
Please login to merge, or discard this patch.
includes/Pages/UserAuth/PageChangePassword.php 1 patch
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -17,70 +17,70 @@
 block discarded – undo
17 17
 
18 18
 class PageChangePassword extends InternalPageBase
19 19
 {
20
-    /**
21
-     * Main function for this page, when no specific actions are called.
22
-     * @return void
23
-     */
24
-    protected function main()
25
-    {
26
-        $this->setHtmlTitle('Change Password');
20
+	/**
21
+	 * Main function for this page, when no specific actions are called.
22
+	 * @return void
23
+	 */
24
+	protected function main()
25
+	{
26
+		$this->setHtmlTitle('Change Password');
27 27
 
28
-        if (WebRequest::wasPosted()) {
29
-            $this->validateCSRFToken();
30
-            try {
31
-                $oldPassword = WebRequest::postString('oldpassword');
32
-                $newPassword = WebRequest::postString('newpassword');
33
-                $newPasswordConfirmation = WebRequest::postString('newpasswordconfirm');
28
+		if (WebRequest::wasPosted()) {
29
+			$this->validateCSRFToken();
30
+			try {
31
+				$oldPassword = WebRequest::postString('oldpassword');
32
+				$newPassword = WebRequest::postString('newpassword');
33
+				$newPasswordConfirmation = WebRequest::postString('newpasswordconfirm');
34 34
 
35
-                $user = User::getCurrent($this->getDatabase());
36
-                if (!$user instanceof User) {
37
-                    throw new ApplicationLogicException('User not found');
38
-                }
35
+				$user = User::getCurrent($this->getDatabase());
36
+				if (!$user instanceof User) {
37
+					throw new ApplicationLogicException('User not found');
38
+				}
39 39
 
40
-                $this->validateNewPassword($oldPassword, $newPassword, $newPasswordConfirmation, $user);
41
-            }
42
-            catch (ApplicationLogicException $ex) {
43
-                SessionAlert::error($ex->getMessage());
44
-                $this->redirect('changePassword');
40
+				$this->validateNewPassword($oldPassword, $newPassword, $newPasswordConfirmation, $user);
41
+			}
42
+			catch (ApplicationLogicException $ex) {
43
+				SessionAlert::error($ex->getMessage());
44
+				$this->redirect('changePassword');
45 45
 
46
-                return;
47
-            }
46
+				return;
47
+			}
48 48
 
49
-            $passwordProvider = new PasswordCredentialProvider($this->getDatabase(), $this->getSiteConfiguration());
50
-            $passwordProvider->setCredential($user, 1, $newPassword);
49
+			$passwordProvider = new PasswordCredentialProvider($this->getDatabase(), $this->getSiteConfiguration());
50
+			$passwordProvider->setCredential($user, 1, $newPassword);
51 51
 
52
-            SessionAlert::success('Password changed successfully!');
52
+			SessionAlert::success('Password changed successfully!');
53 53
 
54
-            $this->redirect('preferences');
55
-        }
56
-        else {
57
-            $this->assignCSRFToken();
58
-            $this->setTemplate('preferences/changePassword.tpl');
59
-        }
60
-    }
54
+			$this->redirect('preferences');
55
+		}
56
+		else {
57
+			$this->assignCSRFToken();
58
+			$this->setTemplate('preferences/changePassword.tpl');
59
+		}
60
+	}
61 61
 
62
-    /**
63
-     * @param string $oldPassword
64
-     * @param string $newPassword
65
-     * @param string $newPasswordConfirmation
66
-     * @param User   $user
67
-     *
68
-     * @throws ApplicationLogicException
69
-     */
70
-    protected function validateNewPassword($oldPassword, $newPassword, $newPasswordConfirmation, User $user)
71
-    {
72
-        if ($oldPassword === null || $newPassword === null || $newPasswordConfirmation === null) {
73
-            throw new ApplicationLogicException('All three fields must be completed to change your password');
74
-        }
62
+	/**
63
+	 * @param string $oldPassword
64
+	 * @param string $newPassword
65
+	 * @param string $newPasswordConfirmation
66
+	 * @param User   $user
67
+	 *
68
+	 * @throws ApplicationLogicException
69
+	 */
70
+	protected function validateNewPassword($oldPassword, $newPassword, $newPasswordConfirmation, User $user)
71
+	{
72
+		if ($oldPassword === null || $newPassword === null || $newPasswordConfirmation === null) {
73
+			throw new ApplicationLogicException('All three fields must be completed to change your password');
74
+		}
75 75
 
76
-        if ($newPassword !== $newPasswordConfirmation) {
77
-            throw new ApplicationLogicException('Your new passwords did not match!');
78
-        }
76
+		if ($newPassword !== $newPasswordConfirmation) {
77
+			throw new ApplicationLogicException('Your new passwords did not match!');
78
+		}
79 79
 
80
-        // TODO: adapt for MFA support
81
-        $passwordProvider = new PasswordCredentialProvider($this->getDatabase(), $this->getSiteConfiguration());
82
-        if (!$passwordProvider->authenticate($user, $oldPassword)) {
83
-            throw new ApplicationLogicException('The password you entered was incorrect.');
84
-        }
85
-    }
80
+		// TODO: adapt for MFA support
81
+		$passwordProvider = new PasswordCredentialProvider($this->getDatabase(), $this->getSiteConfiguration());
82
+		if (!$passwordProvider->authenticate($user, $oldPassword)) {
83
+			throw new ApplicationLogicException('The password you entered was incorrect.');
84
+		}
85
+	}
86 86
 }
87 87
\ No newline at end of file
Please login to merge, or discard this patch.
includes/DataObjects/Credential.php 1 patch
Indentation   +196 added lines, -196 removed lines patch added patch discarded remove patch
@@ -15,187 +15,187 @@  discard block
 block discarded – undo
15 15
 
16 16
 class Credential extends DataObject
17 17
 {
18
-    /** @var int */
19
-    private $user;
20
-    /** @var int */
21
-    private $factor;
22
-    /** @var string */
23
-    private $type;
24
-    /** @var string */
25
-    private $data;
26
-    /** @var int */
27
-    private $version;
28
-    private $timeout;
29
-    /** @var int */
30
-    private $disabled = 0;
31
-    /** @var int */
32
-    private $priority;
33
-
34
-    /**
35
-     * @return int
36
-     */
37
-    public function getUserId()
38
-    {
39
-        return $this->user;
40
-    }
41
-
42
-    /**
43
-     * @param int $user
44
-     */
45
-    public function setUserId($user)
46
-    {
47
-        $this->user = $user;
48
-    }
49
-
50
-    /**
51
-     * @return int
52
-     */
53
-    public function getFactor()
54
-    {
55
-        return $this->factor;
56
-    }
57
-
58
-    /**
59
-     * @param int $factor
60
-     */
61
-    public function setFactor($factor)
62
-    {
63
-        $this->factor = $factor;
64
-    }
65
-
66
-    /**
67
-     * @return string
68
-     */
69
-    public function getType()
70
-    {
71
-        return $this->type;
72
-    }
73
-
74
-    /**
75
-     * @param string $type
76
-     */
77
-    public function setType($type)
78
-    {
79
-        $this->type = $type;
80
-    }
81
-
82
-    /**
83
-     * @return string
84
-     */
85
-    public function getData()
86
-    {
87
-        return $this->data;
88
-    }
89
-
90
-    /**
91
-     * @param string $data
92
-     */
93
-    public function setData($data)
94
-    {
95
-        $this->data = $data;
96
-    }
97
-
98
-    /**
99
-     * @return int
100
-     */
101
-    public function getVersion()
102
-    {
103
-        return $this->version;
104
-    }
105
-
106
-    /**
107
-     * @param int $version
108
-     */
109
-    public function setVersion($version)
110
-    {
111
-        $this->version = $version;
112
-    }
113
-
114
-    /**
115
-     * @return mixed
116
-     */
117
-    public function getTimeout()
118
-    {
119
-        if ($this->timeout === null) {
120
-            return null;
121
-        }
122
-
123
-        return new DateTimeImmutable($this->timeout);
124
-    }
125
-
126
-    /**
127
-     * @param mixed $timeout
128
-     */
129
-    public function setTimeout(DateTimeImmutable $timeout = null)
130
-    {
131
-        if ($timeout === null) {
132
-            $this->timeout = null;
133
-        }
134
-        else {
135
-            $this->timeout = $timeout->format('Y-m-d H:i:s');
136
-        }
137
-    }
138
-
139
-    /**
140
-     * @return int
141
-     */
142
-    public function getDisabled()
143
-    {
144
-        return $this->disabled;
145
-    }
146
-
147
-    /**
148
-     * @param int $disabled
149
-     */
150
-    public function setDisabled($disabled)
151
-    {
152
-        $this->disabled = $disabled;
153
-    }
154
-
155
-    /**
156
-     * @return int
157
-     */
158
-    public function getPriority()
159
-    {
160
-        return $this->priority;
161
-    }
162
-
163
-    /**
164
-     * @param int $priority
165
-     */
166
-    public function setPriority($priority)
167
-    {
168
-        $this->priority = $priority;
169
-    }
170
-
171
-    public function save()
172
-    {
173
-        if ($this->isNew()) {
174
-            // insert
175
-            $statement = $this->dbObject->prepare(<<<SQL
18
+	/** @var int */
19
+	private $user;
20
+	/** @var int */
21
+	private $factor;
22
+	/** @var string */
23
+	private $type;
24
+	/** @var string */
25
+	private $data;
26
+	/** @var int */
27
+	private $version;
28
+	private $timeout;
29
+	/** @var int */
30
+	private $disabled = 0;
31
+	/** @var int */
32
+	private $priority;
33
+
34
+	/**
35
+	 * @return int
36
+	 */
37
+	public function getUserId()
38
+	{
39
+		return $this->user;
40
+	}
41
+
42
+	/**
43
+	 * @param int $user
44
+	 */
45
+	public function setUserId($user)
46
+	{
47
+		$this->user = $user;
48
+	}
49
+
50
+	/**
51
+	 * @return int
52
+	 */
53
+	public function getFactor()
54
+	{
55
+		return $this->factor;
56
+	}
57
+
58
+	/**
59
+	 * @param int $factor
60
+	 */
61
+	public function setFactor($factor)
62
+	{
63
+		$this->factor = $factor;
64
+	}
65
+
66
+	/**
67
+	 * @return string
68
+	 */
69
+	public function getType()
70
+	{
71
+		return $this->type;
72
+	}
73
+
74
+	/**
75
+	 * @param string $type
76
+	 */
77
+	public function setType($type)
78
+	{
79
+		$this->type = $type;
80
+	}
81
+
82
+	/**
83
+	 * @return string
84
+	 */
85
+	public function getData()
86
+	{
87
+		return $this->data;
88
+	}
89
+
90
+	/**
91
+	 * @param string $data
92
+	 */
93
+	public function setData($data)
94
+	{
95
+		$this->data = $data;
96
+	}
97
+
98
+	/**
99
+	 * @return int
100
+	 */
101
+	public function getVersion()
102
+	{
103
+		return $this->version;
104
+	}
105
+
106
+	/**
107
+	 * @param int $version
108
+	 */
109
+	public function setVersion($version)
110
+	{
111
+		$this->version = $version;
112
+	}
113
+
114
+	/**
115
+	 * @return mixed
116
+	 */
117
+	public function getTimeout()
118
+	{
119
+		if ($this->timeout === null) {
120
+			return null;
121
+		}
122
+
123
+		return new DateTimeImmutable($this->timeout);
124
+	}
125
+
126
+	/**
127
+	 * @param mixed $timeout
128
+	 */
129
+	public function setTimeout(DateTimeImmutable $timeout = null)
130
+	{
131
+		if ($timeout === null) {
132
+			$this->timeout = null;
133
+		}
134
+		else {
135
+			$this->timeout = $timeout->format('Y-m-d H:i:s');
136
+		}
137
+	}
138
+
139
+	/**
140
+	 * @return int
141
+	 */
142
+	public function getDisabled()
143
+	{
144
+		return $this->disabled;
145
+	}
146
+
147
+	/**
148
+	 * @param int $disabled
149
+	 */
150
+	public function setDisabled($disabled)
151
+	{
152
+		$this->disabled = $disabled;
153
+	}
154
+
155
+	/**
156
+	 * @return int
157
+	 */
158
+	public function getPriority()
159
+	{
160
+		return $this->priority;
161
+	}
162
+
163
+	/**
164
+	 * @param int $priority
165
+	 */
166
+	public function setPriority($priority)
167
+	{
168
+		$this->priority = $priority;
169
+	}
170
+
171
+	public function save()
172
+	{
173
+		if ($this->isNew()) {
174
+			// insert
175
+			$statement = $this->dbObject->prepare(<<<SQL
176 176
 INSERT INTO credential ( updateversion, user, factor, type, data, version, timeout, disabled, priority )
177 177
 VALUES ( 0, :user, :factor, :type, :data, :version, :timeout, :disabled, :priority );
178 178
 SQL
179
-            );
180
-            $statement->bindValue(":user", $this->user);
181
-            $statement->bindValue(":factor", $this->factor);
182
-            $statement->bindValue(":type", $this->type);
183
-            $statement->bindValue(":data", $this->data);
184
-            $statement->bindValue(":version", $this->version);
185
-            $statement->bindValue(":timeout", $this->timeout);
186
-            $statement->bindValue(":disabled", $this->disabled);
187
-            $statement->bindValue(":priority", $this->priority);
188
-
189
-            if ($statement->execute()) {
190
-                $this->id = (int)$this->dbObject->lastInsertId();
191
-            }
192
-            else {
193
-                throw new Exception($statement->errorInfo());
194
-            }
195
-        }
196
-        else {
197
-            // update
198
-            $statement = $this->dbObject->prepare(<<<SQL
179
+			);
180
+			$statement->bindValue(":user", $this->user);
181
+			$statement->bindValue(":factor", $this->factor);
182
+			$statement->bindValue(":type", $this->type);
183
+			$statement->bindValue(":data", $this->data);
184
+			$statement->bindValue(":version", $this->version);
185
+			$statement->bindValue(":timeout", $this->timeout);
186
+			$statement->bindValue(":disabled", $this->disabled);
187
+			$statement->bindValue(":priority", $this->priority);
188
+
189
+			if ($statement->execute()) {
190
+				$this->id = (int)$this->dbObject->lastInsertId();
191
+			}
192
+			else {
193
+				throw new Exception($statement->errorInfo());
194
+			}
195
+		}
196
+		else {
197
+			// update
198
+			$statement = $this->dbObject->prepare(<<<SQL
199 199
                 UPDATE credential
200 200
                 SET   factor = :factor
201 201
                     , data = :data
@@ -206,27 +206,27 @@  discard block
 block discarded – undo
206 206
                     , updateversion = updateversion + 1
207 207
                 WHERE id = :id AND updateversion = :updateversion;
208 208
 SQL
209
-            );
209
+			);
210 210
 
211
-            $statement->bindValue(':id', $this->id);
212
-            $statement->bindValue(':updateversion', $this->updateversion);
211
+			$statement->bindValue(':id', $this->id);
212
+			$statement->bindValue(':updateversion', $this->updateversion);
213 213
 
214
-            $statement->bindValue(":factor", $this->factor);
215
-            $statement->bindValue(":data", $this->data);
216
-            $statement->bindValue(":version", $this->version);
217
-            $statement->bindValue(":timeout", $this->timeout);
218
-            $statement->bindValue(":disabled", $this->disabled);
219
-            $statement->bindValue(":priority", $this->priority);
214
+			$statement->bindValue(":factor", $this->factor);
215
+			$statement->bindValue(":data", $this->data);
216
+			$statement->bindValue(":version", $this->version);
217
+			$statement->bindValue(":timeout", $this->timeout);
218
+			$statement->bindValue(":disabled", $this->disabled);
219
+			$statement->bindValue(":priority", $this->priority);
220 220
 
221
-            if (!$statement->execute()) {
222
-                throw new Exception($statement->errorInfo());
223
-            }
221
+			if (!$statement->execute()) {
222
+				throw new Exception($statement->errorInfo());
223
+			}
224 224
 
225
-            if ($statement->rowCount() !== 1) {
226
-                throw new OptimisticLockFailedException();
227
-            }
225
+			if ($statement->rowCount() !== 1) {
226
+				throw new OptimisticLockFailedException();
227
+			}
228 228
 
229
-            $this->updateversion++;
230
-        }
231
-    }
229
+			$this->updateversion++;
230
+		}
231
+	}
232 232
 }
233 233
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/UserAuth/MultiFactor/PageMultiFactor.php 3 patches
Braces   +4 added lines, -2 removed lines patch added patch discarded remove patch
@@ -229,7 +229,8 @@  discard block
 block discarded – undo
229 229
         $this->deleteCredential($database, $currentUser, $otpCredentialProvider, $factorType);
230 230
     }
231 231
 
232
-    protected function enableU2F() {
232
+    protected function enableU2F()
233
+    {
233 234
         $database = $this->getDatabase();
234 235
         $currentUser = User::getCurrent($database);
235 236
 
@@ -336,7 +337,8 @@  discard block
 block discarded – undo
336 337
         }
337 338
     }
338 339
 
339
-    protected function disableU2F() {
340
+    protected function disableU2F()
341
+    {
340 342
         $database = $this->getDatabase();
341 343
         $currentUser = User::getCurrent($database);
342 344
 
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
                     SessionAlert::success('Enabled YubiKey OTP.');
78 78
 
79 79
                     $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
80
-                    if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
80
+                    if ($scratchProvider->getRemaining($currentUser->getId()) < 3) {
81 81
                         $scratchProvider->setCredential($currentUser, 2, null);
82 82
                         $tokens = $scratchProvider->getTokens();
83 83
                         $this->assign('tokens', $tokens);
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
                     }
87 87
                 }
88 88
                 catch (ApplicationLogicException $ex) {
89
-                    SessionAlert::error('Error enabling YubiKey OTP: ' . $ex->getMessage());
89
+                    SessionAlert::error('Error enabling YubiKey OTP: '.$ex->getMessage());
90 90
                 }
91 91
 
92 92
                 $this->redirect('multiFactor');
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
                         SessionAlert::success('Enabled TOTP.');
178 178
 
179 179
                         $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
180
-                        if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
180
+                        if ($scratchProvider->getRemaining($currentUser->getId()) < 3) {
181 181
                             $scratchProvider->setCredential($currentUser, 2, null);
182 182
                             $tokens = $scratchProvider->getTokens();
183 183
                             $this->assign('tokens', $tokens);
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
 
258 258
                     list($data, $reqs) = $otpCredentialProvider->getRegistrationData();
259 259
 
260
-                    $u2fRequest =json_encode($data);
260
+                    $u2fRequest = json_encode($data);
261 261
                     $u2fSigns = json_encode($reqs);
262 262
 
263 263
                     $this->addJs('/vendor/yubico/u2flib-server/examples/assets/u2f-api.js');
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
                     SessionAlert::success('Enabled U2F.');
307 307
 
308 308
                     $scratchProvider = new ScratchTokenCredentialProvider($database, $this->getSiteConfiguration());
309
-                    if($scratchProvider->getRemaining($currentUser->getId()) < 3) {
309
+                    if ($scratchProvider->getRemaining($currentUser->getId()) < 3) {
310 310
                         $scratchProvider->setCredential($currentUser, 2, null);
311 311
                         $tokens = $scratchProvider->getTokens();
312 312
                         $this->assign('tokens', $tokens);
@@ -419,11 +419,11 @@  discard block
 block discarded – undo
419 419
 
420 420
             if ($result) {
421 421
                 $otpCredentialProvider->deleteCredential($currentUser);
422
-                SessionAlert::success('Disabled ' . $factorType . '.');
422
+                SessionAlert::success('Disabled '.$factorType.'.');
423 423
                 $this->redirect('multiFactor');
424 424
             }
425 425
             else {
426
-                SessionAlert::error('Error disabling ' . $factorType . ' - invalid credentials.');
426
+                SessionAlert::error('Error disabling '.$factorType.' - invalid credentials.');
427 427
                 $this->redirect('multiFactor');
428 428
             }
429 429
         }
Please login to merge, or discard this 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.
includes/Pages/UserAuth/PageOAuthCallback.php 1 patch
Indentation   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -17,90 +17,90 @@
 block discarded – undo
17 17
 
18 18
 class PageOAuthCallback extends InternalPageBase
19 19
 {
20
-    /**
21
-     * @return bool
22
-     */
23
-    protected function isProtectedPage()
24
-    {
25
-        // This page is critical to ensuring OAuth functionality is operational.
26
-        return false;
27
-    }
20
+	/**
21
+	 * @return bool
22
+	 */
23
+	protected function isProtectedPage()
24
+	{
25
+		// This page is critical to ensuring OAuth functionality is operational.
26
+		return false;
27
+	}
28 28
 
29
-    /**
30
-     * Main function for this page, when no specific actions are called.
31
-     * @return void
32
-     */
33
-    protected function main()
34
-    {
35
-        // This should never get hit except by URL manipulation.
36
-        $this->redirect('');
37
-    }
29
+	/**
30
+	 * Main function for this page, when no specific actions are called.
31
+	 * @return void
32
+	 */
33
+	protected function main()
34
+	{
35
+		// This should never get hit except by URL manipulation.
36
+		$this->redirect('');
37
+	}
38 38
 
39
-    /**
40
-     * Registered endpoint for the account creation callback.
41
-     *
42
-     * If this ever gets hit, something is wrong somewhere.
43
-     */
44
-    protected function create()
45
-    {
46
-        throw new Exception('OAuth account creation endpoint triggered.');
47
-    }
39
+	/**
40
+	 * Registered endpoint for the account creation callback.
41
+	 *
42
+	 * If this ever gets hit, something is wrong somewhere.
43
+	 */
44
+	protected function create()
45
+	{
46
+		throw new Exception('OAuth account creation endpoint triggered.');
47
+	}
48 48
 
49
-    /**
50
-     * Callback entry point
51
-     */
52
-    protected function authorise()
53
-    {
54
-        $oauthToken = WebRequest::getString('oauth_token');
55
-        $oauthVerifier = WebRequest::getString('oauth_verifier');
49
+	/**
50
+	 * Callback entry point
51
+	 */
52
+	protected function authorise()
53
+	{
54
+		$oauthToken = WebRequest::getString('oauth_token');
55
+		$oauthVerifier = WebRequest::getString('oauth_verifier');
56 56
 
57
-        $this->doCallbackValidation($oauthToken, $oauthVerifier);
57
+		$this->doCallbackValidation($oauthToken, $oauthVerifier);
58 58
 
59
-        $database = $this->getDatabase();
59
+		$database = $this->getDatabase();
60 60
 
61
-        $user = OAuthUserHelper::findUserByRequestToken($oauthToken, $database);
62
-        $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
61
+		$user = OAuthUserHelper::findUserByRequestToken($oauthToken, $database);
62
+		$oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
63 63
 
64
-        try {
65
-            $oauth->completeHandshake($oauthVerifier);
66
-        }
67
-        catch (CurlException $ex) {
68
-            throw new ApplicationLogicException($ex->getMessage(), 0, $ex);
69
-        }
64
+		try {
65
+			$oauth->completeHandshake($oauthVerifier);
66
+		}
67
+		catch (CurlException $ex) {
68
+			throw new ApplicationLogicException($ex->getMessage(), 0, $ex);
69
+		}
70 70
 
71
-        // OK, we're the same session that just did a partial login that was redirected to OAuth. Let's upgrade the
72
-        // login to a full login
73
-        if (WebRequest::getOAuthPartialLogin() === $user->getId()) {
74
-            WebRequest::setLoggedInUser($user);
75
-        }
71
+		// OK, we're the same session that just did a partial login that was redirected to OAuth. Let's upgrade the
72
+		// login to a full login
73
+		if (WebRequest::getOAuthPartialLogin() === $user->getId()) {
74
+			WebRequest::setLoggedInUser($user);
75
+		}
76 76
 
77
-        // My thinking is there are three cases here:
78
-        //   a) new user => redirect to prefs - it's the only thing they can access other than stats
79
-        //   b) existing user hit the connect button in prefs => redirect to prefs since it's where they were
80
-        //   c) existing user logging in => redirect to wherever they came from
81
-        $redirectDestination = WebRequest::clearPostLoginRedirect();
82
-        if ($redirectDestination !== null && !$user->isNewUser()) {
83
-            $this->redirectUrl($redirectDestination);
84
-        }
85
-        else {
86
-            $this->redirect('preferences', null, null, 'internal.php');
87
-        }
88
-    }
77
+		// My thinking is there are three cases here:
78
+		//   a) new user => redirect to prefs - it's the only thing they can access other than stats
79
+		//   b) existing user hit the connect button in prefs => redirect to prefs since it's where they were
80
+		//   c) existing user logging in => redirect to wherever they came from
81
+		$redirectDestination = WebRequest::clearPostLoginRedirect();
82
+		if ($redirectDestination !== null && !$user->isNewUser()) {
83
+			$this->redirectUrl($redirectDestination);
84
+		}
85
+		else {
86
+			$this->redirect('preferences', null, null, 'internal.php');
87
+		}
88
+	}
89 89
 
90
-    /**
91
-     * @param string $oauthToken
92
-     * @param string $oauthVerifier
93
-     *
94
-     * @throws ApplicationLogicException
95
-     */
96
-    private function doCallbackValidation($oauthToken, $oauthVerifier)
97
-    {
98
-        if ($oauthToken === null) {
99
-            throw new ApplicationLogicException('No token provided');
100
-        }
90
+	/**
91
+	 * @param string $oauthToken
92
+	 * @param string $oauthVerifier
93
+	 *
94
+	 * @throws ApplicationLogicException
95
+	 */
96
+	private function doCallbackValidation($oauthToken, $oauthVerifier)
97
+	{
98
+		if ($oauthToken === null) {
99
+			throw new ApplicationLogicException('No token provided');
100
+		}
101 101
 
102
-        if ($oauthVerifier === null) {
103
-            throw new ApplicationLogicException('No oauth verifier provided.');
104
-        }
105
-    }
102
+		if ($oauthVerifier === null) {
103
+			throw new ApplicationLogicException('No oauth verifier provided.');
104
+		}
105
+	}
106 106
 }
107 107
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/UserAuth/Login/LoginCredentialPageBase.php 2 patches
Indentation   +311 added lines, -311 removed lines patch added patch discarded remove patch
@@ -21,315 +21,315 @@
 block discarded – undo
21 21
 
22 22
 abstract class LoginCredentialPageBase extends InternalPageBase
23 23
 {
24
-    /** @var User */
25
-    protected $partialUser = null;
26
-    protected $nextPageMap = array(
27
-        'yubikeyotp' => 'otp',
28
-        'totp'       => 'otp',
29
-        'scratch'    => 'otp',
30
-        'u2f'        => 'u2f',
31
-    );
32
-    protected $names = array(
33
-        'yubikeyotp' => 'Yubikey OTP',
34
-        'totp'       => 'TOTP (phone code generator)',
35
-        'scratch'    => 'scratch token',
36
-        'u2f'        => 'U2F security token',
37
-    );
38
-
39
-    /**
40
-     * Main function for this page, when no specific actions are called.
41
-     * @return void
42
-     */
43
-    protected function main()
44
-    {
45
-        if (!$this->enforceHttps()) {
46
-            return;
47
-        }
48
-
49
-        if (WebRequest::wasPosted()) {
50
-            $this->validateCSRFToken();
51
-
52
-            $database = $this->getDatabase();
53
-            try {
54
-                list($partialId, $partialStage) = WebRequest::getAuthPartialLogin();
55
-
56
-                if ($partialStage === null) {
57
-                    $partialStage = 1;
58
-                }
59
-
60
-                if ($partialId === null) {
61
-                    $username = WebRequest::postString('username');
62
-
63
-                    if ($username === null || trim($username) === '') {
64
-                        throw new ApplicationLogicException('No username specified.');
65
-                    }
66
-
67
-                    $user = User::getByUsername($username, $database);
68
-                }
69
-                else {
70
-                    $user = User::getById($partialId, $database);
71
-                }
72
-
73
-                if ($user === false) {
74
-                    throw new ApplicationLogicException("Authentication failed");
75
-                }
76
-
77
-                $authMan = new AuthenticationManager($database, $this->getSiteConfiguration(),
78
-                    $this->getHttpHelper());
79
-
80
-                $credential = $this->getProviderCredentials();
81
-
82
-                $authResult = $authMan->authenticate($user, $credential, $partialStage);
83
-
84
-                if ($authResult === AuthenticationManager::AUTH_FAIL) {
85
-                    throw new ApplicationLogicException("Authentication failed");
86
-                }
87
-
88
-                if ($authResult === AuthenticationManager::AUTH_REQUIRE_NEXT_STAGE) {
89
-                    $this->processJumpNextStage($user, $partialStage, $database);
90
-
91
-                    return;
92
-                }
93
-
94
-                if ($authResult === AuthenticationManager::AUTH_OK) {
95
-                    $this->processLoginSuccess($user);
96
-
97
-                    return;
98
-                }
99
-            }
100
-            catch (ApplicationLogicException $ex) {
101
-                WebRequest::clearAuthPartialLogin();
102
-
103
-                SessionAlert::error($ex->getMessage());
104
-                $this->redirect('login');
105
-
106
-                return;
107
-            }
108
-        }
109
-        else {
110
-            $this->assign('showSignIn', true);
111
-
112
-            $this->setupPartial();
113
-            $this->assignCSRFToken();
114
-            $this->providerSpecificSetup();
115
-        }
116
-    }
117
-
118
-    protected function isProtectedPage()
119
-    {
120
-        return false;
121
-    }
122
-
123
-    /**
124
-     * Enforces HTTPS on the login form
125
-     *
126
-     * @return bool
127
-     */
128
-    private function enforceHttps()
129
-    {
130
-        if ($this->getSiteConfiguration()->getUseStrictTransportSecurity() !== false) {
131
-            if (WebRequest::isHttps()) {
132
-                // Client can clearly use HTTPS, so let's enforce it for all connections.
133
-                $this->headerQueue[] = "Strict-Transport-Security: max-age=15768000";
134
-            }
135
-            else {
136
-                // This is the login form, not the request form. We need protection here.
137
-                $this->redirectUrl('https://' . WebRequest::serverName() . WebRequest::requestUri());
138
-
139
-                return false;
140
-            }
141
-        }
142
-
143
-        return true;
144
-    }
145
-
146
-    protected abstract function providerSpecificSetup();
147
-
148
-    protected function setupPartial()
149
-    {
150
-        $database = $this->getDatabase();
151
-
152
-        // default stuff
153
-        $this->assign('alternatives', array()); // 'u2f' => array('U2F token'), 'otp' => array('TOTP', 'scratch', 'yubiotp')));
154
-
155
-        // is this stage one?
156
-        list($partialId, $partialStage) = WebRequest::getAuthPartialLogin();
157
-        if ($partialStage === null || $partialId === null) {
158
-            WebRequest::clearAuthPartialLogin();
159
-        }
160
-
161
-        // Check to see if we have a partial login in progress
162
-        $username = null;
163
-        if ($partialId !== null) {
164
-            // Yes, enforce this username
165
-            $this->partialUser = User::getById($partialId, $database);
166
-            $username = $this->partialUser->getUsername();
167
-
168
-            $this->setupAlternates($this->partialUser, $partialStage, $database);
169
-        }
170
-        else {
171
-            // No, see if we've preloaded a username
172
-            $preloadUsername = WebRequest::getString('tplUsername');
173
-            if ($preloadUsername !== null) {
174
-                $username = $preloadUsername;
175
-            }
176
-        }
177
-
178
-        if ($partialStage === null) {
179
-            $partialStage = 1;
180
-        }
181
-
182
-        $this->assign('partialStage', $partialStage);
183
-        $this->assign('username', $username);
184
-    }
185
-
186
-    /**
187
-     * Redirect the user back to wherever they came from after a successful login
188
-     *
189
-     * @param User $user
190
-     */
191
-    protected function goBackWhenceYouCame(User $user)
192
-    {
193
-        // Redirect to wherever the user came from
194
-        $redirectDestination = WebRequest::clearPostLoginRedirect();
195
-        if ($redirectDestination !== null) {
196
-            $this->redirectUrl($redirectDestination);
197
-        }
198
-        else {
199
-            if ($user->isNewUser()) {
200
-                // home page isn't allowed, go to preferences instead
201
-                $this->redirect('preferences');
202
-            }
203
-            else {
204
-                // go to the home page
205
-                $this->redirect('');
206
-            }
207
-        }
208
-    }
209
-
210
-    private function processLoginSuccess(User $user)
211
-    {
212
-        // Touch force logout
213
-        $user->setForceLogout(false);
214
-        $user->save();
215
-
216
-        $oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(),
217
-            $this->getSiteConfiguration());
218
-
219
-        if ($oauth->isFullyLinked()) {
220
-            try {
221
-                // Reload the user's identity ticket.
222
-                $oauth->refreshIdentity();
223
-
224
-                // Check for blocks
225
-                if ($oauth->getIdentity()->getBlocked()) {
226
-                    // blocked!
227
-                    SessionAlert::error("You are currently blocked on-wiki. You will not be able to log in until you are unblocked.");
228
-                    $this->redirect('login');
229
-
230
-                    return;
231
-                }
232
-            }
233
-            catch (OAuthException $ex) {
234
-                // Oops. Refreshing ticket failed. Force a re-auth.
235
-                $authoriseUrl = $oauth->getRequestToken();
236
-                WebRequest::setOAuthPartialLogin($user);
237
-                $this->redirectUrl($authoriseUrl);
238
-
239
-                return;
240
-            }
241
-        }
242
-
243
-        if (($this->getSiteConfiguration()->getEnforceOAuth() && !$oauth->isFullyLinked())
244
-            || $oauth->isPartiallyLinked()
245
-        ) {
246
-            $authoriseUrl = $oauth->getRequestToken();
247
-            WebRequest::setOAuthPartialLogin($user);
248
-            $this->redirectUrl($authoriseUrl);
249
-
250
-            return;
251
-        }
252
-
253
-        WebRequest::setLoggedInUser($user);
254
-
255
-        $this->goBackWhenceYouCame($user);
256
-    }
257
-
258
-    protected abstract function getProviderCredentials();
259
-
260
-    /**
261
-     * @param User        $user
262
-     * @param int         $partialStage
263
-     * @param PdoDatabase $database
264
-     *
265
-     * @throws ApplicationLogicException
266
-     */
267
-    private function processJumpNextStage(User $user, $partialStage, PdoDatabase $database)
268
-    {
269
-        WebRequest::setAuthPartialLogin($user->getId(), $partialStage + 1);
270
-
271
-        $sql = 'SELECT type FROM credential WHERE user = :user AND factor = :stage AND disabled = 0 ORDER BY priority';
272
-        $statement = $database->prepare($sql);
273
-        $statement->execute(array(':user' => $user->getId(), ':stage' => $partialStage + 1));
274
-        $nextStage = $statement->fetchColumn();
275
-        $statement->closeCursor();
276
-
277
-        if (!isset($this->nextPageMap[$nextStage])) {
278
-            throw new ApplicationLogicException('Unknown page handler for next authentication stage.');
279
-        }
280
-
281
-        $this->redirect("login/" . $this->nextPageMap[$nextStage]);
282
-    }
283
-
284
-    private function setupAlternates(User $user, $partialStage, PdoDatabase $database)
285
-    {
286
-        // get the providers available
287
-        $sql = 'SELECT type FROM credential WHERE user = :user AND factor = :stage AND disabled = 0';
288
-        $statement = $database->prepare($sql);
289
-        $statement->execute(array(':user' => $user->getId(), ':stage' => $partialStage));
290
-        $alternates = $statement->fetchAll(PDO::FETCH_COLUMN);
291
-
292
-        $types = array();
293
-        foreach ($alternates as $item) {
294
-            $type = $this->nextPageMap[$item];
295
-            if (!isset($types[$type])) {
296
-                $types[$type] = array();
297
-            }
298
-
299
-            $types[$type][] = $item;
300
-        }
301
-
302
-        $userOptions = array();
303
-        if (get_called_class() === PageOtpLogin::class) {
304
-            $userOptions = $this->setupUserOptionsForType($types, 'u2f', $userOptions);
305
-        }
306
-
307
-        if (get_called_class() === PageU2FLogin::class) {
308
-            $userOptions = $this->setupUserOptionsForType($types, 'otp', $userOptions);
309
-        }
310
-
311
-        $this->assign('alternatives', $userOptions);
312
-    }
313
-
314
-    /**
315
-     * @param $types
316
-     * @param $type
317
-     * @param $userOptions
318
-     *
319
-     * @return mixed
320
-     */
321
-    private function setupUserOptionsForType($types, $type, $userOptions)
322
-    {
323
-        if (isset($types[$type])) {
324
-            $options = $types[$type];
325
-
326
-            array_walk($options, function(&$val) {
327
-                $val = $this->names[$val];
328
-            });
329
-
330
-            $userOptions[$type] = $options;
331
-        }
332
-
333
-        return $userOptions;
334
-    }
24
+	/** @var User */
25
+	protected $partialUser = null;
26
+	protected $nextPageMap = array(
27
+		'yubikeyotp' => 'otp',
28
+		'totp'       => 'otp',
29
+		'scratch'    => 'otp',
30
+		'u2f'        => 'u2f',
31
+	);
32
+	protected $names = array(
33
+		'yubikeyotp' => 'Yubikey OTP',
34
+		'totp'       => 'TOTP (phone code generator)',
35
+		'scratch'    => 'scratch token',
36
+		'u2f'        => 'U2F security token',
37
+	);
38
+
39
+	/**
40
+	 * Main function for this page, when no specific actions are called.
41
+	 * @return void
42
+	 */
43
+	protected function main()
44
+	{
45
+		if (!$this->enforceHttps()) {
46
+			return;
47
+		}
48
+
49
+		if (WebRequest::wasPosted()) {
50
+			$this->validateCSRFToken();
51
+
52
+			$database = $this->getDatabase();
53
+			try {
54
+				list($partialId, $partialStage) = WebRequest::getAuthPartialLogin();
55
+
56
+				if ($partialStage === null) {
57
+					$partialStage = 1;
58
+				}
59
+
60
+				if ($partialId === null) {
61
+					$username = WebRequest::postString('username');
62
+
63
+					if ($username === null || trim($username) === '') {
64
+						throw new ApplicationLogicException('No username specified.');
65
+					}
66
+
67
+					$user = User::getByUsername($username, $database);
68
+				}
69
+				else {
70
+					$user = User::getById($partialId, $database);
71
+				}
72
+
73
+				if ($user === false) {
74
+					throw new ApplicationLogicException("Authentication failed");
75
+				}
76
+
77
+				$authMan = new AuthenticationManager($database, $this->getSiteConfiguration(),
78
+					$this->getHttpHelper());
79
+
80
+				$credential = $this->getProviderCredentials();
81
+
82
+				$authResult = $authMan->authenticate($user, $credential, $partialStage);
83
+
84
+				if ($authResult === AuthenticationManager::AUTH_FAIL) {
85
+					throw new ApplicationLogicException("Authentication failed");
86
+				}
87
+
88
+				if ($authResult === AuthenticationManager::AUTH_REQUIRE_NEXT_STAGE) {
89
+					$this->processJumpNextStage($user, $partialStage, $database);
90
+
91
+					return;
92
+				}
93
+
94
+				if ($authResult === AuthenticationManager::AUTH_OK) {
95
+					$this->processLoginSuccess($user);
96
+
97
+					return;
98
+				}
99
+			}
100
+			catch (ApplicationLogicException $ex) {
101
+				WebRequest::clearAuthPartialLogin();
102
+
103
+				SessionAlert::error($ex->getMessage());
104
+				$this->redirect('login');
105
+
106
+				return;
107
+			}
108
+		}
109
+		else {
110
+			$this->assign('showSignIn', true);
111
+
112
+			$this->setupPartial();
113
+			$this->assignCSRFToken();
114
+			$this->providerSpecificSetup();
115
+		}
116
+	}
117
+
118
+	protected function isProtectedPage()
119
+	{
120
+		return false;
121
+	}
122
+
123
+	/**
124
+	 * Enforces HTTPS on the login form
125
+	 *
126
+	 * @return bool
127
+	 */
128
+	private function enforceHttps()
129
+	{
130
+		if ($this->getSiteConfiguration()->getUseStrictTransportSecurity() !== false) {
131
+			if (WebRequest::isHttps()) {
132
+				// Client can clearly use HTTPS, so let's enforce it for all connections.
133
+				$this->headerQueue[] = "Strict-Transport-Security: max-age=15768000";
134
+			}
135
+			else {
136
+				// This is the login form, not the request form. We need protection here.
137
+				$this->redirectUrl('https://' . WebRequest::serverName() . WebRequest::requestUri());
138
+
139
+				return false;
140
+			}
141
+		}
142
+
143
+		return true;
144
+	}
145
+
146
+	protected abstract function providerSpecificSetup();
147
+
148
+	protected function setupPartial()
149
+	{
150
+		$database = $this->getDatabase();
151
+
152
+		// default stuff
153
+		$this->assign('alternatives', array()); // 'u2f' => array('U2F token'), 'otp' => array('TOTP', 'scratch', 'yubiotp')));
154
+
155
+		// is this stage one?
156
+		list($partialId, $partialStage) = WebRequest::getAuthPartialLogin();
157
+		if ($partialStage === null || $partialId === null) {
158
+			WebRequest::clearAuthPartialLogin();
159
+		}
160
+
161
+		// Check to see if we have a partial login in progress
162
+		$username = null;
163
+		if ($partialId !== null) {
164
+			// Yes, enforce this username
165
+			$this->partialUser = User::getById($partialId, $database);
166
+			$username = $this->partialUser->getUsername();
167
+
168
+			$this->setupAlternates($this->partialUser, $partialStage, $database);
169
+		}
170
+		else {
171
+			// No, see if we've preloaded a username
172
+			$preloadUsername = WebRequest::getString('tplUsername');
173
+			if ($preloadUsername !== null) {
174
+				$username = $preloadUsername;
175
+			}
176
+		}
177
+
178
+		if ($partialStage === null) {
179
+			$partialStage = 1;
180
+		}
181
+
182
+		$this->assign('partialStage', $partialStage);
183
+		$this->assign('username', $username);
184
+	}
185
+
186
+	/**
187
+	 * Redirect the user back to wherever they came from after a successful login
188
+	 *
189
+	 * @param User $user
190
+	 */
191
+	protected function goBackWhenceYouCame(User $user)
192
+	{
193
+		// Redirect to wherever the user came from
194
+		$redirectDestination = WebRequest::clearPostLoginRedirect();
195
+		if ($redirectDestination !== null) {
196
+			$this->redirectUrl($redirectDestination);
197
+		}
198
+		else {
199
+			if ($user->isNewUser()) {
200
+				// home page isn't allowed, go to preferences instead
201
+				$this->redirect('preferences');
202
+			}
203
+			else {
204
+				// go to the home page
205
+				$this->redirect('');
206
+			}
207
+		}
208
+	}
209
+
210
+	private function processLoginSuccess(User $user)
211
+	{
212
+		// Touch force logout
213
+		$user->setForceLogout(false);
214
+		$user->save();
215
+
216
+		$oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(),
217
+			$this->getSiteConfiguration());
218
+
219
+		if ($oauth->isFullyLinked()) {
220
+			try {
221
+				// Reload the user's identity ticket.
222
+				$oauth->refreshIdentity();
223
+
224
+				// Check for blocks
225
+				if ($oauth->getIdentity()->getBlocked()) {
226
+					// blocked!
227
+					SessionAlert::error("You are currently blocked on-wiki. You will not be able to log in until you are unblocked.");
228
+					$this->redirect('login');
229
+
230
+					return;
231
+				}
232
+			}
233
+			catch (OAuthException $ex) {
234
+				// Oops. Refreshing ticket failed. Force a re-auth.
235
+				$authoriseUrl = $oauth->getRequestToken();
236
+				WebRequest::setOAuthPartialLogin($user);
237
+				$this->redirectUrl($authoriseUrl);
238
+
239
+				return;
240
+			}
241
+		}
242
+
243
+		if (($this->getSiteConfiguration()->getEnforceOAuth() && !$oauth->isFullyLinked())
244
+			|| $oauth->isPartiallyLinked()
245
+		) {
246
+			$authoriseUrl = $oauth->getRequestToken();
247
+			WebRequest::setOAuthPartialLogin($user);
248
+			$this->redirectUrl($authoriseUrl);
249
+
250
+			return;
251
+		}
252
+
253
+		WebRequest::setLoggedInUser($user);
254
+
255
+		$this->goBackWhenceYouCame($user);
256
+	}
257
+
258
+	protected abstract function getProviderCredentials();
259
+
260
+	/**
261
+	 * @param User        $user
262
+	 * @param int         $partialStage
263
+	 * @param PdoDatabase $database
264
+	 *
265
+	 * @throws ApplicationLogicException
266
+	 */
267
+	private function processJumpNextStage(User $user, $partialStage, PdoDatabase $database)
268
+	{
269
+		WebRequest::setAuthPartialLogin($user->getId(), $partialStage + 1);
270
+
271
+		$sql = 'SELECT type FROM credential WHERE user = :user AND factor = :stage AND disabled = 0 ORDER BY priority';
272
+		$statement = $database->prepare($sql);
273
+		$statement->execute(array(':user' => $user->getId(), ':stage' => $partialStage + 1));
274
+		$nextStage = $statement->fetchColumn();
275
+		$statement->closeCursor();
276
+
277
+		if (!isset($this->nextPageMap[$nextStage])) {
278
+			throw new ApplicationLogicException('Unknown page handler for next authentication stage.');
279
+		}
280
+
281
+		$this->redirect("login/" . $this->nextPageMap[$nextStage]);
282
+	}
283
+
284
+	private function setupAlternates(User $user, $partialStage, PdoDatabase $database)
285
+	{
286
+		// get the providers available
287
+		$sql = 'SELECT type FROM credential WHERE user = :user AND factor = :stage AND disabled = 0';
288
+		$statement = $database->prepare($sql);
289
+		$statement->execute(array(':user' => $user->getId(), ':stage' => $partialStage));
290
+		$alternates = $statement->fetchAll(PDO::FETCH_COLUMN);
291
+
292
+		$types = array();
293
+		foreach ($alternates as $item) {
294
+			$type = $this->nextPageMap[$item];
295
+			if (!isset($types[$type])) {
296
+				$types[$type] = array();
297
+			}
298
+
299
+			$types[$type][] = $item;
300
+		}
301
+
302
+		$userOptions = array();
303
+		if (get_called_class() === PageOtpLogin::class) {
304
+			$userOptions = $this->setupUserOptionsForType($types, 'u2f', $userOptions);
305
+		}
306
+
307
+		if (get_called_class() === PageU2FLogin::class) {
308
+			$userOptions = $this->setupUserOptionsForType($types, 'otp', $userOptions);
309
+		}
310
+
311
+		$this->assign('alternatives', $userOptions);
312
+	}
313
+
314
+	/**
315
+	 * @param $types
316
+	 * @param $type
317
+	 * @param $userOptions
318
+	 *
319
+	 * @return mixed
320
+	 */
321
+	private function setupUserOptionsForType($types, $type, $userOptions)
322
+	{
323
+		if (isset($types[$type])) {
324
+			$options = $types[$type];
325
+
326
+			array_walk($options, function(&$val) {
327
+				$val = $this->names[$val];
328
+			});
329
+
330
+			$userOptions[$type] = $options;
331
+		}
332
+
333
+		return $userOptions;
334
+	}
335 335
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -134,7 +134,7 @@  discard block
 block discarded – undo
134 134
             }
135 135
             else {
136 136
                 // This is the login form, not the request form. We need protection here.
137
-                $this->redirectUrl('https://' . WebRequest::serverName() . WebRequest::requestUri());
137
+                $this->redirectUrl('https://'.WebRequest::serverName().WebRequest::requestUri());
138 138
 
139 139
                 return false;
140 140
             }
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
             throw new ApplicationLogicException('Unknown page handler for next authentication stage.');
279 279
         }
280 280
 
281
-        $this->redirect("login/" . $this->nextPageMap[$nextStage]);
281
+        $this->redirect("login/".$this->nextPageMap[$nextStage]);
282 282
     }
283 283
 
284 284
     private function setupAlternates(User $user, $partialStage, PdoDatabase $database)
Please login to merge, or discard this patch.
includes/Pages/UserAuth/Login/PagePasswordLogin.php 2 patches
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -13,31 +13,31 @@
 block discarded – undo
13 13
 
14 14
 class PagePasswordLogin extends LoginCredentialPageBase
15 15
 {
16
-    protected function providerSpecificSetup()
17
-    {
18
-        list($partialId, $partialStage) = WebRequest::getAuthPartialLogin();
19
-
20
-        if($partialId !== null && $partialStage > 1) {
21
-            $sql = 'SELECT type FROM credential WHERE user = :user AND factor = :stage AND disabled = 0 ORDER BY priority';
22
-            $statement = $this->getDatabase()->prepare($sql);
23
-            $statement->execute(array(':user' => $partialId, ':stage' => $partialStage));
24
-            $nextStage = $statement->fetchColumn();
25
-            $statement->closeCursor();
26
-
27
-            $this->redirect("login/" . $this->nextPageMap[$nextStage]);
28
-            return;
29
-        }
30
-
31
-        $this->setTemplate('login/password.tpl');
32
-    }
33
-
34
-    protected function getProviderCredentials()
35
-    {
36
-        $password = WebRequest::postString("password");
37
-        if ($password === null || $password === "") {
38
-            throw new ApplicationLogicException("No password specified");
39
-        }
40
-
41
-        return $password;
42
-    }
16
+	protected function providerSpecificSetup()
17
+	{
18
+		list($partialId, $partialStage) = WebRequest::getAuthPartialLogin();
19
+
20
+		if($partialId !== null && $partialStage > 1) {
21
+			$sql = 'SELECT type FROM credential WHERE user = :user AND factor = :stage AND disabled = 0 ORDER BY priority';
22
+			$statement = $this->getDatabase()->prepare($sql);
23
+			$statement->execute(array(':user' => $partialId, ':stage' => $partialStage));
24
+			$nextStage = $statement->fetchColumn();
25
+			$statement->closeCursor();
26
+
27
+			$this->redirect("login/" . $this->nextPageMap[$nextStage]);
28
+			return;
29
+		}
30
+
31
+		$this->setTemplate('login/password.tpl');
32
+	}
33
+
34
+	protected function getProviderCredentials()
35
+	{
36
+		$password = WebRequest::postString("password");
37
+		if ($password === null || $password === "") {
38
+			throw new ApplicationLogicException("No password specified");
39
+		}
40
+
41
+		return $password;
42
+	}
43 43
 }
44 44
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -17,14 +17,14 @@
 block discarded – undo
17 17
     {
18 18
         list($partialId, $partialStage) = WebRequest::getAuthPartialLogin();
19 19
 
20
-        if($partialId !== null && $partialStage > 1) {
20
+        if ($partialId !== null && $partialStage > 1) {
21 21
             $sql = 'SELECT type FROM credential WHERE user = :user AND factor = :stage AND disabled = 0 ORDER BY priority';
22 22
             $statement = $this->getDatabase()->prepare($sql);
23 23
             $statement->execute(array(':user' => $partialId, ':stage' => $partialStage));
24 24
             $nextStage = $statement->fetchColumn();
25 25
             $statement->closeCursor();
26 26
 
27
-            $this->redirect("login/" . $this->nextPageMap[$nextStage]);
27
+            $this->redirect("login/".$this->nextPageMap[$nextStage]);
28 28
             return;
29 29
         }
30 30
 
Please login to merge, or discard this patch.
includes/Pages/UserAuth/Login/PageOtpLogin.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -13,18 +13,18 @@
 block discarded – undo
13 13
 
14 14
 class PageOtpLogin extends LoginCredentialPageBase
15 15
 {
16
-    protected function providerSpecificSetup()
17
-    {
18
-        $this->setTemplate('login/otp.tpl');
19
-    }
16
+	protected function providerSpecificSetup()
17
+	{
18
+		$this->setTemplate('login/otp.tpl');
19
+	}
20 20
 
21
-    protected function getProviderCredentials()
22
-    {
23
-        $otp = WebRequest::postString("otp");
24
-        if ($otp === null || $otp === "") {
25
-            throw new ApplicationLogicException("No one-time code specified");
26
-        }
21
+	protected function getProviderCredentials()
22
+	{
23
+		$otp = WebRequest::postString("otp");
24
+		if ($otp === null || $otp === "") {
25
+			throw new ApplicationLogicException("No one-time code specified");
26
+		}
27 27
 
28
-        return $otp;
29
-    }
28
+		return $otp;
29
+	}
30 30
 }
31 31
\ No newline at end of file
Please login to merge, or discard this patch.