Completed
Push — newinternal-releasecandidate ( 06bb07...1c5b59 )
by Simon
06:04
created
includes/Pages/UserAuth/PagePreferences.php 1 patch
Indentation   +90 added lines, -90 removed lines patch added patch discarded remove patch
@@ -16,94 +16,94 @@
 block discarded – undo
16 16
 
17 17
 class PagePreferences extends InternalPageBase
18 18
 {
19
-    /**
20
-     * Main function for this page, when no specific actions are called.
21
-     * @return void
22
-     */
23
-    protected function main()
24
-    {
25
-        $this->setHtmlTitle('Preferences');
26
-
27
-        $enforceOAuth = $this->getSiteConfiguration()->getEnforceOAuth();
28
-        $database = $this->getDatabase();
29
-        $user = User::getCurrent($database);
30
-
31
-        // Dual mode
32
-        if (WebRequest::wasPosted()) {
33
-            $this->validateCSRFToken();
34
-            $user->setWelcomeSig(WebRequest::postString('sig'));
35
-            $user->setEmailSig(WebRequest::postString('emailsig'));
36
-            $user->setAbortPref(WebRequest::postBoolean('abortpref') ? 1 : 0);
37
-            $this->setCreationMode($user);
38
-            $user->setSkin(WebRequest::postBoolean('skintype') ? 'alt' : 'main');
39
-
40
-            $email = WebRequest::postEmail('email');
41
-            if ($email !== null) {
42
-                $user->setEmail($email);
43
-            }
44
-
45
-            $user->save();
46
-            SessionAlert::success("Preferences updated!");
47
-
48
-            $this->redirect('');
49
-        }
50
-        else {
51
-            $this->assignCSRFToken();
52
-            $this->setTemplate('preferences/prefs.tpl');
53
-            $this->assign("enforceOAuth", $enforceOAuth);
54
-
55
-            $this->assign('canManualCreate',
56
-                $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation'));
57
-            $this->assign('canOauthCreate',
58
-                $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation'));
59
-            $this->assign('canBotCreate',
60
-                $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation'));
61
-
62
-            $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
63
-                $this->getSiteConfiguration());
64
-            $this->assign('oauth', $oauth);
65
-
66
-            $identity = null;
67
-            if ($oauth->isFullyLinked()) {
68
-                $identity = $oauth->getIdentity();
69
-            }
70
-
71
-            $this->assign('identity', $identity);
72
-            $this->assign('graceTime', $this->getSiteConfiguration()->getOauthIdentityGraceTime());
73
-        }
74
-    }
75
-
76
-    protected function refreshOAuth()
77
-    {
78
-        if (!WebRequest::wasPosted()) {
79
-            $this->redirect('preferences');
80
-
81
-            return;
82
-        }
83
-
84
-        $database = $this->getDatabase();
85
-        $oauth = new OAuthUserHelper(User::getCurrent($database), $database, $this->getOAuthProtocolHelper(),
86
-            $this->getSiteConfiguration());
87
-        if ($oauth->isFullyLinked()) {
88
-            $oauth->refreshIdentity();
89
-        }
90
-
91
-        $this->redirect('preferences');
92
-
93
-        return;
94
-    }
95
-
96
-    /**
97
-     * @param User $user
98
-     */
99
-    protected function setCreationMode(User $user)
100
-    {
101
-        // if the user is selecting a creation mode that they are not allowed, do nothing.
102
-        // this has the side effect of allowing them to keep a selected mode that either has been changed for them,
103
-        // or that they have kept from when they previously had certain access.
104
-        $creationMode = WebRequest::postInt('creationmode');
105
-        if ($this->barrierTest($creationMode, $user, 'RequestCreation')) {
106
-            $user->setCreationMode($creationMode);
107
-        }
108
-    }
19
+	/**
20
+	 * Main function for this page, when no specific actions are called.
21
+	 * @return void
22
+	 */
23
+	protected function main()
24
+	{
25
+		$this->setHtmlTitle('Preferences');
26
+
27
+		$enforceOAuth = $this->getSiteConfiguration()->getEnforceOAuth();
28
+		$database = $this->getDatabase();
29
+		$user = User::getCurrent($database);
30
+
31
+		// Dual mode
32
+		if (WebRequest::wasPosted()) {
33
+			$this->validateCSRFToken();
34
+			$user->setWelcomeSig(WebRequest::postString('sig'));
35
+			$user->setEmailSig(WebRequest::postString('emailsig'));
36
+			$user->setAbortPref(WebRequest::postBoolean('abortpref') ? 1 : 0);
37
+			$this->setCreationMode($user);
38
+			$user->setSkin(WebRequest::postBoolean('skintype') ? 'alt' : 'main');
39
+
40
+			$email = WebRequest::postEmail('email');
41
+			if ($email !== null) {
42
+				$user->setEmail($email);
43
+			}
44
+
45
+			$user->save();
46
+			SessionAlert::success("Preferences updated!");
47
+
48
+			$this->redirect('');
49
+		}
50
+		else {
51
+			$this->assignCSRFToken();
52
+			$this->setTemplate('preferences/prefs.tpl');
53
+			$this->assign("enforceOAuth", $enforceOAuth);
54
+
55
+			$this->assign('canManualCreate',
56
+				$this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation'));
57
+			$this->assign('canOauthCreate',
58
+				$this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation'));
59
+			$this->assign('canBotCreate',
60
+				$this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation'));
61
+
62
+			$oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
63
+				$this->getSiteConfiguration());
64
+			$this->assign('oauth', $oauth);
65
+
66
+			$identity = null;
67
+			if ($oauth->isFullyLinked()) {
68
+				$identity = $oauth->getIdentity();
69
+			}
70
+
71
+			$this->assign('identity', $identity);
72
+			$this->assign('graceTime', $this->getSiteConfiguration()->getOauthIdentityGraceTime());
73
+		}
74
+	}
75
+
76
+	protected function refreshOAuth()
77
+	{
78
+		if (!WebRequest::wasPosted()) {
79
+			$this->redirect('preferences');
80
+
81
+			return;
82
+		}
83
+
84
+		$database = $this->getDatabase();
85
+		$oauth = new OAuthUserHelper(User::getCurrent($database), $database, $this->getOAuthProtocolHelper(),
86
+			$this->getSiteConfiguration());
87
+		if ($oauth->isFullyLinked()) {
88
+			$oauth->refreshIdentity();
89
+		}
90
+
91
+		$this->redirect('preferences');
92
+
93
+		return;
94
+	}
95
+
96
+	/**
97
+	 * @param User $user
98
+	 */
99
+	protected function setCreationMode(User $user)
100
+	{
101
+		// if the user is selecting a creation mode that they are not allowed, do nothing.
102
+		// this has the side effect of allowing them to keep a selected mode that either has been changed for them,
103
+		// or that they have kept from when they previously had certain access.
104
+		$creationMode = WebRequest::postInt('creationmode');
105
+		if ($this->barrierTest($creationMode, $user, 'RequestCreation')) {
106
+			$user->setCreationMode($creationMode);
107
+		}
108
+	}
109 109
 }
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCustomClose.php 1 patch
Indentation   +274 added lines, -274 removed lines patch added patch discarded remove patch
@@ -24,278 +24,278 @@
 block discarded – undo
24 24
 
25 25
 class PageCustomClose extends PageCloseRequest
26 26
 {
27
-    use RequestData;
28
-
29
-    protected function main()
30
-    {
31
-        $database = $this->getDatabase();
32
-
33
-        $request = $this->getRequest($database);
34
-        $currentUser = User::getCurrent($this->getDatabase());
35
-
36
-        if ($request->getStatus() === 'Closed') {
37
-            throw new ApplicationLogicException('Request is already closed');
38
-        }
39
-
40
-        // Dual-mode page
41
-        if (WebRequest::wasPosted()) {
42
-            $this->validateCSRFToken();
43
-            $this->doCustomClose($currentUser, $request, $database);
44
-
45
-            $this->redirect();
46
-        }
47
-        else {
48
-            $this->assignCSRFToken();
49
-            $this->showCustomCloseForm($database, $request);
50
-        }
51
-    }
52
-
53
-    /**
54
-     * @param $database
55
-     *
56
-     * @return Request
57
-     * @throws ApplicationLogicException
58
-     */
59
-    protected function getRequest(PdoDatabase $database)
60
-    {
61
-        $requestId = WebRequest::getInt('request');
62
-        if ($requestId === null) {
63
-            throw new ApplicationLogicException('Request ID not found');
64
-        }
65
-
66
-        /** @var Request $request */
67
-        $request = Request::getById($requestId, $database);
68
-
69
-        if ($request === false) {
70
-            throw new ApplicationLogicException('Request not found');
71
-        }
72
-
73
-        return $request;
74
-    }
75
-
76
-    /**
77
-     * @param PdoDatabase $database
78
-     *
79
-     * @return EmailTemplate|null
80
-     */
81
-    protected function getTemplate(PdoDatabase $database)
82
-    {
83
-        $templateId = WebRequest::getInt('template');
84
-        if ($templateId === null) {
85
-            return null;
86
-        }
87
-
88
-        /** @var EmailTemplate $template */
89
-        $template = EmailTemplate::getById($templateId, $database);
90
-        if ($template === false || !$template->getActive()) {
91
-            return null;
92
-        }
93
-
94
-        return $template;
95
-    }
96
-
97
-    /**
98
-     * @param $database
99
-     * @param $request
100
-     *
101
-     * @throws Exception
102
-     */
103
-    protected function showCustomCloseForm(PdoDatabase $database, Request $request)
104
-    {
105
-        $currentUser = User::getCurrent($database);
106
-        $config = $this->getSiteConfiguration();
107
-
108
-        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
109
-        if (!$allowedPrivateData) {
110
-            // we probably shouldn't be showing the user this form if they're not allowed to access private data...
111
-            throw new AccessDeniedException($this->getSecurityManager());
112
-        }
113
-
114
-        $template = $this->getTemplate($database);
115
-
116
-        // Preload data
117
-        $this->assign('defaultAction', '');
118
-        $this->assign('preloadText', '');
119
-        $this->assign('preloadTitle', '');
120
-
121
-        if ($template !== null) {
122
-            $this->assign('defaultAction', $template->getDefaultAction());
123
-            $this->assign('preloadText', $template->getText());
124
-            $this->assign('preloadTitle', $template->getName());
125
-        }
126
-
127
-        // Static data
128
-        $this->assign('requeststates', $config->getRequestStates());
129
-
130
-        // request data
131
-        $this->assign('requestId', $request->getIp());
132
-        $this->assign('updateVersion', $request->getUpdateVersion());
133
-        $this->setupBasicData($request, $config);
134
-        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
135
-        $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
136
-
137
-        // IP location
138
-        $trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
139
-        $this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
140
-
141
-        // Confirmations
142
-        $this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
143
-
144
-        $this->assign('canSkipCcMailingList', $this->barrierTest('skipCcMailingList', $currentUser));
145
-
146
-        $this->assign('allowWelcomeSkip', false);
147
-        $this->assign('forceWelcomeSkip', false);
148
-
149
-        $oauth = new OAuthUserHelper($currentUser, $this->getDatabase(), $this->getOAuthProtocolHelper(), $config);
150
-
151
-        if ($currentUser->getWelcomeTemplate() != 0) {
152
-            $this->assign('allowWelcomeSkip', true);
153
-
154
-            if (!$oauth->canWelcome()) {
155
-                $this->assign('forceWelcomeSkip', true);
156
-            }
157
-        }
158
-
159
-
160
-        // template
161
-        $this->setTemplate('custom-close.tpl');
162
-    }
163
-
164
-    /**
165
-     * @param User        $currentUser
166
-     * @param Request     $request
167
-     * @param PdoDatabase $database
168
-     *
169
-     * @throws ApplicationLogicException
170
-     */
171
-    protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
172
-    {
173
-        $messageBody = WebRequest::postString('msgbody');
174
-        if ($messageBody === null || trim($messageBody) === '') {
175
-            throw new ApplicationLogicException('Message body cannot be blank');
176
-        }
177
-
178
-        $ccMailingList = true;
179
-        if ($this->barrierTest('skipCcMailingList', $currentUser)) {
180
-            $ccMailingList = WebRequest::postBoolean('ccMailingList');
181
-        }
182
-
183
-        if ($request->getStatus() === 'Closed') {
184
-            throw new ApplicationLogicException('Request is already closed');
185
-        }
186
-
187
-        if (!(WebRequest::postBoolean('confirmEmailAlreadySent'))
188
-        ) {
189
-            throw new ApplicationLogicException('Not all confirmations checked');
190
-        }
191
-
192
-        $action = WebRequest::postString('action');
193
-        $availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
194
-
195
-        if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
196
-            // Close request
197
-            $this->closeRequest($request, $database, $action, $messageBody);
198
-
199
-            $this->processWelcome($action);
200
-
201
-            // Send the mail after the save, since save can be rolled back
202
-            $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
203
-        }
204
-        else {
205
-            if (array_key_exists($action, $availableRequestStates)) {
206
-                // Defer to other state
207
-                $this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
208
-
209
-                // Send the mail after the save, since save can be rolled back
210
-                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
211
-            }
212
-            else {
213
-                $request->setReserved(null);
214
-                $request->setUpdateVersion(WebRequest::postInt('updateversion'));
215
-                $request->save();
216
-
217
-                // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
218
-                // and be rolled back.
219
-
220
-                // Send mail
221
-                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
222
-
223
-                Logger::sentMail($database, $request, $messageBody);
224
-                Logger::unreserve($database, $request);
225
-
226
-                $this->getNotificationHelper()->sentMail($request);
227
-                SessionAlert::success("Sent mail to Request {$request->getId()}");
228
-            }
229
-        }
230
-    }
231
-
232
-    /**
233
-     * @param Request     $request
234
-     * @param PdoDatabase $database
235
-     * @param string      $action
236
-     * @param string      $messageBody
237
-     *
238
-     * @throws Exception
239
-     * @throws OptimisticLockFailedException
240
-     */
241
-    protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
242
-    {
243
-        $request->setStatus('Closed');
244
-        $request->setReserved(null);
245
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
246
-        $request->save();
247
-
248
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
249
-        // be rolled back.
250
-
251
-        if ($action == EmailTemplate::CREATED) {
252
-            $logCloseType = 'custom-y';
253
-            $notificationCloseType = "Custom, Created";
254
-        }
255
-        else {
256
-            $logCloseType = 'custom-n';
257
-            $notificationCloseType = "Custom, Not Created";
258
-        }
259
-
260
-        Logger::closeRequest($database, $request, $logCloseType, $messageBody);
261
-        $this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
262
-
263
-        $requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
264
-        SessionAlert::success("Request {$request->getId()} ({$requestName}) closed as {$notificationCloseType}.");
265
-    }
266
-
267
-    /**
268
-     * @param Request     $request
269
-     * @param PdoDatabase $database
270
-     * @param string      $action
271
-     * @param             $availableRequestStates
272
-     * @param string      $messageBody
273
-     *
274
-     * @throws Exception
275
-     * @throws OptimisticLockFailedException
276
-     */
277
-    protected function deferRequest(
278
-        Request $request,
279
-        PdoDatabase $database,
280
-        $action,
281
-        $availableRequestStates,
282
-        $messageBody
283
-    ) {
284
-        $request->setStatus($action);
285
-        $request->setReserved(null);
286
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
287
-        $request->save();
288
-
289
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
290
-        // and be rolled back.
291
-
292
-        $deferToLog = $availableRequestStates[$action]['defertolog'];
293
-        Logger::sentMail($database, $request, $messageBody);
294
-        Logger::deferRequest($database, $request, $deferToLog);
295
-
296
-        $this->getNotificationHelper()->requestDeferredWithMail($request);
297
-
298
-        $deferTo = $availableRequestStates[$action]['deferto'];
299
-        SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
300
-    }
27
+	use RequestData;
28
+
29
+	protected function main()
30
+	{
31
+		$database = $this->getDatabase();
32
+
33
+		$request = $this->getRequest($database);
34
+		$currentUser = User::getCurrent($this->getDatabase());
35
+
36
+		if ($request->getStatus() === 'Closed') {
37
+			throw new ApplicationLogicException('Request is already closed');
38
+		}
39
+
40
+		// Dual-mode page
41
+		if (WebRequest::wasPosted()) {
42
+			$this->validateCSRFToken();
43
+			$this->doCustomClose($currentUser, $request, $database);
44
+
45
+			$this->redirect();
46
+		}
47
+		else {
48
+			$this->assignCSRFToken();
49
+			$this->showCustomCloseForm($database, $request);
50
+		}
51
+	}
52
+
53
+	/**
54
+	 * @param $database
55
+	 *
56
+	 * @return Request
57
+	 * @throws ApplicationLogicException
58
+	 */
59
+	protected function getRequest(PdoDatabase $database)
60
+	{
61
+		$requestId = WebRequest::getInt('request');
62
+		if ($requestId === null) {
63
+			throw new ApplicationLogicException('Request ID not found');
64
+		}
65
+
66
+		/** @var Request $request */
67
+		$request = Request::getById($requestId, $database);
68
+
69
+		if ($request === false) {
70
+			throw new ApplicationLogicException('Request not found');
71
+		}
72
+
73
+		return $request;
74
+	}
75
+
76
+	/**
77
+	 * @param PdoDatabase $database
78
+	 *
79
+	 * @return EmailTemplate|null
80
+	 */
81
+	protected function getTemplate(PdoDatabase $database)
82
+	{
83
+		$templateId = WebRequest::getInt('template');
84
+		if ($templateId === null) {
85
+			return null;
86
+		}
87
+
88
+		/** @var EmailTemplate $template */
89
+		$template = EmailTemplate::getById($templateId, $database);
90
+		if ($template === false || !$template->getActive()) {
91
+			return null;
92
+		}
93
+
94
+		return $template;
95
+	}
96
+
97
+	/**
98
+	 * @param $database
99
+	 * @param $request
100
+	 *
101
+	 * @throws Exception
102
+	 */
103
+	protected function showCustomCloseForm(PdoDatabase $database, Request $request)
104
+	{
105
+		$currentUser = User::getCurrent($database);
106
+		$config = $this->getSiteConfiguration();
107
+
108
+		$allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
109
+		if (!$allowedPrivateData) {
110
+			// we probably shouldn't be showing the user this form if they're not allowed to access private data...
111
+			throw new AccessDeniedException($this->getSecurityManager());
112
+		}
113
+
114
+		$template = $this->getTemplate($database);
115
+
116
+		// Preload data
117
+		$this->assign('defaultAction', '');
118
+		$this->assign('preloadText', '');
119
+		$this->assign('preloadTitle', '');
120
+
121
+		if ($template !== null) {
122
+			$this->assign('defaultAction', $template->getDefaultAction());
123
+			$this->assign('preloadText', $template->getText());
124
+			$this->assign('preloadTitle', $template->getName());
125
+		}
126
+
127
+		// Static data
128
+		$this->assign('requeststates', $config->getRequestStates());
129
+
130
+		// request data
131
+		$this->assign('requestId', $request->getIp());
132
+		$this->assign('updateVersion', $request->getUpdateVersion());
133
+		$this->setupBasicData($request, $config);
134
+		$this->setupReservationDetails($request->getReserved(), $database, $currentUser);
135
+		$this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
136
+
137
+		// IP location
138
+		$trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
139
+		$this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
140
+
141
+		// Confirmations
142
+		$this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
143
+
144
+		$this->assign('canSkipCcMailingList', $this->barrierTest('skipCcMailingList', $currentUser));
145
+
146
+		$this->assign('allowWelcomeSkip', false);
147
+		$this->assign('forceWelcomeSkip', false);
148
+
149
+		$oauth = new OAuthUserHelper($currentUser, $this->getDatabase(), $this->getOAuthProtocolHelper(), $config);
150
+
151
+		if ($currentUser->getWelcomeTemplate() != 0) {
152
+			$this->assign('allowWelcomeSkip', true);
153
+
154
+			if (!$oauth->canWelcome()) {
155
+				$this->assign('forceWelcomeSkip', true);
156
+			}
157
+		}
158
+
159
+
160
+		// template
161
+		$this->setTemplate('custom-close.tpl');
162
+	}
163
+
164
+	/**
165
+	 * @param User        $currentUser
166
+	 * @param Request     $request
167
+	 * @param PdoDatabase $database
168
+	 *
169
+	 * @throws ApplicationLogicException
170
+	 */
171
+	protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
172
+	{
173
+		$messageBody = WebRequest::postString('msgbody');
174
+		if ($messageBody === null || trim($messageBody) === '') {
175
+			throw new ApplicationLogicException('Message body cannot be blank');
176
+		}
177
+
178
+		$ccMailingList = true;
179
+		if ($this->barrierTest('skipCcMailingList', $currentUser)) {
180
+			$ccMailingList = WebRequest::postBoolean('ccMailingList');
181
+		}
182
+
183
+		if ($request->getStatus() === 'Closed') {
184
+			throw new ApplicationLogicException('Request is already closed');
185
+		}
186
+
187
+		if (!(WebRequest::postBoolean('confirmEmailAlreadySent'))
188
+		) {
189
+			throw new ApplicationLogicException('Not all confirmations checked');
190
+		}
191
+
192
+		$action = WebRequest::postString('action');
193
+		$availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
194
+
195
+		if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
196
+			// Close request
197
+			$this->closeRequest($request, $database, $action, $messageBody);
198
+
199
+			$this->processWelcome($action);
200
+
201
+			// Send the mail after the save, since save can be rolled back
202
+			$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
203
+		}
204
+		else {
205
+			if (array_key_exists($action, $availableRequestStates)) {
206
+				// Defer to other state
207
+				$this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
208
+
209
+				// Send the mail after the save, since save can be rolled back
210
+				$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
211
+			}
212
+			else {
213
+				$request->setReserved(null);
214
+				$request->setUpdateVersion(WebRequest::postInt('updateversion'));
215
+				$request->save();
216
+
217
+				// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
218
+				// and be rolled back.
219
+
220
+				// Send mail
221
+				$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
222
+
223
+				Logger::sentMail($database, $request, $messageBody);
224
+				Logger::unreserve($database, $request);
225
+
226
+				$this->getNotificationHelper()->sentMail($request);
227
+				SessionAlert::success("Sent mail to Request {$request->getId()}");
228
+			}
229
+		}
230
+	}
231
+
232
+	/**
233
+	 * @param Request     $request
234
+	 * @param PdoDatabase $database
235
+	 * @param string      $action
236
+	 * @param string      $messageBody
237
+	 *
238
+	 * @throws Exception
239
+	 * @throws OptimisticLockFailedException
240
+	 */
241
+	protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
242
+	{
243
+		$request->setStatus('Closed');
244
+		$request->setReserved(null);
245
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
246
+		$request->save();
247
+
248
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
249
+		// be rolled back.
250
+
251
+		if ($action == EmailTemplate::CREATED) {
252
+			$logCloseType = 'custom-y';
253
+			$notificationCloseType = "Custom, Created";
254
+		}
255
+		else {
256
+			$logCloseType = 'custom-n';
257
+			$notificationCloseType = "Custom, Not Created";
258
+		}
259
+
260
+		Logger::closeRequest($database, $request, $logCloseType, $messageBody);
261
+		$this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
262
+
263
+		$requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
264
+		SessionAlert::success("Request {$request->getId()} ({$requestName}) closed as {$notificationCloseType}.");
265
+	}
266
+
267
+	/**
268
+	 * @param Request     $request
269
+	 * @param PdoDatabase $database
270
+	 * @param string      $action
271
+	 * @param             $availableRequestStates
272
+	 * @param string      $messageBody
273
+	 *
274
+	 * @throws Exception
275
+	 * @throws OptimisticLockFailedException
276
+	 */
277
+	protected function deferRequest(
278
+		Request $request,
279
+		PdoDatabase $database,
280
+		$action,
281
+		$availableRequestStates,
282
+		$messageBody
283
+	) {
284
+		$request->setStatus($action);
285
+		$request->setReserved(null);
286
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
287
+		$request->save();
288
+
289
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
290
+		// and be rolled back.
291
+
292
+		$deferToLog = $availableRequestStates[$action]['defertolog'];
293
+		Logger::sentMail($database, $request, $messageBody);
294
+		Logger::deferRequest($database, $request, $deferToLog);
295
+
296
+		$this->getNotificationHelper()->requestDeferredWithMail($request);
297
+
298
+		$deferTo = $availableRequestStates[$action]['deferto'];
299
+		SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
300
+	}
301 301
 }
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCloseRequest.php 2 patches
Indentation   +225 added lines, -225 removed lines patch added patch discarded remove patch
@@ -21,229 +21,229 @@
 block discarded – undo
21 21
 
22 22
 class PageCloseRequest extends RequestActionBase
23 23
 {
24
-    protected function main()
25
-    {
26
-        $this->processClose();
27
-    }
28
-
29
-    /**
30
-     * Main function for this page, when no specific actions are called.
31
-     * @throws ApplicationLogicException
32
-     */
33
-    final protected function processClose()
34
-    {
35
-        $this->checkPosted();
36
-        $database = $this->getDatabase();
37
-
38
-        $currentUser = User::getCurrent($database);
39
-        $template = $this->getTemplate($database);
40
-        $request = $this->getRequest($database);
41
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
42
-
43
-        if ($request->getStatus() === 'Closed') {
44
-            throw new ApplicationLogicException('Request is already closed');
45
-        }
46
-
47
-        if ($this->confirmEmailAlreadySent($request, $template)) {
48
-            return;
49
-        }
50
-
51
-        if ($this->checkReserveProtect($request, $currentUser)) {
52
-            return;
53
-        }
54
-
55
-        if ($this->confirmAccountCreated($request, $template)) {
56
-            return;
57
-        }
58
-
59
-        // I think we're good here...
60
-        $request->setStatus('Closed');
61
-        $request->setReserved(null);
62
-
63
-        Logger::closeRequest($database, $request, $template->getId(), null);
64
-
65
-        $request->save();
66
-
67
-        $this->processWelcome($template->getDefaultAction());
68
-
69
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
70
-        // be rolled back.
71
-
72
-        $this->getNotificationHelper()->requestClosed($request, $template->getName());
73
-        $sanitisedTemplateName = htmlentities($template->getName(), ENT_COMPAT, 'UTF-8');
74
-        SessionAlert::success("Request {$request->getId()} has been closed as {$sanitisedTemplateName}");
75
-
76
-        $this->sendMail($request, $template->getText(), $currentUser, false);
77
-
78
-        $this->redirect();
79
-    }
80
-
81
-    /**
82
-     * @param PdoDatabase $database
83
-     *
84
-     * @return EmailTemplate
85
-     * @throws ApplicationLogicException
86
-     */
87
-    protected function getTemplate(PdoDatabase $database)
88
-    {
89
-        $templateId = WebRequest::postInt('template');
90
-        if ($templateId === null) {
91
-            throw new ApplicationLogicException('No template specified');
92
-        }
93
-
94
-        /** @var EmailTemplate $template */
95
-        $template = EmailTemplate::getById($templateId, $database);
96
-        if ($template === false || !$template->getActive()) {
97
-            throw new ApplicationLogicException('Invalid or inactive template specified');
98
-        }
99
-
100
-        return $template;
101
-    }
102
-
103
-    /**
104
-     * @param Request       $request
105
-     * @param EmailTemplate $template
106
-     *
107
-     * @return bool
108
-     */
109
-    protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
110
-    {
111
-        if ($this->checkEmailAlreadySent($request)) {
112
-            $this->showConfirmation($request, $template, 'close-confirmations/email-sent.tpl');
113
-
114
-            return true;
115
-        }
116
-
117
-        return false;
118
-    }
119
-
120
-    protected function checkEmailAlreadySent(Request $request)
121
-    {
122
-        if ($request->getEmailSent() && !WebRequest::postBoolean('emailSentOverride')) {
123
-            return true;
124
-        }
125
-
126
-        return false;
127
-    }
128
-
129
-    protected function checkReserveProtect(Request $request, User $currentUser)
130
-    {
131
-        $reservationId = $request->getReserved();
132
-
133
-        if ($reservationId !== 0 && $reservationId !== null) {
134
-            if ($currentUser->getId() !== $reservationId) {
135
-                SessionAlert::error("Request is reserved by someone else.");
136
-                $this->redirect('/viewRequest', null, ['id' => $request->getId()] );
137
-                return true;
138
-            }
139
-        }
140
-
141
-        return false;
142
-    }
143
-
144
-    /**
145
-     * @param Request       $request
146
-     * @param EmailTemplate $template
147
-     *
148
-     * @return bool
149
-     * @throws \Waca\Exceptions\CurlException
150
-     */
151
-    protected function confirmAccountCreated(Request $request, EmailTemplate $template)
152
-    {
153
-        if ($this->checkAccountCreated($request, $template)) {
154
-            $this->showConfirmation($request, $template, 'close-confirmations/account-created.tpl');
155
-
156
-            return true;
157
-        }
158
-
159
-        return false;
160
-    }
161
-
162
-    protected function checkAccountCreated(Request $request, EmailTemplate $template)
163
-    {
164
-        if ($template->getDefaultAction() === EmailTemplate::CREATED && !WebRequest::postBoolean('createOverride')) {
165
-            $parameters = array(
166
-                'action'  => 'query',
167
-                'list'    => 'users',
168
-                'format'  => 'php',
169
-                'ususers' => $request->getName(),
170
-            );
171
-
172
-            $content = $this->getHttpHelper()->get($this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
173
-                $parameters);
174
-
175
-            $apiResult = unserialize($content);
176
-            $exists = !isset($apiResult['query']['users']['0']['missing']);
177
-
178
-            if (!$exists) {
179
-                return true;
180
-            }
181
-        }
182
-
183
-        return false;
184
-    }
185
-
186
-    /**
187
-     * @param Request $request
188
-     * @param string  $mailText
189
-     * @param User    $currentUser
190
-     * @param boolean $ccMailingList
191
-     */
192
-    protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
193
-    {
194
-        $requestEmailHelper = new RequestEmailHelper($this->getEmailHelper());
195
-        $requestEmailHelper->sendMail($request, $mailText, $currentUser, $ccMailingList);
196
-
197
-        $request->setEmailSent(true);
198
-        $request->save();
199
-    }
200
-
201
-    /**
202
-     * @param Request       $request
203
-     * @param EmailTemplate $template
204
-     * @param string        $templateName
205
-     *
206
-     * @throws Exception
207
-     * @return void
208
-     */
209
-    protected function showConfirmation(Request $request, EmailTemplate $template, $templateName)
210
-    {
211
-        $this->assignCSRFToken();
212
-
213
-        $this->assign('request', $request->getId());
214
-        $this->assign('template', $template->getId());
215
-
216
-        $this->assign('updateversion', $request->getUpdateVersion());
217
-
218
-        $this->assign('emailSentOverride', WebRequest::postBoolean('emailSentOverride') ? 'true' : 'false');
219
-        $this->assign('reserveOverride', WebRequest::postBoolean('reserveOverride') ? 'true' : 'false');
220
-        $this->assign('createOverride', WebRequest::postBoolean('createOverride') ? 'true' : 'false');
221
-
222
-        $this->setTemplate($templateName);
223
-    }
224
-
225
-    /**
226
-     * @param string $action
227
-     *
228
-     * @throws ApplicationLogicException
229
-     */
230
-    final protected function processWelcome(string $action): void
231
-    {
232
-        $database = $this->getDatabase();
233
-        $currentUser = User::getCurrent($database);
234
-
235
-        if ($action !== EmailTemplate::CREATED) {
236
-            return;
237
-        }
238
-
239
-        if ($currentUser->getWelcomeTemplate() === null) {
240
-            return;
241
-        }
242
-
243
-        if (WebRequest::postBoolean('skipAutoWelcome')) {
244
-            return;
245
-        }
246
-
247
-        $this->enqueueWelcomeTask($this->getRequest($database), null, $currentUser, $database);
248
-    }
24
+	protected function main()
25
+	{
26
+		$this->processClose();
27
+	}
28
+
29
+	/**
30
+	 * Main function for this page, when no specific actions are called.
31
+	 * @throws ApplicationLogicException
32
+	 */
33
+	final protected function processClose()
34
+	{
35
+		$this->checkPosted();
36
+		$database = $this->getDatabase();
37
+
38
+		$currentUser = User::getCurrent($database);
39
+		$template = $this->getTemplate($database);
40
+		$request = $this->getRequest($database);
41
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
42
+
43
+		if ($request->getStatus() === 'Closed') {
44
+			throw new ApplicationLogicException('Request is already closed');
45
+		}
46
+
47
+		if ($this->confirmEmailAlreadySent($request, $template)) {
48
+			return;
49
+		}
50
+
51
+		if ($this->checkReserveProtect($request, $currentUser)) {
52
+			return;
53
+		}
54
+
55
+		if ($this->confirmAccountCreated($request, $template)) {
56
+			return;
57
+		}
58
+
59
+		// I think we're good here...
60
+		$request->setStatus('Closed');
61
+		$request->setReserved(null);
62
+
63
+		Logger::closeRequest($database, $request, $template->getId(), null);
64
+
65
+		$request->save();
66
+
67
+		$this->processWelcome($template->getDefaultAction());
68
+
69
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
70
+		// be rolled back.
71
+
72
+		$this->getNotificationHelper()->requestClosed($request, $template->getName());
73
+		$sanitisedTemplateName = htmlentities($template->getName(), ENT_COMPAT, 'UTF-8');
74
+		SessionAlert::success("Request {$request->getId()} has been closed as {$sanitisedTemplateName}");
75
+
76
+		$this->sendMail($request, $template->getText(), $currentUser, false);
77
+
78
+		$this->redirect();
79
+	}
80
+
81
+	/**
82
+	 * @param PdoDatabase $database
83
+	 *
84
+	 * @return EmailTemplate
85
+	 * @throws ApplicationLogicException
86
+	 */
87
+	protected function getTemplate(PdoDatabase $database)
88
+	{
89
+		$templateId = WebRequest::postInt('template');
90
+		if ($templateId === null) {
91
+			throw new ApplicationLogicException('No template specified');
92
+		}
93
+
94
+		/** @var EmailTemplate $template */
95
+		$template = EmailTemplate::getById($templateId, $database);
96
+		if ($template === false || !$template->getActive()) {
97
+			throw new ApplicationLogicException('Invalid or inactive template specified');
98
+		}
99
+
100
+		return $template;
101
+	}
102
+
103
+	/**
104
+	 * @param Request       $request
105
+	 * @param EmailTemplate $template
106
+	 *
107
+	 * @return bool
108
+	 */
109
+	protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
110
+	{
111
+		if ($this->checkEmailAlreadySent($request)) {
112
+			$this->showConfirmation($request, $template, 'close-confirmations/email-sent.tpl');
113
+
114
+			return true;
115
+		}
116
+
117
+		return false;
118
+	}
119
+
120
+	protected function checkEmailAlreadySent(Request $request)
121
+	{
122
+		if ($request->getEmailSent() && !WebRequest::postBoolean('emailSentOverride')) {
123
+			return true;
124
+		}
125
+
126
+		return false;
127
+	}
128
+
129
+	protected function checkReserveProtect(Request $request, User $currentUser)
130
+	{
131
+		$reservationId = $request->getReserved();
132
+
133
+		if ($reservationId !== 0 && $reservationId !== null) {
134
+			if ($currentUser->getId() !== $reservationId) {
135
+				SessionAlert::error("Request is reserved by someone else.");
136
+				$this->redirect('/viewRequest', null, ['id' => $request->getId()] );
137
+				return true;
138
+			}
139
+		}
140
+
141
+		return false;
142
+	}
143
+
144
+	/**
145
+	 * @param Request       $request
146
+	 * @param EmailTemplate $template
147
+	 *
148
+	 * @return bool
149
+	 * @throws \Waca\Exceptions\CurlException
150
+	 */
151
+	protected function confirmAccountCreated(Request $request, EmailTemplate $template)
152
+	{
153
+		if ($this->checkAccountCreated($request, $template)) {
154
+			$this->showConfirmation($request, $template, 'close-confirmations/account-created.tpl');
155
+
156
+			return true;
157
+		}
158
+
159
+		return false;
160
+	}
161
+
162
+	protected function checkAccountCreated(Request $request, EmailTemplate $template)
163
+	{
164
+		if ($template->getDefaultAction() === EmailTemplate::CREATED && !WebRequest::postBoolean('createOverride')) {
165
+			$parameters = array(
166
+				'action'  => 'query',
167
+				'list'    => 'users',
168
+				'format'  => 'php',
169
+				'ususers' => $request->getName(),
170
+			);
171
+
172
+			$content = $this->getHttpHelper()->get($this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
173
+				$parameters);
174
+
175
+			$apiResult = unserialize($content);
176
+			$exists = !isset($apiResult['query']['users']['0']['missing']);
177
+
178
+			if (!$exists) {
179
+				return true;
180
+			}
181
+		}
182
+
183
+		return false;
184
+	}
185
+
186
+	/**
187
+	 * @param Request $request
188
+	 * @param string  $mailText
189
+	 * @param User    $currentUser
190
+	 * @param boolean $ccMailingList
191
+	 */
192
+	protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
193
+	{
194
+		$requestEmailHelper = new RequestEmailHelper($this->getEmailHelper());
195
+		$requestEmailHelper->sendMail($request, $mailText, $currentUser, $ccMailingList);
196
+
197
+		$request->setEmailSent(true);
198
+		$request->save();
199
+	}
200
+
201
+	/**
202
+	 * @param Request       $request
203
+	 * @param EmailTemplate $template
204
+	 * @param string        $templateName
205
+	 *
206
+	 * @throws Exception
207
+	 * @return void
208
+	 */
209
+	protected function showConfirmation(Request $request, EmailTemplate $template, $templateName)
210
+	{
211
+		$this->assignCSRFToken();
212
+
213
+		$this->assign('request', $request->getId());
214
+		$this->assign('template', $template->getId());
215
+
216
+		$this->assign('updateversion', $request->getUpdateVersion());
217
+
218
+		$this->assign('emailSentOverride', WebRequest::postBoolean('emailSentOverride') ? 'true' : 'false');
219
+		$this->assign('reserveOverride', WebRequest::postBoolean('reserveOverride') ? 'true' : 'false');
220
+		$this->assign('createOverride', WebRequest::postBoolean('createOverride') ? 'true' : 'false');
221
+
222
+		$this->setTemplate($templateName);
223
+	}
224
+
225
+	/**
226
+	 * @param string $action
227
+	 *
228
+	 * @throws ApplicationLogicException
229
+	 */
230
+	final protected function processWelcome(string $action): void
231
+	{
232
+		$database = $this->getDatabase();
233
+		$currentUser = User::getCurrent($database);
234
+
235
+		if ($action !== EmailTemplate::CREATED) {
236
+			return;
237
+		}
238
+
239
+		if ($currentUser->getWelcomeTemplate() === null) {
240
+			return;
241
+		}
242
+
243
+		if (WebRequest::postBoolean('skipAutoWelcome')) {
244
+			return;
245
+		}
246
+
247
+		$this->enqueueWelcomeTask($this->getRequest($database), null, $currentUser, $database);
248
+	}
249 249
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -133,7 +133,7 @@
 block discarded – undo
133 133
         if ($reservationId !== 0 && $reservationId !== null) {
134 134
             if ($currentUser->getId() !== $reservationId) {
135 135
                 SessionAlert::error("Request is reserved by someone else.");
136
-                $this->redirect('/viewRequest', null, ['id' => $request->getId()] );
136
+                $this->redirect('/viewRequest', null, ['id' => $request->getId()]);
137 137
                 return true;
138 138
             }
139 139
         }
Please login to merge, or discard this patch.
includes/Router/ApiRequestRouter.php 1 patch
Indentation   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -22,49 +22,49 @@
 block discarded – undo
22 22
 
23 23
 class ApiRequestRouter implements IRequestRouter
24 24
 {
25
-    /**
26
-     * @return string[]
27
-     */
28
-    public static function getActionList()
29
-    {
30
-        return array("count", "status", "stats", "help", "monitor");
31
-    }
25
+	/**
26
+	 * @return string[]
27
+	 */
28
+	public static function getActionList()
29
+	{
30
+		return array("count", "status", "stats", "help", "monitor");
31
+	}
32 32
 
33
-    /**
34
-     * @return IRoutedTask
35
-     * @throws Exception
36
-     */
37
-    public function route()
38
-    {
39
-        $requestAction = WebRequest::getString('action');
33
+	/**
34
+	 * @return IRoutedTask
35
+	 * @throws Exception
36
+	 */
37
+	public function route()
38
+	{
39
+		$requestAction = WebRequest::getString('action');
40 40
 
41
-        switch ($requestAction) {
42
-            case "count":
43
-                $result = new CountAction();
44
-                break;
45
-            case "status":
46
-                $result = new StatusAction();
47
-                break;
48
-            case "stats":
49
-                $result = new StatsAction();
50
-                break;
51
-            case "help":
52
-                $result = new HelpAction();
53
-                break;
54
-            case "monitor":
55
-                $result = new MonitorAction();
56
-                break;
57
-            case "users":
58
-                $result = new JsUsersAction();
59
-                break;
60
-            case "templates":
61
-                $result = new JsTemplateConfirmsAction();
62
-                break;
63
-            default:
64
-                $result = new UnknownAction();
65
-                break;
66
-        }
41
+		switch ($requestAction) {
42
+			case "count":
43
+				$result = new CountAction();
44
+				break;
45
+			case "status":
46
+				$result = new StatusAction();
47
+				break;
48
+			case "stats":
49
+				$result = new StatsAction();
50
+				break;
51
+			case "help":
52
+				$result = new HelpAction();
53
+				break;
54
+			case "monitor":
55
+				$result = new MonitorAction();
56
+				break;
57
+			case "users":
58
+				$result = new JsUsersAction();
59
+				break;
60
+			case "templates":
61
+				$result = new JsTemplateConfirmsAction();
62
+				break;
63
+			default:
64
+				$result = new UnknownAction();
65
+				break;
66
+		}
67 67
 
68
-        return $result;
69
-    }
68
+		return $result;
69
+	}
70 70
 }
Please login to merge, or discard this patch.
includes/Security/ContentSecurityPolicyManager.php 2 patches
Indentation   +85 added lines, -85 removed lines patch added patch discarded remove patch
@@ -12,100 +12,100 @@
 block discarded – undo
12 12
 
13 13
 class ContentSecurityPolicyManager
14 14
 {
15
-    private $policy = [
16
-        'default-src'     => [],
17
-        'script-src'      => ['self', 'nonce'],
18
-        'script-src-elem' => ['self', 'nonce'],
19
-        'script-src-attr' => [],
20
-        'connect-src'     => ['self'],
21
-        'style-src'       => ['self'],
22
-        'style-src-elem'  => ['self'],
23
-        'style-src-attr'  => [],
24
-        'img-src'         => ['self', 'data:', 'https://upload.wikimedia.org', 'https://accounts-dev.wmflabs.org/'],
25
-        'font-src'        => ['self'],
26
-        'form-action'     => ['self', 'oauth'],
27
-        'frame-ancestors' => [],
28
-    ];
29
-    private $nonce = null;
30
-    private $reportOnly = false;
31
-    /**
32
-     * @var SiteConfiguration
33
-     */
34
-    private $configuration;
15
+	private $policy = [
16
+		'default-src'     => [],
17
+		'script-src'      => ['self', 'nonce'],
18
+		'script-src-elem' => ['self', 'nonce'],
19
+		'script-src-attr' => [],
20
+		'connect-src'     => ['self'],
21
+		'style-src'       => ['self'],
22
+		'style-src-elem'  => ['self'],
23
+		'style-src-attr'  => [],
24
+		'img-src'         => ['self', 'data:', 'https://upload.wikimedia.org', 'https://accounts-dev.wmflabs.org/'],
25
+		'font-src'        => ['self'],
26
+		'form-action'     => ['self', 'oauth'],
27
+		'frame-ancestors' => [],
28
+	];
29
+	private $nonce = null;
30
+	private $reportOnly = false;
31
+	/**
32
+	 * @var SiteConfiguration
33
+	 */
34
+	private $configuration;
35 35
 
36
-    /**
37
-     * ContentSecurityPolicyManager constructor.
38
-     *
39
-     * @param SiteConfiguration $configuration
40
-     */
41
-    public function __construct(SiteConfiguration $configuration)
42
-    {
43
-        $this->configuration = $configuration;
44
-    }
36
+	/**
37
+	 * ContentSecurityPolicyManager constructor.
38
+	 *
39
+	 * @param SiteConfiguration $configuration
40
+	 */
41
+	public function __construct(SiteConfiguration $configuration)
42
+	{
43
+		$this->configuration = $configuration;
44
+	}
45 45
 
46
-    public function getNonce()
47
-    {
48
-        if ($this->nonce === null) {
49
-            $this->nonce = base64_encode(openssl_random_pseudo_bytes(32));
50
-        }
46
+	public function getNonce()
47
+	{
48
+		if ($this->nonce === null) {
49
+			$this->nonce = base64_encode(openssl_random_pseudo_bytes(32));
50
+		}
51 51
 
52
-        return $this->nonce;
53
-    }
52
+		return $this->nonce;
53
+	}
54 54
 
55
-    public function getHeader(): string
56
-    {
57
-        $reportOnly = '';
58
-        if ($this->reportOnly) {
59
-            $reportOnly = '-Report-Only';
60
-        }
55
+	public function getHeader(): string
56
+	{
57
+		$reportOnly = '';
58
+		if ($this->reportOnly) {
59
+			$reportOnly = '-Report-Only';
60
+		}
61 61
 
62
-        $constructedPolicy = "Content-Security-Policy{$reportOnly}: ";
62
+		$constructedPolicy = "Content-Security-Policy{$reportOnly}: ";
63 63
 
64
-        foreach ($this->policy as $item => $values) {
65
-            $constructedPolicy .= $item . ' ';
66
-            $policyIsSet = false;
64
+		foreach ($this->policy as $item => $values) {
65
+			$constructedPolicy .= $item . ' ';
66
+			$policyIsSet = false;
67 67
 
68
-            if (count($values) > 0) {
69
-                foreach ($values as $value) {
70
-                    switch ($value) {
71
-                        case 'none':
72
-                        case 'self':
73
-                        case 'strict-dynamic':
74
-                            $policyIsSet = true;
75
-                            $constructedPolicy .= "'{$value}' ";
76
-                            break;
77
-                        case 'nonce':
78
-                            if ($this->nonce !== null) {
79
-                                $policyIsSet = true;
80
-                                $constructedPolicy .= "'nonce-{$this->nonce}' ";
81
-                            }
82
-                            break;
83
-                        case 'oauth':
84
-                            $policyIsSet = true;
85
-                            $constructedPolicy .= "{$this->configuration->getOauthMediaWikiCanonicalServer()} ";
86
-                            break;
87
-                        default:
88
-                            $policyIsSet = true;
89
-                            $constructedPolicy .= $value . ' ';
90
-                            break;
91
-                    }
92
-                }
68
+			if (count($values) > 0) {
69
+				foreach ($values as $value) {
70
+					switch ($value) {
71
+						case 'none':
72
+						case 'self':
73
+						case 'strict-dynamic':
74
+							$policyIsSet = true;
75
+							$constructedPolicy .= "'{$value}' ";
76
+							break;
77
+						case 'nonce':
78
+							if ($this->nonce !== null) {
79
+								$policyIsSet = true;
80
+								$constructedPolicy .= "'nonce-{$this->nonce}' ";
81
+							}
82
+							break;
83
+						case 'oauth':
84
+							$policyIsSet = true;
85
+							$constructedPolicy .= "{$this->configuration->getOauthMediaWikiCanonicalServer()} ";
86
+							break;
87
+						default:
88
+							$policyIsSet = true;
89
+							$constructedPolicy .= $value . ' ';
90
+							break;
91
+					}
92
+				}
93 93
 
94
-                if (!$policyIsSet) {
95
-                    $constructedPolicy .= "'none' ";
96
-                }
97
-            }
98
-            else {
99
-                $constructedPolicy .= "'none' ";
100
-            }
94
+				if (!$policyIsSet) {
95
+					$constructedPolicy .= "'none' ";
96
+				}
97
+			}
98
+			else {
99
+				$constructedPolicy .= "'none' ";
100
+			}
101 101
 
102
-            $constructedPolicy .= '; ';
103
-        }
102
+			$constructedPolicy .= '; ';
103
+		}
104 104
 
105
-        if ($this->configuration->getCspReportUri() !== null) {
106
-            $constructedPolicy .= 'report-uri ' . $this->configuration->getCspReportUri();
107
-        }
105
+		if ($this->configuration->getCspReportUri() !== null) {
106
+			$constructedPolicy .= 'report-uri ' . $this->configuration->getCspReportUri();
107
+		}
108 108
 
109
-        return $constructedPolicy;
110
-    }
109
+		return $constructedPolicy;
110
+	}
111 111
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -62,7 +62,7 @@  discard block
 block discarded – undo
62 62
         $constructedPolicy = "Content-Security-Policy{$reportOnly}: ";
63 63
 
64 64
         foreach ($this->policy as $item => $values) {
65
-            $constructedPolicy .= $item . ' ';
65
+            $constructedPolicy .= $item.' ';
66 66
             $policyIsSet = false;
67 67
 
68 68
             if (count($values) > 0) {
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
                             break;
87 87
                         default:
88 88
                             $policyIsSet = true;
89
-                            $constructedPolicy .= $value . ' ';
89
+                            $constructedPolicy .= $value.' ';
90 90
                             break;
91 91
                     }
92 92
                 }
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
         }
104 104
 
105 105
         if ($this->configuration->getCspReportUri() !== null) {
106
-            $constructedPolicy .= 'report-uri ' . $this->configuration->getCspReportUri();
106
+            $constructedPolicy .= 'report-uri '.$this->configuration->getCspReportUri();
107 107
         }
108 108
 
109 109
         return $constructedPolicy;
Please login to merge, or discard this patch.
includes/Security/RoleConfiguration.php 1 patch
Indentation   +360 added lines, -360 removed lines patch added patch discarded remove patch
@@ -47,391 +47,391 @@
 block discarded – undo
47 47
 
48 48
 class RoleConfiguration
49 49
 {
50
-    const ACCESS_ALLOW = 1;
51
-    const ACCESS_DENY = -1;
52
-    const ACCESS_DEFAULT = 0;
53
-    const MAIN = 'main';
54
-    const ALL = '*';
55
-    /**
56
-     * A map of roles to rights
57
-     *
58
-     * For example:
59
-     *
60
-     * array(
61
-     *   'myrole' => array(
62
-     *       PageMyPage::class => array(
63
-     *           'edit' => self::ACCESS_ALLOW,
64
-     *           'create' => self::ACCESS_DENY,
65
-     *       )
66
-     *   )
67
-     * )
68
-     *
69
-     * Note that DENY takes precedence over everything else when roles are combined, followed by ALLOW, followed by
70
-     * DEFAULT. Thus, if you have the following ([A]llow, [D]eny, [-] (default)) grants in different roles, this should
71
-     * be the expected result:
72
-     *
73
-     * - (-,-,-) = - (default because nothing to explicitly say allowed or denied equates to a denial)
74
-     * - (A,-,-) = A
75
-     * - (D,-,-) = D
76
-     * - (A,D,-) = D (deny takes precedence over allow)
77
-     * - (A,A,A) = A (repetition has no effect)
78
-     *
79
-     * The public role is special, and is applied to all users automatically. Avoid using deny on this role.
80
-     *
81
-     * @var array
82
-     */
83
-    private $roleConfig = array(
84
-        'public'            => array(
85
-            /*
50
+	const ACCESS_ALLOW = 1;
51
+	const ACCESS_DENY = -1;
52
+	const ACCESS_DEFAULT = 0;
53
+	const MAIN = 'main';
54
+	const ALL = '*';
55
+	/**
56
+	 * A map of roles to rights
57
+	 *
58
+	 * For example:
59
+	 *
60
+	 * array(
61
+	 *   'myrole' => array(
62
+	 *       PageMyPage::class => array(
63
+	 *           'edit' => self::ACCESS_ALLOW,
64
+	 *           'create' => self::ACCESS_DENY,
65
+	 *       )
66
+	 *   )
67
+	 * )
68
+	 *
69
+	 * Note that DENY takes precedence over everything else when roles are combined, followed by ALLOW, followed by
70
+	 * DEFAULT. Thus, if you have the following ([A]llow, [D]eny, [-] (default)) grants in different roles, this should
71
+	 * be the expected result:
72
+	 *
73
+	 * - (-,-,-) = - (default because nothing to explicitly say allowed or denied equates to a denial)
74
+	 * - (A,-,-) = A
75
+	 * - (D,-,-) = D
76
+	 * - (A,D,-) = D (deny takes precedence over allow)
77
+	 * - (A,A,A) = A (repetition has no effect)
78
+	 *
79
+	 * The public role is special, and is applied to all users automatically. Avoid using deny on this role.
80
+	 *
81
+	 * @var array
82
+	 */
83
+	private $roleConfig = array(
84
+		'public'            => array(
85
+			/*
86 86
              * THIS ROLE IS GRANTED TO ALL LOGGED *OUT* USERS IMPLICITLY.
87 87
              *
88 88
              * USERS IN THIS ROLE DO NOT HAVE TO BE IDENTIFIED TO GET THE RIGHTS CONFERRED HERE.
89 89
              * DO NOT ADD ANY SECURITY-SENSITIVE RIGHTS HERE.
90 90
              */
91
-            '_childRoles'   => array(
92
-                'publicStats',
93
-            ),
94
-            PageTeam::class => array(
95
-                self::MAIN => self::ACCESS_ALLOW,
96
-            ),
97
-            PageXffDemo::class        => array(
98
-                self::MAIN  => self::ACCESS_ALLOW,
99
-            )
100
-        ),
101
-        'loggedIn'          => array(
102
-            /*
91
+			'_childRoles'   => array(
92
+				'publicStats',
93
+			),
94
+			PageTeam::class => array(
95
+				self::MAIN => self::ACCESS_ALLOW,
96
+			),
97
+			PageXffDemo::class        => array(
98
+				self::MAIN  => self::ACCESS_ALLOW,
99
+			)
100
+		),
101
+		'loggedIn'          => array(
102
+			/*
103 103
              * THIS ROLE IS GRANTED TO ALL LOGGED IN USERS IMPLICITLY.
104 104
              *
105 105
              * USERS IN THIS ROLE DO NOT HAVE TO BE IDENTIFIED TO GET THE RIGHTS CONFERRED HERE.
106 106
              * DO NOT ADD ANY SECURITY-SENSITIVE RIGHTS HERE.
107 107
              */
108
-            '_childRoles'             => array(
109
-                'public',
110
-            ),
111
-            PagePreferences::class    => array(
112
-                self::MAIN => self::ACCESS_ALLOW,
113
-                'refreshOAuth' => self::ACCESS_ALLOW,
114
-            ),
115
-            PageChangePassword::class => array(
116
-                self::MAIN => self::ACCESS_ALLOW,
117
-            ),
118
-            PageMultiFactor::class    => array(
119
-                self::MAIN          => self::ACCESS_ALLOW,
120
-                'scratch'           => self::ACCESS_ALLOW,
121
-                'enableYubikeyOtp'  => self::ACCESS_ALLOW,
122
-                'disableYubikeyOtp' => self::ACCESS_ALLOW,
123
-                'enableTotp'        => self::ACCESS_ALLOW,
124
-                'disableTotp'       => self::ACCESS_ALLOW,
125
-            ),
126
-            PageOAuth::class          => array(
127
-                'attach' => self::ACCESS_ALLOW,
128
-                'detach' => self::ACCESS_ALLOW,
129
-            ),
130
-        ),
131
-        'user'              => array(
132
-            '_description'                       => 'A standard tool user.',
133
-            '_editableBy'                        => array('admin', 'toolRoot'),
134
-            '_childRoles'                        => array(
135
-                'internalStats',
136
-            ),
137
-            PageMain::class                      => array(
138
-                self::MAIN => self::ACCESS_ALLOW,
139
-            ),
140
-            PageBan::class                       => array(
141
-                self::MAIN => self::ACCESS_ALLOW,
142
-            ),
143
-            PageEditComment::class               => array(
144
-                self::MAIN => self::ACCESS_ALLOW,
145
-            ),
146
-            PageEmailManagement::class           => array(
147
-                self::MAIN => self::ACCESS_ALLOW,
148
-                'view'     => self::ACCESS_ALLOW,
149
-            ),
150
-            PageExpandedRequestList::class       => array(
151
-                self::MAIN => self::ACCESS_ALLOW,
152
-            ),
153
-            PageLog::class                       => array(
154
-                self::MAIN => self::ACCESS_ALLOW,
155
-            ),
156
-            PageSearch::class                    => array(
157
-                self::MAIN => self::ACCESS_ALLOW,
158
-            ),
159
-            PageWelcomeTemplateManagement::class => array(
160
-                self::MAIN => self::ACCESS_ALLOW,
161
-                'select'   => self::ACCESS_ALLOW,
162
-                'view'     => self::ACCESS_ALLOW,
163
-            ),
164
-            PageViewRequest::class               => array(
165
-                self::MAIN       => self::ACCESS_ALLOW,
166
-                'seeAllRequests' => self::ACCESS_ALLOW,
167
-            ),
168
-            'RequestData'                        => array(
169
-                'seePrivateDataWhenReserved' => self::ACCESS_ALLOW,
170
-                'seePrivateDataWithHash'     => self::ACCESS_ALLOW,
171
-            ),
172
-            PageCustomClose::class               => array(
173
-                self::MAIN => self::ACCESS_ALLOW,
174
-            ),
175
-            PageComment::class                   => array(
176
-                self::MAIN => self::ACCESS_ALLOW,
177
-            ),
178
-            PageCloseRequest::class              => array(
179
-                self::MAIN => self::ACCESS_ALLOW,
180
-            ),
181
-            PageCreateRequest::class             => array(
182
-                self::MAIN => self::ACCESS_ALLOW,
183
-            ),
184
-            PageDeferRequest::class              => array(
185
-                self::MAIN => self::ACCESS_ALLOW,
186
-            ),
187
-            PageDropRequest::class               => array(
188
-                self::MAIN => self::ACCESS_ALLOW,
189
-            ),
190
-            PageReservation::class               => array(
191
-                self::MAIN => self::ACCESS_ALLOW,
192
-            ),
193
-            PageSendToUser::class                => array(
194
-                self::MAIN => self::ACCESS_ALLOW,
195
-            ),
196
-            PageBreakReservation::class          => array(
197
-                self::MAIN => self::ACCESS_ALLOW,
198
-            ),
199
-            PageJobQueue::class                  => array(
200
-                self::MAIN => self::ACCESS_ALLOW,
201
-                'view'     => self::ACCESS_ALLOW,
202
-                'all'      => self::ACCESS_ALLOW,
203
-            ),
204
-            'RequestCreation'                    => array(
205
-                User::CREATION_MANUAL => self::ACCESS_ALLOW,
206
-            ),
207
-            'GlobalInfo'                         => array(
208
-                'viewSiteNotice' => self::ACCESS_ALLOW,
209
-                'viewOnlineUsers' => self::ACCESS_ALLOW,
210
-            ),
211
-        ),
212
-        'admin'             => array(
213
-            '_description'                       => 'A tool administrator.',
214
-            '_editableBy'                        => array('admin', 'toolRoot'),
215
-            '_childRoles'                        => array(
216
-                'user',
217
-                'requestAdminTools',
218
-            ),
219
-            PageEmailManagement::class           => array(
220
-                'edit'   => self::ACCESS_ALLOW,
221
-                'create' => self::ACCESS_ALLOW,
222
-            ),
223
-            PageSiteNotice::class                => array(
224
-                self::MAIN => self::ACCESS_ALLOW,
225
-            ),
226
-            PageUserManagement::class            => array(
227
-                self::MAIN  => self::ACCESS_ALLOW,
228
-                'approve'   => self::ACCESS_ALLOW,
229
-                'decline'   => self::ACCESS_ALLOW,
230
-                'rename'    => self::ACCESS_ALLOW,
231
-                'editUser'  => self::ACCESS_ALLOW,
232
-                'suspend'   => self::ACCESS_ALLOW,
233
-                'editRoles' => self::ACCESS_ALLOW,
234
-            ),
235
-            PageWelcomeTemplateManagement::class => array(
236
-                'edit'   => self::ACCESS_ALLOW,
237
-                'delete' => self::ACCESS_ALLOW,
238
-                'add'    => self::ACCESS_ALLOW,
239
-            ),
240
-            PageJobQueue::class                  => array(
241
-                'acknowledge' => self::ACCESS_ALLOW,
242
-                'requeue'     => self::ACCESS_ALLOW,
243
-            ),
244
-        ),
245
-        'checkuser'         => array(
246
-            '_description'            => 'A user with CheckUser access',
247
-            '_editableBy'             => array('checkuser', 'toolRoot'),
248
-            '_childRoles'             => array(
249
-                'user',
250
-                'requestAdminTools',
251
-            ),
252
-            PageUserManagement::class => array(
253
-                self::MAIN  => self::ACCESS_ALLOW,
254
-                'suspend'   => self::ACCESS_ALLOW,
255
-                'editRoles' => self::ACCESS_ALLOW,
256
-            ),
257
-            'RequestData'             => array(
258
-                'seeUserAgentData' => self::ACCESS_ALLOW,
259
-            ),
260
-        ),
261
-        'toolRoot'          => array(
262
-            '_description' => 'A user with shell access to the servers running the tool',
263
-            '_editableBy'  => array('toolRoot'),
264
-            '_childRoles'  => array(
265
-                'admin',
266
-            ),
267
-            PageMultiFactor::class => array(
268
-                'enableU2F'         => self::ACCESS_ALLOW,
269
-                'disableU2F'        => self::ACCESS_ALLOW,
270
-            )
271
-        ),
272
-        'botCreation'       => array(
273
-            '_description'    => 'A user allowed to use the bot to perform account creations',
274
-            '_editableBy'     => array('admin', 'toolRoot'),
275
-            '_childRoles'     => array(),
276
-            'RequestCreation' => array(
277
-                User::CREATION_BOT => self::ACCESS_ALLOW,
278
-            ),
279
-        ),
280
-        'oauthCreation'       => array(
281
-            '_description'    => 'A user allowed to use the OAuth to perform account creations',
282
-            '_editableBy'     => array('admin', 'toolRoot'),
283
-            '_childRoles'     => array(),
284
-            'RequestCreation'                    => array(
285
-                User::CREATION_OAUTH  => self::ACCESS_ALLOW,
286
-            ),
287
-        ),
108
+			'_childRoles'             => array(
109
+				'public',
110
+			),
111
+			PagePreferences::class    => array(
112
+				self::MAIN => self::ACCESS_ALLOW,
113
+				'refreshOAuth' => self::ACCESS_ALLOW,
114
+			),
115
+			PageChangePassword::class => array(
116
+				self::MAIN => self::ACCESS_ALLOW,
117
+			),
118
+			PageMultiFactor::class    => array(
119
+				self::MAIN          => self::ACCESS_ALLOW,
120
+				'scratch'           => self::ACCESS_ALLOW,
121
+				'enableYubikeyOtp'  => self::ACCESS_ALLOW,
122
+				'disableYubikeyOtp' => self::ACCESS_ALLOW,
123
+				'enableTotp'        => self::ACCESS_ALLOW,
124
+				'disableTotp'       => self::ACCESS_ALLOW,
125
+			),
126
+			PageOAuth::class          => array(
127
+				'attach' => self::ACCESS_ALLOW,
128
+				'detach' => self::ACCESS_ALLOW,
129
+			),
130
+		),
131
+		'user'              => array(
132
+			'_description'                       => 'A standard tool user.',
133
+			'_editableBy'                        => array('admin', 'toolRoot'),
134
+			'_childRoles'                        => array(
135
+				'internalStats',
136
+			),
137
+			PageMain::class                      => array(
138
+				self::MAIN => self::ACCESS_ALLOW,
139
+			),
140
+			PageBan::class                       => array(
141
+				self::MAIN => self::ACCESS_ALLOW,
142
+			),
143
+			PageEditComment::class               => array(
144
+				self::MAIN => self::ACCESS_ALLOW,
145
+			),
146
+			PageEmailManagement::class           => array(
147
+				self::MAIN => self::ACCESS_ALLOW,
148
+				'view'     => self::ACCESS_ALLOW,
149
+			),
150
+			PageExpandedRequestList::class       => array(
151
+				self::MAIN => self::ACCESS_ALLOW,
152
+			),
153
+			PageLog::class                       => array(
154
+				self::MAIN => self::ACCESS_ALLOW,
155
+			),
156
+			PageSearch::class                    => array(
157
+				self::MAIN => self::ACCESS_ALLOW,
158
+			),
159
+			PageWelcomeTemplateManagement::class => array(
160
+				self::MAIN => self::ACCESS_ALLOW,
161
+				'select'   => self::ACCESS_ALLOW,
162
+				'view'     => self::ACCESS_ALLOW,
163
+			),
164
+			PageViewRequest::class               => array(
165
+				self::MAIN       => self::ACCESS_ALLOW,
166
+				'seeAllRequests' => self::ACCESS_ALLOW,
167
+			),
168
+			'RequestData'                        => array(
169
+				'seePrivateDataWhenReserved' => self::ACCESS_ALLOW,
170
+				'seePrivateDataWithHash'     => self::ACCESS_ALLOW,
171
+			),
172
+			PageCustomClose::class               => array(
173
+				self::MAIN => self::ACCESS_ALLOW,
174
+			),
175
+			PageComment::class                   => array(
176
+				self::MAIN => self::ACCESS_ALLOW,
177
+			),
178
+			PageCloseRequest::class              => array(
179
+				self::MAIN => self::ACCESS_ALLOW,
180
+			),
181
+			PageCreateRequest::class             => array(
182
+				self::MAIN => self::ACCESS_ALLOW,
183
+			),
184
+			PageDeferRequest::class              => array(
185
+				self::MAIN => self::ACCESS_ALLOW,
186
+			),
187
+			PageDropRequest::class               => array(
188
+				self::MAIN => self::ACCESS_ALLOW,
189
+			),
190
+			PageReservation::class               => array(
191
+				self::MAIN => self::ACCESS_ALLOW,
192
+			),
193
+			PageSendToUser::class                => array(
194
+				self::MAIN => self::ACCESS_ALLOW,
195
+			),
196
+			PageBreakReservation::class          => array(
197
+				self::MAIN => self::ACCESS_ALLOW,
198
+			),
199
+			PageJobQueue::class                  => array(
200
+				self::MAIN => self::ACCESS_ALLOW,
201
+				'view'     => self::ACCESS_ALLOW,
202
+				'all'      => self::ACCESS_ALLOW,
203
+			),
204
+			'RequestCreation'                    => array(
205
+				User::CREATION_MANUAL => self::ACCESS_ALLOW,
206
+			),
207
+			'GlobalInfo'                         => array(
208
+				'viewSiteNotice' => self::ACCESS_ALLOW,
209
+				'viewOnlineUsers' => self::ACCESS_ALLOW,
210
+			),
211
+		),
212
+		'admin'             => array(
213
+			'_description'                       => 'A tool administrator.',
214
+			'_editableBy'                        => array('admin', 'toolRoot'),
215
+			'_childRoles'                        => array(
216
+				'user',
217
+				'requestAdminTools',
218
+			),
219
+			PageEmailManagement::class           => array(
220
+				'edit'   => self::ACCESS_ALLOW,
221
+				'create' => self::ACCESS_ALLOW,
222
+			),
223
+			PageSiteNotice::class                => array(
224
+				self::MAIN => self::ACCESS_ALLOW,
225
+			),
226
+			PageUserManagement::class            => array(
227
+				self::MAIN  => self::ACCESS_ALLOW,
228
+				'approve'   => self::ACCESS_ALLOW,
229
+				'decline'   => self::ACCESS_ALLOW,
230
+				'rename'    => self::ACCESS_ALLOW,
231
+				'editUser'  => self::ACCESS_ALLOW,
232
+				'suspend'   => self::ACCESS_ALLOW,
233
+				'editRoles' => self::ACCESS_ALLOW,
234
+			),
235
+			PageWelcomeTemplateManagement::class => array(
236
+				'edit'   => self::ACCESS_ALLOW,
237
+				'delete' => self::ACCESS_ALLOW,
238
+				'add'    => self::ACCESS_ALLOW,
239
+			),
240
+			PageJobQueue::class                  => array(
241
+				'acknowledge' => self::ACCESS_ALLOW,
242
+				'requeue'     => self::ACCESS_ALLOW,
243
+			),
244
+		),
245
+		'checkuser'         => array(
246
+			'_description'            => 'A user with CheckUser access',
247
+			'_editableBy'             => array('checkuser', 'toolRoot'),
248
+			'_childRoles'             => array(
249
+				'user',
250
+				'requestAdminTools',
251
+			),
252
+			PageUserManagement::class => array(
253
+				self::MAIN  => self::ACCESS_ALLOW,
254
+				'suspend'   => self::ACCESS_ALLOW,
255
+				'editRoles' => self::ACCESS_ALLOW,
256
+			),
257
+			'RequestData'             => array(
258
+				'seeUserAgentData' => self::ACCESS_ALLOW,
259
+			),
260
+		),
261
+		'toolRoot'          => array(
262
+			'_description' => 'A user with shell access to the servers running the tool',
263
+			'_editableBy'  => array('toolRoot'),
264
+			'_childRoles'  => array(
265
+				'admin',
266
+			),
267
+			PageMultiFactor::class => array(
268
+				'enableU2F'         => self::ACCESS_ALLOW,
269
+				'disableU2F'        => self::ACCESS_ALLOW,
270
+			)
271
+		),
272
+		'botCreation'       => array(
273
+			'_description'    => 'A user allowed to use the bot to perform account creations',
274
+			'_editableBy'     => array('admin', 'toolRoot'),
275
+			'_childRoles'     => array(),
276
+			'RequestCreation' => array(
277
+				User::CREATION_BOT => self::ACCESS_ALLOW,
278
+			),
279
+		),
280
+		'oauthCreation'       => array(
281
+			'_description'    => 'A user allowed to use the OAuth to perform account creations',
282
+			'_editableBy'     => array('admin', 'toolRoot'),
283
+			'_childRoles'     => array(),
284
+			'RequestCreation'                    => array(
285
+				User::CREATION_OAUTH  => self::ACCESS_ALLOW,
286
+			),
287
+		),
288 288
 
289 289
 
290
-        // Child roles go below this point
291
-        'publicStats'       => array(
292
-            '_hidden'               => true,
293
-            StatsUsers::class       => array(
294
-                self::MAIN => self::ACCESS_ALLOW,
295
-                'detail'   => self::ACCESS_ALLOW,
296
-            ),
297
-            StatsTopCreators::class => array(
298
-                self::MAIN => self::ACCESS_ALLOW,
299
-            ),
300
-        ),
301
-        'internalStats'     => array(
302
-            '_hidden'                    => true,
303
-            StatsMain::class             => array(
304
-                self::MAIN => self::ACCESS_ALLOW,
305
-            ),
306
-            StatsFastCloses::class       => array(
307
-                self::MAIN => self::ACCESS_ALLOW,
308
-            ),
309
-            StatsInactiveUsers::class    => array(
310
-                self::MAIN => self::ACCESS_ALLOW,
311
-            ),
312
-            StatsMonthlyStats::class     => array(
313
-                self::MAIN => self::ACCESS_ALLOW,
314
-            ),
315
-            StatsReservedRequests::class => array(
316
-                self::MAIN => self::ACCESS_ALLOW,
317
-            ),
318
-            StatsTemplateStats::class    => array(
319
-                self::MAIN => self::ACCESS_ALLOW,
320
-            ),
321
-        ),
322
-        'requestAdminTools' => array(
323
-            '_hidden'                   => true,
324
-            PageBan::class              => array(
325
-                self::MAIN => self::ACCESS_ALLOW,
326
-                'set'      => self::ACCESS_ALLOW,
327
-                'remove'   => self::ACCESS_ALLOW,
328
-            ),
329
-            PageEditComment::class      => array(
330
-                'editOthers' => self::ACCESS_ALLOW,
331
-            ),
332
-            PageBreakReservation::class => array(
333
-                'force' => self::ACCESS_ALLOW,
334
-            ),
335
-            PageCustomClose::class      => array(
336
-                'skipCcMailingList' => self::ACCESS_ALLOW,
337
-            ),
338
-            'RequestData'               => array(
339
-                'reopenOldRequest'      => self::ACCESS_ALLOW,
340
-                'alwaysSeePrivateData'  => self::ACCESS_ALLOW,
341
-                'alwaysSeeHash'         => self::ACCESS_ALLOW,
342
-                'seeRestrictedComments' => self::ACCESS_ALLOW,
343
-            ),
344
-        ),
345
-    );
346
-    /** @var array
347
-     * List of roles which are *exempt* from the identification requirements
348
-     *
349
-     * Think twice about adding roles to this list.
350
-     *
351
-     * @category Security-Critical
352
-     */
353
-    private $identificationExempt = array('public', 'loggedIn');
290
+		// Child roles go below this point
291
+		'publicStats'       => array(
292
+			'_hidden'               => true,
293
+			StatsUsers::class       => array(
294
+				self::MAIN => self::ACCESS_ALLOW,
295
+				'detail'   => self::ACCESS_ALLOW,
296
+			),
297
+			StatsTopCreators::class => array(
298
+				self::MAIN => self::ACCESS_ALLOW,
299
+			),
300
+		),
301
+		'internalStats'     => array(
302
+			'_hidden'                    => true,
303
+			StatsMain::class             => array(
304
+				self::MAIN => self::ACCESS_ALLOW,
305
+			),
306
+			StatsFastCloses::class       => array(
307
+				self::MAIN => self::ACCESS_ALLOW,
308
+			),
309
+			StatsInactiveUsers::class    => array(
310
+				self::MAIN => self::ACCESS_ALLOW,
311
+			),
312
+			StatsMonthlyStats::class     => array(
313
+				self::MAIN => self::ACCESS_ALLOW,
314
+			),
315
+			StatsReservedRequests::class => array(
316
+				self::MAIN => self::ACCESS_ALLOW,
317
+			),
318
+			StatsTemplateStats::class    => array(
319
+				self::MAIN => self::ACCESS_ALLOW,
320
+			),
321
+		),
322
+		'requestAdminTools' => array(
323
+			'_hidden'                   => true,
324
+			PageBan::class              => array(
325
+				self::MAIN => self::ACCESS_ALLOW,
326
+				'set'      => self::ACCESS_ALLOW,
327
+				'remove'   => self::ACCESS_ALLOW,
328
+			),
329
+			PageEditComment::class      => array(
330
+				'editOthers' => self::ACCESS_ALLOW,
331
+			),
332
+			PageBreakReservation::class => array(
333
+				'force' => self::ACCESS_ALLOW,
334
+			),
335
+			PageCustomClose::class      => array(
336
+				'skipCcMailingList' => self::ACCESS_ALLOW,
337
+			),
338
+			'RequestData'               => array(
339
+				'reopenOldRequest'      => self::ACCESS_ALLOW,
340
+				'alwaysSeePrivateData'  => self::ACCESS_ALLOW,
341
+				'alwaysSeeHash'         => self::ACCESS_ALLOW,
342
+				'seeRestrictedComments' => self::ACCESS_ALLOW,
343
+			),
344
+		),
345
+	);
346
+	/** @var array
347
+	 * List of roles which are *exempt* from the identification requirements
348
+	 *
349
+	 * Think twice about adding roles to this list.
350
+	 *
351
+	 * @category Security-Critical
352
+	 */
353
+	private $identificationExempt = array('public', 'loggedIn');
354 354
 
355
-    /**
356
-     * RoleConfiguration constructor.
357
-     *
358
-     * @param array $roleConfig           Set to non-null to override the default configuration.
359
-     * @param array $identificationExempt Set to non-null to override the default configuration.
360
-     */
361
-    public function __construct(array $roleConfig = null, array $identificationExempt = null)
362
-    {
363
-        if ($roleConfig !== null) {
364
-            $this->roleConfig = $roleConfig;
365
-        }
355
+	/**
356
+	 * RoleConfiguration constructor.
357
+	 *
358
+	 * @param array $roleConfig           Set to non-null to override the default configuration.
359
+	 * @param array $identificationExempt Set to non-null to override the default configuration.
360
+	 */
361
+	public function __construct(array $roleConfig = null, array $identificationExempt = null)
362
+	{
363
+		if ($roleConfig !== null) {
364
+			$this->roleConfig = $roleConfig;
365
+		}
366 366
 
367
-        if ($identificationExempt !== null) {
368
-            $this->identificationExempt = $identificationExempt;
369
-        }
370
-    }
367
+		if ($identificationExempt !== null) {
368
+			$this->identificationExempt = $identificationExempt;
369
+		}
370
+	}
371 371
 
372
-    /**
373
-     * @param array $roles The roles to check
374
-     *
375
-     * @return array
376
-     */
377
-    public function getApplicableRoles(array $roles)
378
-    {
379
-        $available = array();
372
+	/**
373
+	 * @param array $roles The roles to check
374
+	 *
375
+	 * @return array
376
+	 */
377
+	public function getApplicableRoles(array $roles)
378
+	{
379
+		$available = array();
380 380
 
381
-        foreach ($roles as $role) {
382
-            if (!isset($this->roleConfig[$role])) {
383
-                // wat
384
-                continue;
385
-            }
381
+		foreach ($roles as $role) {
382
+			if (!isset($this->roleConfig[$role])) {
383
+				// wat
384
+				continue;
385
+			}
386 386
 
387
-            $available[$role] = $this->roleConfig[$role];
387
+			$available[$role] = $this->roleConfig[$role];
388 388
 
389
-            if (isset($available[$role]['_childRoles'])) {
390
-                $childRoles = self::getApplicableRoles($available[$role]['_childRoles']);
391
-                $available = array_merge($available, $childRoles);
389
+			if (isset($available[$role]['_childRoles'])) {
390
+				$childRoles = self::getApplicableRoles($available[$role]['_childRoles']);
391
+				$available = array_merge($available, $childRoles);
392 392
 
393
-                unset($available[$role]['_childRoles']);
394
-            }
393
+				unset($available[$role]['_childRoles']);
394
+			}
395 395
 
396
-            foreach (array('_hidden', '_editableBy', '_description') as $item) {
397
-                if (isset($available[$role][$item])) {
398
-                    unset($available[$role][$item]);
399
-                }
400
-            }
401
-        }
396
+			foreach (array('_hidden', '_editableBy', '_description') as $item) {
397
+				if (isset($available[$role][$item])) {
398
+					unset($available[$role][$item]);
399
+				}
400
+			}
401
+		}
402 402
 
403
-        return $available;
404
-    }
403
+		return $available;
404
+	}
405 405
 
406
-    public function getAvailableRoles()
407
-    {
408
-        $possible = array_diff(array_keys($this->roleConfig), array('public', 'loggedIn'));
406
+	public function getAvailableRoles()
407
+	{
408
+		$possible = array_diff(array_keys($this->roleConfig), array('public', 'loggedIn'));
409 409
 
410
-        $actual = array();
410
+		$actual = array();
411 411
 
412
-        foreach ($possible as $role) {
413
-            if (!isset($this->roleConfig[$role]['_hidden'])) {
414
-                $actual[$role] = array(
415
-                    'description' => $this->roleConfig[$role]['_description'],
416
-                    'editableBy'  => $this->roleConfig[$role]['_editableBy'],
417
-                );
418
-            }
419
-        }
412
+		foreach ($possible as $role) {
413
+			if (!isset($this->roleConfig[$role]['_hidden'])) {
414
+				$actual[$role] = array(
415
+					'description' => $this->roleConfig[$role]['_description'],
416
+					'editableBy'  => $this->roleConfig[$role]['_editableBy'],
417
+				);
418
+			}
419
+		}
420 420
 
421
-        return $actual;
422
-    }
421
+		return $actual;
422
+	}
423 423
 
424
-    /**
425
-     * @param string $role
426
-     *
427
-     * @return bool
428
-     */
429
-    public function roleNeedsIdentification($role)
430
-    {
431
-        if (in_array($role, $this->identificationExempt)) {
432
-            return false;
433
-        }
424
+	/**
425
+	 * @param string $role
426
+	 *
427
+	 * @return bool
428
+	 */
429
+	public function roleNeedsIdentification($role)
430
+	{
431
+		if (in_array($role, $this->identificationExempt)) {
432
+			return false;
433
+		}
434 434
 
435
-        return true;
436
-    }
435
+		return true;
436
+	}
437 437
 }
Please login to merge, or discard this patch.
includes/Fragments/RequestData.php 1 patch
Indentation   +312 added lines, -312 removed lines patch added patch discarded remove patch
@@ -24,316 +24,316 @@
 block discarded – undo
24 24
 
25 25
 trait RequestData
26 26
 {
27
-    /**
28
-     * @var array Array of IP address classed as 'private' by RFC1918.
29
-     */
30
-    protected static $rfc1918ips = array(
31
-        "10.0.0.0"    => "10.255.255.255",
32
-        "172.16.0.0"  => "172.31.255.255",
33
-        "192.168.0.0" => "192.168.255.255",
34
-        "169.254.0.0" => "169.254.255.255",
35
-        "127.0.0.0"   => "127.255.255.255",
36
-    );
37
-
38
-    /**
39
-     * Gets a request object
40
-     *
41
-     * @param PdoDatabase $database  The database connection
42
-     * @param int         $requestId The ID of the request to retrieve
43
-     *
44
-     * @return Request
45
-     * @throws ApplicationLogicException
46
-     */
47
-    protected function getRequest(PdoDatabase $database, $requestId)
48
-    {
49
-        if ($requestId === null) {
50
-            throw new ApplicationLogicException("No request specified");
51
-        }
52
-
53
-        $request = Request::getById($requestId, $database);
54
-        if ($request === false || !is_a($request, Request::class)) {
55
-            throw new ApplicationLogicException('Could not load the requested request!');
56
-        }
57
-
58
-        return $request;
59
-    }
60
-
61
-    /**
62
-     * Returns a value stating whether the user is allowed to see private data or not
63
-     *
64
-     * @param Request $request
65
-     * @param User    $currentUser
66
-     *
67
-     * @return bool
68
-     * @category Security-Critical
69
-     */
70
-    protected function isAllowedPrivateData(Request $request, User $currentUser)
71
-    {
72
-        // Test the main security barrier for private data access using SecurityManager
73
-        if ($this->barrierTest('alwaysSeePrivateData', $currentUser, 'RequestData')) {
74
-            // Tool admins/check-users can always see private data
75
-            return true;
76
-        }
77
-
78
-        // reserving user is allowed to see the data
79
-        if ($currentUser->getId() === $request->getReserved()
80
-            && $request->getReserved() !== null
81
-            && $this->barrierTest('seePrivateDataWhenReserved', $currentUser, 'RequestData')
82
-        ) {
83
-            return true;
84
-        }
85
-
86
-        // user has the reveal hash
87
-        if (WebRequest::getString('hash') === $request->getRevealHash()
88
-            && $this->barrierTest('seePrivateDataWithHash', $currentUser, 'RequestData')
89
-        ) {
90
-            return true;
91
-        }
92
-
93
-        // nope. Not allowed.
94
-        return false;
95
-    }
96
-
97
-    /**
98
-     * Tests the security barrier for a specified action.
99
-     *
100
-     * Don't use within templates
101
-     *
102
-     * @param string      $action
103
-     *
104
-     * @param User        $user
105
-     * @param null|string $pageName
106
-     *
107
-     * @return bool
108
-     * @category Security-Critical
109
-     */
110
-    abstract protected function barrierTest($action, User $user, $pageName = null);
111
-
112
-    /**
113
-     * Gets the name of the route that has been passed from the request router.
114
-     * @return string
115
-     */
116
-    abstract protected function getRouteName();
117
-
118
-    /** @return SecurityManager */
119
-    abstract protected function getSecurityManager();
120
-
121
-    /**
122
-     * Sets the name of the template this page should display.
123
-     *
124
-     * @param string $name
125
-     */
126
-    abstract protected function setTemplate($name);
127
-
128
-    /** @return IXffTrustProvider */
129
-    abstract protected function getXffTrustProvider();
130
-
131
-    /** @return ILocationProvider */
132
-    abstract protected function getLocationProvider();
133
-
134
-    /** @return IRDnsProvider */
135
-    abstract protected function getRdnsProvider();
136
-
137
-    /**
138
-     * Assigns a Smarty variable
139
-     *
140
-     * @param  array|string $name  the template variable name(s)
141
-     * @param  mixed        $value the value to assign
142
-     */
143
-    abstract protected function assign($name, $value);
144
-
145
-    /**
146
-     * @param int         $requestReservationId
147
-     * @param PdoDatabase $database
148
-     * @param User        $currentUser
149
-     */
150
-    protected function setupReservationDetails($requestReservationId, PdoDatabase $database, User $currentUser)
151
-    {
152
-        $requestIsReserved = $requestReservationId !== null;
153
-        $this->assign('requestIsReserved', $requestIsReserved);
154
-        $this->assign('requestIsReservedByMe', false);
155
-
156
-        if ($requestIsReserved) {
157
-            $this->assign('requestReservedByName', User::getById($requestReservationId, $database)->getUsername());
158
-            $this->assign('requestReservedById', $requestReservationId);
159
-
160
-            if ($requestReservationId === $currentUser->getId()) {
161
-                $this->assign('requestIsReservedByMe', true);
162
-            }
163
-        }
164
-
165
-        $this->assign('canBreakReservation', $this->barrierTest('force', $currentUser, PageBreakReservation::class));
166
-    }
167
-
168
-    /**
169
-     * Adds private request data to Smarty. DO NOT USE WITHOUT FIRST CHECKING THAT THE USER IS AUTHORISED!
170
-     *
171
-     * @param Request           $request
172
-     * @param User              $currentUser
173
-     * @param SiteConfiguration $configuration
174
-     *
175
-     * @param PdoDatabase       $database
176
-     */
177
-    protected function setupPrivateData(
178
-        $request,
179
-        User $currentUser,
180
-        SiteConfiguration $configuration,
181
-        PdoDatabase $database
182
-    ) {
183
-        $xffProvider = $this->getXffTrustProvider();
184
-
185
-        $relatedEmailRequests = RequestSearchHelper::get($database)
186
-            ->byEmailAddress($request->getEmail())
187
-            ->withConfirmedEmail()
188
-            ->excludingPurgedData($configuration)
189
-            ->excludingRequest($request->getId())
190
-            ->fetch();
191
-
192
-        $this->assign('requestEmail', $request->getEmail());
193
-        $emailDomain = explode("@", $request->getEmail())[1];
194
-        $this->assign("emailurl", $emailDomain);
195
-        $this->assign('requestRelatedEmailRequestsCount', count($relatedEmailRequests));
196
-        $this->assign('requestRelatedEmailRequests', $relatedEmailRequests);
197
-
198
-        $trustedIp = $xffProvider->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
199
-        $this->assign('requestTrustedIp', $trustedIp);
200
-        $this->assign('requestRealIp', $request->getIp());
201
-        $this->assign('requestForwardedIp', $request->getForwardedIp());
202
-
203
-        $trustedIpLocation = $this->getLocationProvider()->getIpLocation($trustedIp);
204
-        $this->assign('requestTrustedIpLocation', $trustedIpLocation);
205
-
206
-        $this->assign('requestHasForwardedIp', $request->getForwardedIp() !== null);
207
-
208
-        $relatedIpRequests = RequestSearchHelper::get($database)
209
-            ->byIp($trustedIp)
210
-            ->withConfirmedEmail()
211
-            ->excludingPurgedData($configuration)
212
-            ->excludingRequest($request->getId())
213
-            ->fetch();
214
-
215
-        $this->assign('requestRelatedIpRequestsCount', count($relatedIpRequests));
216
-        $this->assign('requestRelatedIpRequests', $relatedIpRequests);
217
-
218
-        $this->setupForwardedIpData($request);
219
-    }
220
-
221
-    /**
222
-     * Adds checkuser request data to Smarty. DO NOT USE WITHOUT FIRST CHECKING THAT THE USER IS AUTHORISED!
223
-     *
224
-     * @param Request $request
225
-     */
226
-    protected function setupCheckUserData(Request $request)
227
-    {
228
-        $this->assign('requestUserAgent', $request->getUserAgent());
229
-    }
230
-
231
-    /**
232
-     * Sets up the basic data for this request, and adds it to Smarty
233
-     *
234
-     * @param Request           $request
235
-     * @param SiteConfiguration $config
236
-     */
237
-    protected function setupBasicData(Request $request, SiteConfiguration $config)
238
-    {
239
-        $this->assign('requestId', $request->getId());
240
-        $this->assign('updateVersion', $request->getUpdateVersion());
241
-        $this->assign('requestName', $request->getName());
242
-        $this->assign('requestDate', $request->getDate());
243
-        $this->assign('requestStatus', $request->getStatus());
244
-
245
-        $isClosed = !array_key_exists($request->getStatus(), $config->getRequestStates())
246
-            && $request->getStatus() !== RequestStatus::HOSPITAL;
247
-        $this->assign('requestIsClosed', $isClosed);
248
-    }
249
-
250
-    /**
251
-     * Sets up the forwarded IP data for this request and adds it to Smarty
252
-     *
253
-     * @param Request $request
254
-     */
255
-    protected function setupForwardedIpData(Request $request)
256
-    {
257
-        if ($request->getForwardedIp() !== null) {
258
-            $requestProxyData = array(); // Initialize array to store data to be output in Smarty template.
259
-            $proxyIndex = 0;
260
-
261
-            // Assuming [client] <=> [proxy1] <=> [proxy2] <=> [proxy3] <=> [us], we will see an XFF header of [client],
262
-            // [proxy1], [proxy2], and our actual IP will be [proxy3]
263
-            $proxies = explode(",", $request->getForwardedIp());
264
-            $proxies[] = $request->getIp();
265
-
266
-            // Origin is the supposed "client" IP.
267
-            $origin = $proxies[0];
268
-            $this->assign("forwardedOrigin", $origin);
269
-
270
-            // We step through the servers in reverse order, from closest to furthest
271
-            $proxies = array_reverse($proxies);
272
-
273
-            // By default, we have trust, because the first in the chain is now REMOTE_ADDR, which is hardest to spoof.
274
-            $trust = true;
275
-
276
-            /**
277
-             * @var int    $index     The zero-based index of the proxy.
278
-             * @var string $proxyData The proxy IP address (although possibly not!)
279
-             */
280
-            foreach ($proxies as $index => $proxyData) {
281
-                $proxyAddress = trim($proxyData);
282
-                $requestProxyData[$proxyIndex]['ip'] = $proxyAddress;
283
-
284
-                // get data on this IP.
285
-                $thisProxyIsTrusted = $this->getXffTrustProvider()->isTrusted($proxyAddress);
286
-
287
-                $proxyIsInPrivateRange = $this->getXffTrustProvider()
288
-                    ->ipInRange(self::$rfc1918ips, $proxyAddress);
289
-
290
-                if (!$proxyIsInPrivateRange) {
291
-                    $proxyReverseDns = $this->getRdnsProvider()->getReverseDNS($proxyAddress);
292
-                    $proxyLocation = $this->getLocationProvider()->getIpLocation($proxyAddress);
293
-                }
294
-                else {
295
-                    // this is going to fail, so why bother trying?
296
-                    $proxyReverseDns = false;
297
-                    $proxyLocation = false;
298
-                }
299
-
300
-                // current trust chain status BEFORE this link
301
-                $preLinkTrust = $trust;
302
-
303
-                // is *this* link trusted? Note, this will be true even if there is an untrusted link before this!
304
-                $requestProxyData[$proxyIndex]['trustedlink'] = $thisProxyIsTrusted;
305
-
306
-                // set the trust status of the chain to this point
307
-                $trust = $trust & $thisProxyIsTrusted;
308
-
309
-                // If this is the origin address, and the chain was trusted before this point, then we can trust
310
-                // the origin.
311
-                if ($preLinkTrust && $proxyAddress == $origin) {
312
-                    // if this is the origin, then we are at the last point in the chain.
313
-                    // @todo: this is probably the cause of some bugs when an IP appears twice - we're missing a check
314
-                    // to see if this is *really* the last in the chain, rather than just the same IP as it.
315
-                    $trust = true;
316
-                }
317
-
318
-                $requestProxyData[$proxyIndex]['trust'] = $trust;
319
-
320
-                $requestProxyData[$proxyIndex]['rdnsfailed'] = $proxyReverseDns === false;
321
-                $requestProxyData[$proxyIndex]['rdns'] = $proxyReverseDns;
322
-                $requestProxyData[$proxyIndex]['routable'] = !$proxyIsInPrivateRange;
323
-
324
-                $requestProxyData[$proxyIndex]['location'] = $proxyLocation;
325
-
326
-                if ($proxyReverseDns === $proxyAddress && $proxyIsInPrivateRange === false) {
327
-                    $requestProxyData[$proxyIndex]['rdns'] = null;
328
-                }
329
-
330
-                $showLinks = (!$trust || $proxyAddress == $origin) && !$proxyIsInPrivateRange;
331
-                $requestProxyData[$proxyIndex]['showlinks'] = $showLinks;
332
-
333
-                $proxyIndex++;
334
-            }
335
-
336
-            $this->assign("requestProxyData", $requestProxyData);
337
-        }
338
-    }
27
+	/**
28
+	 * @var array Array of IP address classed as 'private' by RFC1918.
29
+	 */
30
+	protected static $rfc1918ips = array(
31
+		"10.0.0.0"    => "10.255.255.255",
32
+		"172.16.0.0"  => "172.31.255.255",
33
+		"192.168.0.0" => "192.168.255.255",
34
+		"169.254.0.0" => "169.254.255.255",
35
+		"127.0.0.0"   => "127.255.255.255",
36
+	);
37
+
38
+	/**
39
+	 * Gets a request object
40
+	 *
41
+	 * @param PdoDatabase $database  The database connection
42
+	 * @param int         $requestId The ID of the request to retrieve
43
+	 *
44
+	 * @return Request
45
+	 * @throws ApplicationLogicException
46
+	 */
47
+	protected function getRequest(PdoDatabase $database, $requestId)
48
+	{
49
+		if ($requestId === null) {
50
+			throw new ApplicationLogicException("No request specified");
51
+		}
52
+
53
+		$request = Request::getById($requestId, $database);
54
+		if ($request === false || !is_a($request, Request::class)) {
55
+			throw new ApplicationLogicException('Could not load the requested request!');
56
+		}
57
+
58
+		return $request;
59
+	}
60
+
61
+	/**
62
+	 * Returns a value stating whether the user is allowed to see private data or not
63
+	 *
64
+	 * @param Request $request
65
+	 * @param User    $currentUser
66
+	 *
67
+	 * @return bool
68
+	 * @category Security-Critical
69
+	 */
70
+	protected function isAllowedPrivateData(Request $request, User $currentUser)
71
+	{
72
+		// Test the main security barrier for private data access using SecurityManager
73
+		if ($this->barrierTest('alwaysSeePrivateData', $currentUser, 'RequestData')) {
74
+			// Tool admins/check-users can always see private data
75
+			return true;
76
+		}
77
+
78
+		// reserving user is allowed to see the data
79
+		if ($currentUser->getId() === $request->getReserved()
80
+			&& $request->getReserved() !== null
81
+			&& $this->barrierTest('seePrivateDataWhenReserved', $currentUser, 'RequestData')
82
+		) {
83
+			return true;
84
+		}
85
+
86
+		// user has the reveal hash
87
+		if (WebRequest::getString('hash') === $request->getRevealHash()
88
+			&& $this->barrierTest('seePrivateDataWithHash', $currentUser, 'RequestData')
89
+		) {
90
+			return true;
91
+		}
92
+
93
+		// nope. Not allowed.
94
+		return false;
95
+	}
96
+
97
+	/**
98
+	 * Tests the security barrier for a specified action.
99
+	 *
100
+	 * Don't use within templates
101
+	 *
102
+	 * @param string      $action
103
+	 *
104
+	 * @param User        $user
105
+	 * @param null|string $pageName
106
+	 *
107
+	 * @return bool
108
+	 * @category Security-Critical
109
+	 */
110
+	abstract protected function barrierTest($action, User $user, $pageName = null);
111
+
112
+	/**
113
+	 * Gets the name of the route that has been passed from the request router.
114
+	 * @return string
115
+	 */
116
+	abstract protected function getRouteName();
117
+
118
+	/** @return SecurityManager */
119
+	abstract protected function getSecurityManager();
120
+
121
+	/**
122
+	 * Sets the name of the template this page should display.
123
+	 *
124
+	 * @param string $name
125
+	 */
126
+	abstract protected function setTemplate($name);
127
+
128
+	/** @return IXffTrustProvider */
129
+	abstract protected function getXffTrustProvider();
130
+
131
+	/** @return ILocationProvider */
132
+	abstract protected function getLocationProvider();
133
+
134
+	/** @return IRDnsProvider */
135
+	abstract protected function getRdnsProvider();
136
+
137
+	/**
138
+	 * Assigns a Smarty variable
139
+	 *
140
+	 * @param  array|string $name  the template variable name(s)
141
+	 * @param  mixed        $value the value to assign
142
+	 */
143
+	abstract protected function assign($name, $value);
144
+
145
+	/**
146
+	 * @param int         $requestReservationId
147
+	 * @param PdoDatabase $database
148
+	 * @param User        $currentUser
149
+	 */
150
+	protected function setupReservationDetails($requestReservationId, PdoDatabase $database, User $currentUser)
151
+	{
152
+		$requestIsReserved = $requestReservationId !== null;
153
+		$this->assign('requestIsReserved', $requestIsReserved);
154
+		$this->assign('requestIsReservedByMe', false);
155
+
156
+		if ($requestIsReserved) {
157
+			$this->assign('requestReservedByName', User::getById($requestReservationId, $database)->getUsername());
158
+			$this->assign('requestReservedById', $requestReservationId);
159
+
160
+			if ($requestReservationId === $currentUser->getId()) {
161
+				$this->assign('requestIsReservedByMe', true);
162
+			}
163
+		}
164
+
165
+		$this->assign('canBreakReservation', $this->barrierTest('force', $currentUser, PageBreakReservation::class));
166
+	}
167
+
168
+	/**
169
+	 * Adds private request data to Smarty. DO NOT USE WITHOUT FIRST CHECKING THAT THE USER IS AUTHORISED!
170
+	 *
171
+	 * @param Request           $request
172
+	 * @param User              $currentUser
173
+	 * @param SiteConfiguration $configuration
174
+	 *
175
+	 * @param PdoDatabase       $database
176
+	 */
177
+	protected function setupPrivateData(
178
+		$request,
179
+		User $currentUser,
180
+		SiteConfiguration $configuration,
181
+		PdoDatabase $database
182
+	) {
183
+		$xffProvider = $this->getXffTrustProvider();
184
+
185
+		$relatedEmailRequests = RequestSearchHelper::get($database)
186
+			->byEmailAddress($request->getEmail())
187
+			->withConfirmedEmail()
188
+			->excludingPurgedData($configuration)
189
+			->excludingRequest($request->getId())
190
+			->fetch();
191
+
192
+		$this->assign('requestEmail', $request->getEmail());
193
+		$emailDomain = explode("@", $request->getEmail())[1];
194
+		$this->assign("emailurl", $emailDomain);
195
+		$this->assign('requestRelatedEmailRequestsCount', count($relatedEmailRequests));
196
+		$this->assign('requestRelatedEmailRequests', $relatedEmailRequests);
197
+
198
+		$trustedIp = $xffProvider->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
199
+		$this->assign('requestTrustedIp', $trustedIp);
200
+		$this->assign('requestRealIp', $request->getIp());
201
+		$this->assign('requestForwardedIp', $request->getForwardedIp());
202
+
203
+		$trustedIpLocation = $this->getLocationProvider()->getIpLocation($trustedIp);
204
+		$this->assign('requestTrustedIpLocation', $trustedIpLocation);
205
+
206
+		$this->assign('requestHasForwardedIp', $request->getForwardedIp() !== null);
207
+
208
+		$relatedIpRequests = RequestSearchHelper::get($database)
209
+			->byIp($trustedIp)
210
+			->withConfirmedEmail()
211
+			->excludingPurgedData($configuration)
212
+			->excludingRequest($request->getId())
213
+			->fetch();
214
+
215
+		$this->assign('requestRelatedIpRequestsCount', count($relatedIpRequests));
216
+		$this->assign('requestRelatedIpRequests', $relatedIpRequests);
217
+
218
+		$this->setupForwardedIpData($request);
219
+	}
220
+
221
+	/**
222
+	 * Adds checkuser request data to Smarty. DO NOT USE WITHOUT FIRST CHECKING THAT THE USER IS AUTHORISED!
223
+	 *
224
+	 * @param Request $request
225
+	 */
226
+	protected function setupCheckUserData(Request $request)
227
+	{
228
+		$this->assign('requestUserAgent', $request->getUserAgent());
229
+	}
230
+
231
+	/**
232
+	 * Sets up the basic data for this request, and adds it to Smarty
233
+	 *
234
+	 * @param Request           $request
235
+	 * @param SiteConfiguration $config
236
+	 */
237
+	protected function setupBasicData(Request $request, SiteConfiguration $config)
238
+	{
239
+		$this->assign('requestId', $request->getId());
240
+		$this->assign('updateVersion', $request->getUpdateVersion());
241
+		$this->assign('requestName', $request->getName());
242
+		$this->assign('requestDate', $request->getDate());
243
+		$this->assign('requestStatus', $request->getStatus());
244
+
245
+		$isClosed = !array_key_exists($request->getStatus(), $config->getRequestStates())
246
+			&& $request->getStatus() !== RequestStatus::HOSPITAL;
247
+		$this->assign('requestIsClosed', $isClosed);
248
+	}
249
+
250
+	/**
251
+	 * Sets up the forwarded IP data for this request and adds it to Smarty
252
+	 *
253
+	 * @param Request $request
254
+	 */
255
+	protected function setupForwardedIpData(Request $request)
256
+	{
257
+		if ($request->getForwardedIp() !== null) {
258
+			$requestProxyData = array(); // Initialize array to store data to be output in Smarty template.
259
+			$proxyIndex = 0;
260
+
261
+			// Assuming [client] <=> [proxy1] <=> [proxy2] <=> [proxy3] <=> [us], we will see an XFF header of [client],
262
+			// [proxy1], [proxy2], and our actual IP will be [proxy3]
263
+			$proxies = explode(",", $request->getForwardedIp());
264
+			$proxies[] = $request->getIp();
265
+
266
+			// Origin is the supposed "client" IP.
267
+			$origin = $proxies[0];
268
+			$this->assign("forwardedOrigin", $origin);
269
+
270
+			// We step through the servers in reverse order, from closest to furthest
271
+			$proxies = array_reverse($proxies);
272
+
273
+			// By default, we have trust, because the first in the chain is now REMOTE_ADDR, which is hardest to spoof.
274
+			$trust = true;
275
+
276
+			/**
277
+			 * @var int    $index     The zero-based index of the proxy.
278
+			 * @var string $proxyData The proxy IP address (although possibly not!)
279
+			 */
280
+			foreach ($proxies as $index => $proxyData) {
281
+				$proxyAddress = trim($proxyData);
282
+				$requestProxyData[$proxyIndex]['ip'] = $proxyAddress;
283
+
284
+				// get data on this IP.
285
+				$thisProxyIsTrusted = $this->getXffTrustProvider()->isTrusted($proxyAddress);
286
+
287
+				$proxyIsInPrivateRange = $this->getXffTrustProvider()
288
+					->ipInRange(self::$rfc1918ips, $proxyAddress);
289
+
290
+				if (!$proxyIsInPrivateRange) {
291
+					$proxyReverseDns = $this->getRdnsProvider()->getReverseDNS($proxyAddress);
292
+					$proxyLocation = $this->getLocationProvider()->getIpLocation($proxyAddress);
293
+				}
294
+				else {
295
+					// this is going to fail, so why bother trying?
296
+					$proxyReverseDns = false;
297
+					$proxyLocation = false;
298
+				}
299
+
300
+				// current trust chain status BEFORE this link
301
+				$preLinkTrust = $trust;
302
+
303
+				// is *this* link trusted? Note, this will be true even if there is an untrusted link before this!
304
+				$requestProxyData[$proxyIndex]['trustedlink'] = $thisProxyIsTrusted;
305
+
306
+				// set the trust status of the chain to this point
307
+				$trust = $trust & $thisProxyIsTrusted;
308
+
309
+				// If this is the origin address, and the chain was trusted before this point, then we can trust
310
+				// the origin.
311
+				if ($preLinkTrust && $proxyAddress == $origin) {
312
+					// if this is the origin, then we are at the last point in the chain.
313
+					// @todo: this is probably the cause of some bugs when an IP appears twice - we're missing a check
314
+					// to see if this is *really* the last in the chain, rather than just the same IP as it.
315
+					$trust = true;
316
+				}
317
+
318
+				$requestProxyData[$proxyIndex]['trust'] = $trust;
319
+
320
+				$requestProxyData[$proxyIndex]['rdnsfailed'] = $proxyReverseDns === false;
321
+				$requestProxyData[$proxyIndex]['rdns'] = $proxyReverseDns;
322
+				$requestProxyData[$proxyIndex]['routable'] = !$proxyIsInPrivateRange;
323
+
324
+				$requestProxyData[$proxyIndex]['location'] = $proxyLocation;
325
+
326
+				if ($proxyReverseDns === $proxyAddress && $proxyIsInPrivateRange === false) {
327
+					$requestProxyData[$proxyIndex]['rdns'] = null;
328
+				}
329
+
330
+				$showLinks = (!$trust || $proxyAddress == $origin) && !$proxyIsInPrivateRange;
331
+				$requestProxyData[$proxyIndex]['showlinks'] = $showLinks;
332
+
333
+				$proxyIndex++;
334
+			}
335
+
336
+			$this->assign("requestProxyData", $requestProxyData);
337
+		}
338
+	}
339 339
 }
Please login to merge, or discard this patch.
includes/Pages/PageExpandedRequestList.php 1 patch
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -19,120 +19,120 @@
 block discarded – undo
19 19
 
20 20
 class PageExpandedRequestList extends InternalPageBase
21 21
 {
22
-    /**
23
-     * Main function for this page, when no specific actions are called.
24
-     * @return void
25
-     * @todo This is very similar to the PageMain code, we could probably generalise this somehow
26
-     */
27
-    protected function main()
28
-    {
29
-        $config = $this->getSiteConfiguration();
30
-
31
-        $requestedStatus = WebRequest::getString('status');
32
-        $requestStates = $config->getRequestStates();
33
-
34
-        if ($requestedStatus !== null && isset($requestStates[$requestedStatus])) {
22
+	/**
23
+	 * Main function for this page, when no specific actions are called.
24
+	 * @return void
25
+	 * @todo This is very similar to the PageMain code, we could probably generalise this somehow
26
+	 */
27
+	protected function main()
28
+	{
29
+		$config = $this->getSiteConfiguration();
30
+
31
+		$requestedStatus = WebRequest::getString('status');
32
+		$requestStates = $config->getRequestStates();
33
+
34
+		if ($requestedStatus !== null && isset($requestStates[$requestedStatus])) {
35 35
 
36
-            $this->assignCSRFToken();
37
-
38
-            $database = $this->getDatabase();
39
-
40
-            $help = $requestStates[$requestedStatus]['queuehelp'];
41
-            $this->assign('queuehelp', $help);
42
-
43
-            if ($config->getEmailConfirmationEnabled()) {
44
-                $query = "SELECT * FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
45
-                $totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
46
-            }
47
-            else {
48
-                $query = "SELECT * FROM request WHERE status = :type;";
49
-                $totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type;";
50
-            }
51
-
52
-            $statement = $database->prepare($query);
53
-
54
-            $totalRequestsStatement = $database->prepare($totalQuery);
55
-
56
-            $this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
57
-
58
-            $type = $requestedStatus;
59
-
60
-            $statement->bindValue(":type", $type);
61
-            $statement->execute();
62
-
63
-            $requests = $statement->fetchAll(PDO::FETCH_CLASS, Request::class);
64
-
65
-            /** @var Request $req */
66
-            foreach ($requests as $req) {
67
-                $req->setDatabase($database);
68
-            }
69
-
70
-            $this->assign('requests', $requests);
71
-            $this->assign('header', $type);
72
-
73
-            $totalRequestsStatement->bindValue(':type', $type);
74
-            $totalRequestsStatement->execute();
75
-            $totalRequests = $totalRequestsStatement->fetchColumn();
76
-            $totalRequestsStatement->closeCursor();
77
-            $this->assign('totalRequests', $totalRequests);
78
-
79
-
80
-            $this->setHtmlTitle('{$header|escape}{if $totalRequests > 0} [{$totalRequests|escape}]{/if}');
81
-
82
-            $userIds = array_map(
83
-                function(Request $entry) {
84
-                    return $entry->getReserved();
85
-                },
86
-                $requests
87
-            );
88
-
89
-            $userList = UserSearchHelper::get($this->getDatabase())->inIds($userIds)->fetchMap('username');
90
-            $this->assign('userList', $userList);
91
-
92
-            $requestTrustedIp = [];
93
-            $relatedEmailRequests = [];
94
-            $relatedIpRequests = [];
95
-            foreach ($requests as $request) {
96
-                $trustedIp = $this->getXffTrustProvider()->getTrustedClientIp(
97
-                    $request->getIp(),
98
-                    $request->getForwardedIp()
99
-                );
100
-
101
-                RequestSearchHelper::get($database)
102
-                    ->byIp($trustedIp)
103
-                    ->withConfirmedEmail()
104
-                    ->excludingPurgedData($this->getSiteConfiguration())
105
-                    ->excludingRequest($request->getId())
106
-                    ->getRecordCount($ipCount);
107
-
108
-                RequestSearchHelper::get($database)
109
-                    ->byEmailAddress($request->getEmail())
110
-                    ->withConfirmedEmail()
111
-                    ->excludingPurgedData($this->getSiteConfiguration())
112
-                    ->excludingRequest($request->getId())
113
-                    ->getRecordCount($emailCount);
114
-
115
-                $requestTrustedIp[$request->getId()] = $trustedIp;
116
-                $relatedEmailRequests[$request->getId()] = $emailCount;
117
-                $relatedIpRequests[$request->getId()] = $ipCount;
118
-            }
119
-            $this->assign('requestTrustedIp', $requestTrustedIp);
120
-            $this->assign('relatedEmailRequests', $relatedEmailRequests);
121
-            $this->assign('relatedIpRequests', $relatedIpRequests);
122
-
123
-            $this->assign('requestLimitShowOnly', $config->getMiserModeLimit());
36
+			$this->assignCSRFToken();
37
+
38
+			$database = $this->getDatabase();
39
+
40
+			$help = $requestStates[$requestedStatus]['queuehelp'];
41
+			$this->assign('queuehelp', $help);
42
+
43
+			if ($config->getEmailConfirmationEnabled()) {
44
+				$query = "SELECT * FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
45
+				$totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
46
+			}
47
+			else {
48
+				$query = "SELECT * FROM request WHERE status = :type;";
49
+				$totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type;";
50
+			}
51
+
52
+			$statement = $database->prepare($query);
53
+
54
+			$totalRequestsStatement = $database->prepare($totalQuery);
55
+
56
+			$this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
57
+
58
+			$type = $requestedStatus;
59
+
60
+			$statement->bindValue(":type", $type);
61
+			$statement->execute();
62
+
63
+			$requests = $statement->fetchAll(PDO::FETCH_CLASS, Request::class);
64
+
65
+			/** @var Request $req */
66
+			foreach ($requests as $req) {
67
+				$req->setDatabase($database);
68
+			}
69
+
70
+			$this->assign('requests', $requests);
71
+			$this->assign('header', $type);
72
+
73
+			$totalRequestsStatement->bindValue(':type', $type);
74
+			$totalRequestsStatement->execute();
75
+			$totalRequests = $totalRequestsStatement->fetchColumn();
76
+			$totalRequestsStatement->closeCursor();
77
+			$this->assign('totalRequests', $totalRequests);
78
+
79
+
80
+			$this->setHtmlTitle('{$header|escape}{if $totalRequests > 0} [{$totalRequests|escape}]{/if}');
81
+
82
+			$userIds = array_map(
83
+				function(Request $entry) {
84
+					return $entry->getReserved();
85
+				},
86
+				$requests
87
+			);
88
+
89
+			$userList = UserSearchHelper::get($this->getDatabase())->inIds($userIds)->fetchMap('username');
90
+			$this->assign('userList', $userList);
91
+
92
+			$requestTrustedIp = [];
93
+			$relatedEmailRequests = [];
94
+			$relatedIpRequests = [];
95
+			foreach ($requests as $request) {
96
+				$trustedIp = $this->getXffTrustProvider()->getTrustedClientIp(
97
+					$request->getIp(),
98
+					$request->getForwardedIp()
99
+				);
100
+
101
+				RequestSearchHelper::get($database)
102
+					->byIp($trustedIp)
103
+					->withConfirmedEmail()
104
+					->excludingPurgedData($this->getSiteConfiguration())
105
+					->excludingRequest($request->getId())
106
+					->getRecordCount($ipCount);
107
+
108
+				RequestSearchHelper::get($database)
109
+					->byEmailAddress($request->getEmail())
110
+					->withConfirmedEmail()
111
+					->excludingPurgedData($this->getSiteConfiguration())
112
+					->excludingRequest($request->getId())
113
+					->getRecordCount($emailCount);
114
+
115
+				$requestTrustedIp[$request->getId()] = $trustedIp;
116
+				$relatedEmailRequests[$request->getId()] = $emailCount;
117
+				$relatedIpRequests[$request->getId()] = $ipCount;
118
+			}
119
+			$this->assign('requestTrustedIp', $requestTrustedIp);
120
+			$this->assign('relatedEmailRequests', $relatedEmailRequests);
121
+			$this->assign('relatedIpRequests', $relatedIpRequests);
122
+
123
+			$this->assign('requestLimitShowOnly', $config->getMiserModeLimit());
124 124
 
125
-            $currentUser = User::getCurrent($database);
126
-            $this->assign('canBan', $this->barrierTest('set', $currentUser, PageBan::class));
127
-            $this->assign('canBreakReservation', $this->barrierTest('force', $currentUser, PageBreakReservation::class));
125
+			$currentUser = User::getCurrent($database);
126
+			$this->assign('canBan', $this->barrierTest('set', $currentUser, PageBan::class));
127
+			$this->assign('canBreakReservation', $this->barrierTest('force', $currentUser, PageBreakReservation::class));
128 128
 
129
-            $this->assign('showPrivateData', $this->barrierTest('alwaysSeePrivateData', $currentUser, 'RequestData'));
130
-            $this->assign('xff', $this->getXffTrustProvider());
129
+			$this->assign('showPrivateData', $this->barrierTest('alwaysSeePrivateData', $currentUser, 'RequestData'));
130
+			$this->assign('xff', $this->getXffTrustProvider());
131 131
 
132
-            $this->assign('dataClearEmail', $this->getSiteConfiguration()->getDataClearEmail());
133
-            $this->assign('dataClearIp', $this->getSiteConfiguration()->getDataClearIp());
132
+			$this->assign('dataClearEmail', $this->getSiteConfiguration()->getDataClearEmail());
133
+			$this->assign('dataClearIp', $this->getSiteConfiguration()->getDataClearIp());
134 134
 
135
-            $this->setTemplate('mainpage/expandedrequestlist.tpl');
136
-        }
137
-    }
135
+			$this->setTemplate('mainpage/expandedrequestlist.tpl');
136
+		}
137
+	}
138 138
 }
Please login to merge, or discard this patch.
includes/Security/CredentialProviders/TotpCredentialProvider.php 2 patches
Indentation   +130 added lines, -130 removed lines patch added patch discarded remove patch
@@ -19,137 +19,137 @@
 block discarded – undo
19 19
 
20 20
 class TotpCredentialProvider extends CredentialProviderBase
21 21
 {
22
-    /** @var EncryptionHelper */
23
-    private $encryptionHelper;
24
-
25
-    /**
26
-     * TotpCredentialProvider constructor.
27
-     *
28
-     * @param PdoDatabase       $database
29
-     * @param SiteConfiguration $configuration
30
-     */
31
-    public function __construct(PdoDatabase $database, SiteConfiguration $configuration)
32
-    {
33
-        parent::__construct($database, $configuration, 'totp');
34
-        $this->encryptionHelper = new EncryptionHelper($configuration);
35
-    }
36
-
37
-    /**
38
-     * Validates a user-provided credential
39
-     *
40
-     * @param User   $user The user to test the authentication against
41
-     * @param string $data The raw credential data to be validated
42
-     *
43
-     * @return bool
44
-     * @throws ApplicationLogicException
45
-     */
46
-    public function authenticate(User $user, $data)
47
-    {
48
-        if (is_array($data)) {
49
-            return false;
50
-        }
51
-
52
-        $storedData = $this->getCredentialData($user->getId());
53
-
54
-        if ($storedData === null) {
55
-            throw new ApplicationLogicException('Credential data not found');
56
-        }
57
-
58
-        $provisioningUrl = $this->encryptionHelper->decryptData($storedData->getData());
59
-        $totp = Factory::loadFromProvisioningUri($provisioningUrl);
60
-
61
-        return $totp->verify($data, null, 2);
62
-    }
63
-
64
-    public function verifyEnable(User $user, $data)
65
-    {
66
-        $storedData = $this->getCredentialData($user->getId(), true);
67
-
68
-        if ($storedData === null) {
69
-            throw new ApplicationLogicException('Credential data not found');
70
-        }
71
-
72
-        $provisioningUrl = $this->encryptionHelper->decryptData($storedData->getData());
73
-        $totp = Factory::loadFromProvisioningUri($provisioningUrl);
74
-
75
-        $result = $totp->verify($data, null, 2);
76
-
77
-        if ($result && $storedData->getTimeout() > new DateTimeImmutable()) {
78
-            $storedData->setDisabled(0);
79
-            $storedData->setPriority(5);
80
-            $storedData->setTimeout(null);
81
-            $storedData->save();
82
-        }
83
-
84
-        return $result;
85
-    }
86
-
87
-    /**
88
-     * @param User   $user   The user the credential belongs to
89
-     * @param int    $factor The factor this credential provides
90
-     * @param string $data   Unused here, due to there being no user-provided data. We provide the user with the secret.
91
-     */
92
-    public function setCredential(User $user, $factor, $data)
93
-    {
94
-        $issuer = 'ACC - ' . $this->getConfiguration()->getIrcNotificationsInstance();
95
-        $totp = TOTP::create();
96
-        $totp->setLabel($user->getUsername());
97
-        $totp->setIssuer($issuer);
98
-
99
-        $storedData = $this->getCredentialData($user->getId(), null);
100
-
101
-        if ($storedData !== null) {
102
-            $storedData->delete();
103
-        }
104
-
105
-        $storedData = $this->createNewCredential($user);
106
-
107
-        $storedData->setData($this->encryptionHelper->encryptData($totp->getProvisioningUri()));
108
-        $storedData->setFactor($factor);
109
-        $storedData->setTimeout(new DateTimeImmutable('+ 1 hour'));
110
-        $storedData->setDisabled(1);
111
-        $storedData->setVersion(1);
112
-
113
-        $storedData->save();
114
-    }
115
-
116
-    public function getProvisioningUrl(User $user)
117
-    {
118
-        $storedData = $this->getCredentialData($user->getId(), true);
119
-
120
-        if ($storedData->getTimeout() < new DateTimeImmutable()) {
121
-            $storedData->delete();
122
-            $storedData = null;
123
-        }
124
-
125
-        if ($storedData === null) {
126
-            throw new ApplicationLogicException('Credential data not found');
127
-        }
128
-
129
-        return $this->encryptionHelper->decryptData($storedData->getData());
130
-    }
131
-
132
-    public function isPartiallyEnrolled(User $user)
133
-    {
134
-        $storedData = $this->getCredentialData($user->getId(), true);
135
-
136
-        if ($storedData->getTimeout() < new DateTimeImmutable()) {
137
-            $storedData->delete();
138
-
139
-            return false;
140
-        }
141
-
142
-        if ($storedData === null) {
143
-            return false;
144
-        }
22
+	/** @var EncryptionHelper */
23
+	private $encryptionHelper;
24
+
25
+	/**
26
+	 * TotpCredentialProvider constructor.
27
+	 *
28
+	 * @param PdoDatabase       $database
29
+	 * @param SiteConfiguration $configuration
30
+	 */
31
+	public function __construct(PdoDatabase $database, SiteConfiguration $configuration)
32
+	{
33
+		parent::__construct($database, $configuration, 'totp');
34
+		$this->encryptionHelper = new EncryptionHelper($configuration);
35
+	}
36
+
37
+	/**
38
+	 * Validates a user-provided credential
39
+	 *
40
+	 * @param User   $user The user to test the authentication against
41
+	 * @param string $data The raw credential data to be validated
42
+	 *
43
+	 * @return bool
44
+	 * @throws ApplicationLogicException
45
+	 */
46
+	public function authenticate(User $user, $data)
47
+	{
48
+		if (is_array($data)) {
49
+			return false;
50
+		}
51
+
52
+		$storedData = $this->getCredentialData($user->getId());
53
+
54
+		if ($storedData === null) {
55
+			throw new ApplicationLogicException('Credential data not found');
56
+		}
57
+
58
+		$provisioningUrl = $this->encryptionHelper->decryptData($storedData->getData());
59
+		$totp = Factory::loadFromProvisioningUri($provisioningUrl);
60
+
61
+		return $totp->verify($data, null, 2);
62
+	}
63
+
64
+	public function verifyEnable(User $user, $data)
65
+	{
66
+		$storedData = $this->getCredentialData($user->getId(), true);
67
+
68
+		if ($storedData === null) {
69
+			throw new ApplicationLogicException('Credential data not found');
70
+		}
71
+
72
+		$provisioningUrl = $this->encryptionHelper->decryptData($storedData->getData());
73
+		$totp = Factory::loadFromProvisioningUri($provisioningUrl);
74
+
75
+		$result = $totp->verify($data, null, 2);
76
+
77
+		if ($result && $storedData->getTimeout() > new DateTimeImmutable()) {
78
+			$storedData->setDisabled(0);
79
+			$storedData->setPriority(5);
80
+			$storedData->setTimeout(null);
81
+			$storedData->save();
82
+		}
83
+
84
+		return $result;
85
+	}
86
+
87
+	/**
88
+	 * @param User   $user   The user the credential belongs to
89
+	 * @param int    $factor The factor this credential provides
90
+	 * @param string $data   Unused here, due to there being no user-provided data. We provide the user with the secret.
91
+	 */
92
+	public function setCredential(User $user, $factor, $data)
93
+	{
94
+		$issuer = 'ACC - ' . $this->getConfiguration()->getIrcNotificationsInstance();
95
+		$totp = TOTP::create();
96
+		$totp->setLabel($user->getUsername());
97
+		$totp->setIssuer($issuer);
98
+
99
+		$storedData = $this->getCredentialData($user->getId(), null);
100
+
101
+		if ($storedData !== null) {
102
+			$storedData->delete();
103
+		}
104
+
105
+		$storedData = $this->createNewCredential($user);
106
+
107
+		$storedData->setData($this->encryptionHelper->encryptData($totp->getProvisioningUri()));
108
+		$storedData->setFactor($factor);
109
+		$storedData->setTimeout(new DateTimeImmutable('+ 1 hour'));
110
+		$storedData->setDisabled(1);
111
+		$storedData->setVersion(1);
112
+
113
+		$storedData->save();
114
+	}
115
+
116
+	public function getProvisioningUrl(User $user)
117
+	{
118
+		$storedData = $this->getCredentialData($user->getId(), true);
119
+
120
+		if ($storedData->getTimeout() < new DateTimeImmutable()) {
121
+			$storedData->delete();
122
+			$storedData = null;
123
+		}
124
+
125
+		if ($storedData === null) {
126
+			throw new ApplicationLogicException('Credential data not found');
127
+		}
128
+
129
+		return $this->encryptionHelper->decryptData($storedData->getData());
130
+	}
131
+
132
+	public function isPartiallyEnrolled(User $user)
133
+	{
134
+		$storedData = $this->getCredentialData($user->getId(), true);
135
+
136
+		if ($storedData->getTimeout() < new DateTimeImmutable()) {
137
+			$storedData->delete();
138
+
139
+			return false;
140
+		}
141
+
142
+		if ($storedData === null) {
143
+			return false;
144
+		}
145 145
 
146
-        return true;
147
-    }
146
+		return true;
147
+	}
148 148
 
149
-    public function getSecret(User $user)
150
-    {
151
-        $totp = Factory::loadFromProvisioningUri($this->getProvisioningUrl($user));
149
+	public function getSecret(User $user)
150
+	{
151
+		$totp = Factory::loadFromProvisioningUri($this->getProvisioningUrl($user));
152 152
 
153
-        return $totp->getSecret();
154
-    }
153
+		return $totp->getSecret();
154
+	}
155 155
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -91,7 +91,7 @@
 block discarded – undo
91 91
      */
92 92
     public function setCredential(User $user, $factor, $data)
93 93
     {
94
-        $issuer = 'ACC - ' . $this->getConfiguration()->getIrcNotificationsInstance();
94
+        $issuer = 'ACC - '.$this->getConfiguration()->getIrcNotificationsInstance();
95 95
         $totp = TOTP::create();
96 96
         $totp->setLabel($user->getUsername());
97 97
         $totp->setIssuer($issuer);
Please login to merge, or discard this patch.