Completed
Pull Request — newinternal (#285)
by Simon
07:17 queued 04:17
created
includes/Pages/RequestAction/PageSendToUser.php 1 patch
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -18,57 +18,57 @@
 block discarded – undo
18 18
 
19 19
 class PageSendToUser extends RequestActionBase
20 20
 {
21
-    /**
22
-     * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
23
-     * the return value from this function.
24
-     *
25
-     * If this page even supports actions, you will need to check the route
26
-     *
27
-     * @return SecurityConfiguration
28
-     * @category Security-Critical
29
-     */
30
-    protected function getSecurityConfiguration()
31
-    {
32
-        return $this->getSecurityManager()->configure()->asInternalPage();
33
-    }
21
+	/**
22
+	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
23
+	 * the return value from this function.
24
+	 *
25
+	 * If this page even supports actions, you will need to check the route
26
+	 *
27
+	 * @return SecurityConfiguration
28
+	 * @category Security-Critical
29
+	 */
30
+	protected function getSecurityConfiguration()
31
+	{
32
+		return $this->getSecurityManager()->configure()->asInternalPage();
33
+	}
34 34
 
35
-    /**
36
-     * Main function for this page, when no specific actions are called.
37
-     * @throws ApplicationLogicException
38
-     * @throws Exception
39
-     */
40
-    protected function main()
41
-    {
42
-        $this->checkPosted();
43
-        $database = $this->getDatabase();
44
-        $request = $this->getRequest($database);
35
+	/**
36
+	 * Main function for this page, when no specific actions are called.
37
+	 * @throws ApplicationLogicException
38
+	 * @throws Exception
39
+	 */
40
+	protected function main()
41
+	{
42
+		$this->checkPosted();
43
+		$database = $this->getDatabase();
44
+		$request = $this->getRequest($database);
45 45
 
46
-        if ($request->getReserved() !== User::getCurrent($database)->getId()) {
47
-            throw new ApplicationLogicException('You don\'t have this request reserved!');
48
-        }
46
+		if ($request->getReserved() !== User::getCurrent($database)->getId()) {
47
+			throw new ApplicationLogicException('You don\'t have this request reserved!');
48
+		}
49 49
 
50
-        $username = WebRequest::postString('user');
51
-        if ($username === null) {
52
-            throw new ApplicationLogicException('User must be specified');
53
-        }
50
+		$username = WebRequest::postString('user');
51
+		if ($username === null) {
52
+			throw new ApplicationLogicException('User must be specified');
53
+		}
54 54
 
55
-        $user = User::getByUsername($username, $database);
56
-        if ($user === false) {
57
-            throw new ApplicationLogicException('User not found');
58
-        }
55
+		$user = User::getByUsername($username, $database);
56
+		if ($user === false) {
57
+			throw new ApplicationLogicException('User not found');
58
+		}
59 59
 
60
-        if (!$user->isUser() && !$user->isAdmin()) {
61
-            throw new ApplicationLogicException('User is currently not active on the tool');
62
-        }
60
+		if (!$user->isUser() && !$user->isAdmin()) {
61
+			throw new ApplicationLogicException('User is currently not active on the tool');
62
+		}
63 63
 
64
-        $request->setReserved($user->getId());
65
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
66
-        $request->save();
64
+		$request->setReserved($user->getId());
65
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
66
+		$request->save();
67 67
 
68
-        Logger::sendReservation($database, $request, $user);
69
-        $this->getNotificationHelper()->requestReservationSent($request, $user);
70
-        SessionAlert::success("Reservation sent successfully");
68
+		Logger::sendReservation($database, $request, $user);
69
+		$this->getNotificationHelper()->requestReservationSent($request, $user);
70
+		SessionAlert::success("Reservation sent successfully");
71 71
 
72
-        $this->redirect('viewRequest', null, array('id' => $request->getId()));
73
-    }
72
+		$this->redirect('viewRequest', null, array('id' => $request->getId()));
73
+	}
74 74
 }
75 75
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageReservation.php 1 patch
Indentation   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -18,69 +18,69 @@
 block discarded – undo
18 18
 
19 19
 class PageReservation extends RequestActionBase
20 20
 {
21
-    /**
22
-     * Main function for this page, when no specific actions are called.
23
-     * @throws ApplicationLogicException
24
-     */
25
-    protected function main()
26
-    {
27
-        $this->checkPosted();
28
-        $database = $this->getDatabase();
29
-        $request = $this->getRequest($database);
21
+	/**
22
+	 * Main function for this page, when no specific actions are called.
23
+	 * @throws ApplicationLogicException
24
+	 */
25
+	protected function main()
26
+	{
27
+		$this->checkPosted();
28
+		$database = $this->getDatabase();
29
+		$request = $this->getRequest($database);
30 30
 
31
-        $closureDate = $request->getClosureDate();
31
+		$closureDate = $request->getClosureDate();
32 32
 
33
-        $date = new DateTime();
34
-        $date->modify("-7 days");
35
-        $oneweek = $date->format("Y-m-d H:i:s");
33
+		$date = new DateTime();
34
+		$date->modify("-7 days");
35
+		$oneweek = $date->format("Y-m-d H:i:s");
36 36
 
37
-        if ($request->getStatus() == "Closed" && $closureDate < $oneweek && !User::getCurrent($database)->isAdmin()) {
38
-            throw new ApplicationLogicException(
39
-                "Only administrators and checkusers can reserve a request that has been closed for over a week.");
40
-        }
37
+		if ($request->getStatus() == "Closed" && $closureDate < $oneweek && !User::getCurrent($database)->isAdmin()) {
38
+			throw new ApplicationLogicException(
39
+				"Only administrators and checkusers can reserve a request that has been closed for over a week.");
40
+		}
41 41
 
42
-        if ($request->getReserved() !== null && $request->getReserved() != User::getCurrent($database)->getId()) {
43
-            throw new ApplicationLogicException("Request is already reserved!");
44
-        }
42
+		if ($request->getReserved() !== null && $request->getReserved() != User::getCurrent($database)->getId()) {
43
+			throw new ApplicationLogicException("Request is already reserved!");
44
+		}
45 45
 
46
-        if ($request->getReserved() === null) {
47
-            // Check the number of requests a user has reserved already
48
-            $doubleReserveCountQuery = $database->prepare("SELECT COUNT(*) FROM request WHERE reserved = :userid;");
49
-            $doubleReserveCountQuery->bindValue(":userid", User::getCurrent($database)->getId());
50
-            $doubleReserveCountQuery->execute();
51
-            $doubleReserveCount = $doubleReserveCountQuery->fetchColumn();
52
-            $doubleReserveCountQuery->closeCursor();
46
+		if ($request->getReserved() === null) {
47
+			// Check the number of requests a user has reserved already
48
+			$doubleReserveCountQuery = $database->prepare("SELECT COUNT(*) FROM request WHERE reserved = :userid;");
49
+			$doubleReserveCountQuery->bindValue(":userid", User::getCurrent($database)->getId());
50
+			$doubleReserveCountQuery->execute();
51
+			$doubleReserveCount = $doubleReserveCountQuery->fetchColumn();
52
+			$doubleReserveCountQuery->closeCursor();
53 53
 
54
-            // User already has at least one reserved.
55
-            if ($doubleReserveCount != 0) {
56
-                SessionAlert::warning("You have multiple requests reserved!");
57
-            }
54
+			// User already has at least one reserved.
55
+			if ($doubleReserveCount != 0) {
56
+				SessionAlert::warning("You have multiple requests reserved!");
57
+			}
58 58
 
59
-            $request->setReserved(User::getCurrent($database)->getId());
60
-            $request->setUpdateVersion(WebRequest::postInt('updateversion'));
61
-            $request->save();
59
+			$request->setReserved(User::getCurrent($database)->getId());
60
+			$request->setUpdateVersion(WebRequest::postInt('updateversion'));
61
+			$request->save();
62 62
 
63
-            Logger::reserve($database, $request);
63
+			Logger::reserve($database, $request);
64 64
 
65
-            $this->getNotificationHelper()->requestReserved($request);
65
+			$this->getNotificationHelper()->requestReserved($request);
66 66
 
67
-            SessionAlert::success("Reserved request {$request->getId()}.");
68
-        }
67
+			SessionAlert::success("Reserved request {$request->getId()}.");
68
+		}
69 69
 
70
-        $this->redirect('viewRequest', null, array('id' => $request->getId()));
71
-    }
70
+		$this->redirect('viewRequest', null, array('id' => $request->getId()));
71
+	}
72 72
 
73
-    /**
74
-     * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
75
-     * the return value from this function.
76
-     *
77
-     * If this page even supports actions, you will need to check the route
78
-     *
79
-     * @return SecurityConfiguration
80
-     * @category Security-Critical
81
-     */
82
-    protected function getSecurityConfiguration()
83
-    {
84
-        return $this->getSecurityManager()->configure()->asInternalPage();
85
-    }
73
+	/**
74
+	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
75
+	 * the return value from this function.
76
+	 *
77
+	 * If this page even supports actions, you will need to check the route
78
+	 *
79
+	 * @return SecurityConfiguration
80
+	 * @category Security-Critical
81
+	 */
82
+	protected function getSecurityConfiguration()
83
+	{
84
+		return $this->getSecurityManager()->configure()->asInternalPage();
85
+	}
86 86
 }
87 87
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCustomClose.php 1 patch
Indentation   +258 added lines, -258 removed lines patch added patch discarded remove patch
@@ -23,262 +23,262 @@
 block discarded – undo
23 23
 
24 24
 class PageCustomClose extends PageCloseRequest
25 25
 {
26
-    use RequestData;
27
-
28
-    protected function main()
29
-    {
30
-        $database = $this->getDatabase();
31
-
32
-        $request = $this->getRequest($database);
33
-        $currentUser = User::getCurrent($this->getDatabase());
34
-
35
-        if ($request->getStatus() === 'Closed') {
36
-            throw new ApplicationLogicException('Request is already closed');
37
-        }
38
-
39
-        // Dual-mode page
40
-        if (WebRequest::wasPosted()) {
41
-            $this->validateCSRFToken();
42
-            $this->doCustomClose($currentUser, $request, $database);
43
-
44
-            $this->redirect();
45
-        }
46
-        else {
47
-            $this->assignCSRFToken();
48
-            $this->showCustomCloseForm($database, $request);
49
-        }
50
-    }
51
-
52
-    /**
53
-     * @param $database
54
-     *
55
-     * @return Request
56
-     * @throws ApplicationLogicException
57
-     */
58
-    protected function getRequest(PdoDatabase $database)
59
-    {
60
-        $requestId = WebRequest::getInt('request');
61
-        if ($requestId === null) {
62
-            throw new ApplicationLogicException('Request ID not found');
63
-        }
64
-
65
-        /** @var Request $request */
66
-        $request = Request::getById($requestId, $database);
67
-
68
-        if ($request === false) {
69
-            throw new ApplicationLogicException('Request not found');
70
-        }
71
-
72
-        return $request;
73
-    }
74
-
75
-    /**
76
-     * @param PdoDatabase $database
77
-     *
78
-     * @return EmailTemplate|null
79
-     */
80
-    protected function getTemplate(PdoDatabase $database)
81
-    {
82
-        $templateId = WebRequest::getInt('template');
83
-        if ($templateId === null) {
84
-            return null;
85
-        }
86
-
87
-        /** @var EmailTemplate $template */
88
-        $template = EmailTemplate::getById($templateId, $database);
89
-        if ($template === false || !$template->getActive()) {
90
-            return null;
91
-        }
92
-
93
-        return $template;
94
-    }
95
-
96
-    /**
97
-     * @param $database
98
-     * @param $request
99
-     *
100
-     * @throws Exception
101
-     */
102
-    protected function showCustomCloseForm(PdoDatabase $database, Request $request)
103
-    {
104
-        $currentUser = User::getCurrent($database);
105
-        $config = $this->getSiteConfiguration();
106
-
107
-        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
108
-        if (!$allowedPrivateData) {
109
-            // we probably shouldn't be showing the user this form if they're not allowed to access private data...
110
-            throw new AccessDeniedException();
111
-        }
112
-
113
-        $template = $this->getTemplate($database);
114
-
115
-        // Preload data
116
-        $this->assign('defaultAction', '');
117
-        $this->assign('preloadText', '');
118
-        $this->assign('preloadTitle', '');
119
-
120
-        if ($template !== null) {
121
-            $this->assign('defaultAction', $template->getDefaultAction());
122
-            $this->assign('preloadText', $template->getText());
123
-            $this->assign('preloadTitle', $template->getName());
124
-        }
125
-
126
-        // Static data
127
-        $this->assign('requeststates', $config->getRequestStates());
128
-
129
-        // request data
130
-        $this->assign('requestId', $request->getIp());
131
-        $this->assign('updateVersion', $request->getUpdateVersion());
132
-        $this->setupBasicData($request, $config);
133
-        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
134
-        $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
135
-
136
-        // IP location
137
-        $trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
138
-        $this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
139
-
140
-        // Confirmations
141
-        $this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
142
-        $this->assign('confirmReserveOverride', $this->checkReserveOverride($request, $currentUser));
143
-
144
-        // template
145
-        $this->setTemplate('custom-close.tpl');
146
-    }
147
-
148
-    /**
149
-     * @param User        $currentUser
150
-     * @param Request     $request
151
-     * @param PdoDatabase $database
152
-     *
153
-     * @throws ApplicationLogicException
154
-     */
155
-    protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
156
-    {
157
-        $messageBody = WebRequest::postString('msgbody');
158
-        if ($messageBody === null || trim($messageBody) === '') {
159
-            throw new ApplicationLogicException('Message body cannot be blank');
160
-        }
161
-
162
-        $ccMailingList = true;
163
-        if ($currentUser->isAdmin() || $currentUser->isCheckuser()) {
164
-            $ccMailingList = WebRequest::postBoolean('ccMailingList');
165
-        }
166
-
167
-        if ($request->getStatus() === 'Closed') {
168
-            throw new ApplicationLogicException('Request is already closed');
169
-        }
170
-
171
-        if (!(WebRequest::postBoolean('confirmEmailAlreadySent')
172
-            && WebRequest::postBoolean('confirmReserveOverride'))
173
-        ) {
174
-            throw new ApplicationLogicException('Not all confirmations checked');
175
-        }
176
-
177
-        $action = WebRequest::postString('action');
178
-        $availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
179
-
180
-        if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
181
-            // Close request
182
-            $this->closeRequest($request, $database, $action, $messageBody);
183
-
184
-            // Send the mail after the save, since save can be rolled back
185
-            $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
186
-        }
187
-        else {
188
-            if (array_key_exists($action, $availableRequestStates)) {
189
-                // Defer to other state
190
-                $this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
191
-
192
-                // Send the mail after the save, since save can be rolled back
193
-                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
194
-            }
195
-            else {
196
-                $request->setReserved(null);
197
-                $request->setUpdateVersion(WebRequest::postInt('updateversion'));
198
-                $request->save();
199
-
200
-                // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
201
-                // and be rolled back.
202
-
203
-                // Send mail
204
-                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
205
-
206
-                Logger::sentMail($database, $request, $messageBody);
207
-                Logger::unreserve($database, $request);
208
-
209
-                $this->getNotificationHelper()->sentMail($request);
210
-                SessionAlert::success("Sent mail to Request {$request->getId()}");
211
-            }
212
-        }
213
-    }
214
-
215
-    /**
216
-     * @param Request     $request
217
-     * @param PdoDatabase $database
218
-     * @param string      $action
219
-     * @param string      $messageBody
220
-     *
221
-     * @throws Exception
222
-     * @throws OptimisticLockFailedException
223
-     */
224
-    protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
225
-    {
226
-        $request->setStatus('Closed');
227
-        $request->setReserved(null);
228
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
229
-        $request->save();
230
-
231
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
232
-        // be rolled back.
233
-
234
-        if ($action == EmailTemplate::CREATED) {
235
-            $logCloseType = 'custom-y';
236
-            $notificationCloseType = "Custom, Created";
237
-        }
238
-        else {
239
-            $logCloseType = 'custom-n';
240
-            $notificationCloseType = "Custom, Not Created";
241
-        }
242
-
243
-        Logger::closeRequest($database, $request, $logCloseType, $messageBody);
244
-        $this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
245
-
246
-        $requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
247
-        SessionAlert::success("Request {$request->getId()} ({$requestName}) marked as 'Done'.");
248
-    }
249
-
250
-    /**
251
-     * @param Request     $request
252
-     * @param PdoDatabase $database
253
-     * @param string      $action
254
-     * @param             $availableRequestStates
255
-     * @param string      $messageBody
256
-     *
257
-     * @throws Exception
258
-     * @throws OptimisticLockFailedException
259
-     */
260
-    protected function deferRequest(
261
-        Request $request,
262
-        PdoDatabase $database,
263
-        $action,
264
-        $availableRequestStates,
265
-        $messageBody
266
-    ) {
267
-        $request->setStatus($action);
268
-        $request->setReserved(null);
269
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
270
-        $request->save();
271
-
272
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
273
-        // and be rolled back.
274
-
275
-        $deferToLog = $availableRequestStates[$action]['defertolog'];
276
-        Logger::sentMail($database, $request, $messageBody);
277
-        Logger::deferRequest($database, $request, $deferToLog);
278
-
279
-        $this->getNotificationHelper()->requestDeferredWithMail($request);
280
-
281
-        $deferTo = $availableRequestStates[$action]['deferto'];
282
-        SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
283
-    }
26
+	use RequestData;
27
+
28
+	protected function main()
29
+	{
30
+		$database = $this->getDatabase();
31
+
32
+		$request = $this->getRequest($database);
33
+		$currentUser = User::getCurrent($this->getDatabase());
34
+
35
+		if ($request->getStatus() === 'Closed') {
36
+			throw new ApplicationLogicException('Request is already closed');
37
+		}
38
+
39
+		// Dual-mode page
40
+		if (WebRequest::wasPosted()) {
41
+			$this->validateCSRFToken();
42
+			$this->doCustomClose($currentUser, $request, $database);
43
+
44
+			$this->redirect();
45
+		}
46
+		else {
47
+			$this->assignCSRFToken();
48
+			$this->showCustomCloseForm($database, $request);
49
+		}
50
+	}
51
+
52
+	/**
53
+	 * @param $database
54
+	 *
55
+	 * @return Request
56
+	 * @throws ApplicationLogicException
57
+	 */
58
+	protected function getRequest(PdoDatabase $database)
59
+	{
60
+		$requestId = WebRequest::getInt('request');
61
+		if ($requestId === null) {
62
+			throw new ApplicationLogicException('Request ID not found');
63
+		}
64
+
65
+		/** @var Request $request */
66
+		$request = Request::getById($requestId, $database);
67
+
68
+		if ($request === false) {
69
+			throw new ApplicationLogicException('Request not found');
70
+		}
71
+
72
+		return $request;
73
+	}
74
+
75
+	/**
76
+	 * @param PdoDatabase $database
77
+	 *
78
+	 * @return EmailTemplate|null
79
+	 */
80
+	protected function getTemplate(PdoDatabase $database)
81
+	{
82
+		$templateId = WebRequest::getInt('template');
83
+		if ($templateId === null) {
84
+			return null;
85
+		}
86
+
87
+		/** @var EmailTemplate $template */
88
+		$template = EmailTemplate::getById($templateId, $database);
89
+		if ($template === false || !$template->getActive()) {
90
+			return null;
91
+		}
92
+
93
+		return $template;
94
+	}
95
+
96
+	/**
97
+	 * @param $database
98
+	 * @param $request
99
+	 *
100
+	 * @throws Exception
101
+	 */
102
+	protected function showCustomCloseForm(PdoDatabase $database, Request $request)
103
+	{
104
+		$currentUser = User::getCurrent($database);
105
+		$config = $this->getSiteConfiguration();
106
+
107
+		$allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
108
+		if (!$allowedPrivateData) {
109
+			// we probably shouldn't be showing the user this form if they're not allowed to access private data...
110
+			throw new AccessDeniedException();
111
+		}
112
+
113
+		$template = $this->getTemplate($database);
114
+
115
+		// Preload data
116
+		$this->assign('defaultAction', '');
117
+		$this->assign('preloadText', '');
118
+		$this->assign('preloadTitle', '');
119
+
120
+		if ($template !== null) {
121
+			$this->assign('defaultAction', $template->getDefaultAction());
122
+			$this->assign('preloadText', $template->getText());
123
+			$this->assign('preloadTitle', $template->getName());
124
+		}
125
+
126
+		// Static data
127
+		$this->assign('requeststates', $config->getRequestStates());
128
+
129
+		// request data
130
+		$this->assign('requestId', $request->getIp());
131
+		$this->assign('updateVersion', $request->getUpdateVersion());
132
+		$this->setupBasicData($request, $config);
133
+		$this->setupReservationDetails($request->getReserved(), $database, $currentUser);
134
+		$this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
135
+
136
+		// IP location
137
+		$trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
138
+		$this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
139
+
140
+		// Confirmations
141
+		$this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
142
+		$this->assign('confirmReserveOverride', $this->checkReserveOverride($request, $currentUser));
143
+
144
+		// template
145
+		$this->setTemplate('custom-close.tpl');
146
+	}
147
+
148
+	/**
149
+	 * @param User        $currentUser
150
+	 * @param Request     $request
151
+	 * @param PdoDatabase $database
152
+	 *
153
+	 * @throws ApplicationLogicException
154
+	 */
155
+	protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
156
+	{
157
+		$messageBody = WebRequest::postString('msgbody');
158
+		if ($messageBody === null || trim($messageBody) === '') {
159
+			throw new ApplicationLogicException('Message body cannot be blank');
160
+		}
161
+
162
+		$ccMailingList = true;
163
+		if ($currentUser->isAdmin() || $currentUser->isCheckuser()) {
164
+			$ccMailingList = WebRequest::postBoolean('ccMailingList');
165
+		}
166
+
167
+		if ($request->getStatus() === 'Closed') {
168
+			throw new ApplicationLogicException('Request is already closed');
169
+		}
170
+
171
+		if (!(WebRequest::postBoolean('confirmEmailAlreadySent')
172
+			&& WebRequest::postBoolean('confirmReserveOverride'))
173
+		) {
174
+			throw new ApplicationLogicException('Not all confirmations checked');
175
+		}
176
+
177
+		$action = WebRequest::postString('action');
178
+		$availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
179
+
180
+		if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
181
+			// Close request
182
+			$this->closeRequest($request, $database, $action, $messageBody);
183
+
184
+			// Send the mail after the save, since save can be rolled back
185
+			$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
186
+		}
187
+		else {
188
+			if (array_key_exists($action, $availableRequestStates)) {
189
+				// Defer to other state
190
+				$this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
191
+
192
+				// Send the mail after the save, since save can be rolled back
193
+				$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
194
+			}
195
+			else {
196
+				$request->setReserved(null);
197
+				$request->setUpdateVersion(WebRequest::postInt('updateversion'));
198
+				$request->save();
199
+
200
+				// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
201
+				// and be rolled back.
202
+
203
+				// Send mail
204
+				$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
205
+
206
+				Logger::sentMail($database, $request, $messageBody);
207
+				Logger::unreserve($database, $request);
208
+
209
+				$this->getNotificationHelper()->sentMail($request);
210
+				SessionAlert::success("Sent mail to Request {$request->getId()}");
211
+			}
212
+		}
213
+	}
214
+
215
+	/**
216
+	 * @param Request     $request
217
+	 * @param PdoDatabase $database
218
+	 * @param string      $action
219
+	 * @param string      $messageBody
220
+	 *
221
+	 * @throws Exception
222
+	 * @throws OptimisticLockFailedException
223
+	 */
224
+	protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
225
+	{
226
+		$request->setStatus('Closed');
227
+		$request->setReserved(null);
228
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
229
+		$request->save();
230
+
231
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
232
+		// be rolled back.
233
+
234
+		if ($action == EmailTemplate::CREATED) {
235
+			$logCloseType = 'custom-y';
236
+			$notificationCloseType = "Custom, Created";
237
+		}
238
+		else {
239
+			$logCloseType = 'custom-n';
240
+			$notificationCloseType = "Custom, Not Created";
241
+		}
242
+
243
+		Logger::closeRequest($database, $request, $logCloseType, $messageBody);
244
+		$this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
245
+
246
+		$requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
247
+		SessionAlert::success("Request {$request->getId()} ({$requestName}) marked as 'Done'.");
248
+	}
249
+
250
+	/**
251
+	 * @param Request     $request
252
+	 * @param PdoDatabase $database
253
+	 * @param string      $action
254
+	 * @param             $availableRequestStates
255
+	 * @param string      $messageBody
256
+	 *
257
+	 * @throws Exception
258
+	 * @throws OptimisticLockFailedException
259
+	 */
260
+	protected function deferRequest(
261
+		Request $request,
262
+		PdoDatabase $database,
263
+		$action,
264
+		$availableRequestStates,
265
+		$messageBody
266
+	) {
267
+		$request->setStatus($action);
268
+		$request->setReserved(null);
269
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
270
+		$request->save();
271
+
272
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
273
+		// and be rolled back.
274
+
275
+		$deferToLog = $availableRequestStates[$action]['defertolog'];
276
+		Logger::sentMail($database, $request, $messageBody);
277
+		Logger::deferRequest($database, $request, $deferToLog);
278
+
279
+		$this->getNotificationHelper()->requestDeferredWithMail($request);
280
+
281
+		$deferTo = $availableRequestStates[$action]['deferto'];
282
+		SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
283
+	}
284 284
 }
285 285
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/Page404.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -13,30 +13,30 @@
 block discarded – undo
13 13
 
14 14
 class Page404 extends InternalPageBase
15 15
 {
16
-    /**
17
-     * Main function for this page, when no actions are called.
18
-     */
19
-    protected function main()
20
-    {
21
-        if (!headers_sent()) {
22
-            header("HTTP/1.1 404 Not Found");
23
-        }
16
+	/**
17
+	 * Main function for this page, when no actions are called.
18
+	 */
19
+	protected function main()
20
+	{
21
+		if (!headers_sent()) {
22
+			header("HTTP/1.1 404 Not Found");
23
+		}
24 24
 
25
-        $this->setTemplate("404.tpl");
26
-    }
25
+		$this->setTemplate("404.tpl");
26
+	}
27 27
 
28
-    /**
29
-     * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
30
-     * the return value from this function.
31
-     *
32
-     * If this page even supports actions, you will need to check the route
33
-     *
34
-     * @return SecurityConfiguration
35
-     * @category Security-Critical
36
-     */
37
-    protected function getSecurityConfiguration()
38
-    {
39
-        // public because 404s will never contain private data.
40
-        return $this->getSecurityManager()->configure()->asPublicPage();
41
-    }
28
+	/**
29
+	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
30
+	 * the return value from this function.
31
+	 *
32
+	 * If this page even supports actions, you will need to check the route
33
+	 *
34
+	 * @return SecurityConfiguration
35
+	 * @category Security-Critical
36
+	 */
37
+	protected function getSecurityConfiguration()
38
+	{
39
+		// public because 404s will never contain private data.
40
+		return $this->getSecurityManager()->configure()->asPublicPage();
41
+	}
42 42
 }
43 43
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/PageForgotPassword.php 1 patch
Indentation   +154 added lines, -154 removed lines patch added patch discarded remove patch
@@ -18,158 +18,158 @@
 block discarded – undo
18 18
 
19 19
 class PageForgotPassword extends InternalPageBase
20 20
 {
21
-    /**
22
-     * Main function for this page, when no specific actions are called.
23
-     *
24
-     * This is the forgotten password reset form
25
-     * @category Security-Critical
26
-     */
27
-    protected function main()
28
-    {
29
-        if (WebRequest::wasPosted()) {
30
-            $this->validateCSRFToken();
31
-            $username = WebRequest::postString('username');
32
-            $email = WebRequest::postEmail('email');
33
-            $database = $this->getDatabase();
34
-
35
-            if ($username === null || trim($username) === "" || $email === null || trim($email) === "") {
36
-                throw new ApplicationLogicException("Both username and email address must be specified!");
37
-            }
38
-
39
-            $user = User::getByUsername($username, $database);
40
-            $this->sendResetMail($user, $email);
41
-
42
-            SessionAlert::success('<strong>Your password reset request has been completed.</strong> Please check your e-mail.');
43
-
44
-            $this->redirect('login');
45
-        }
46
-        else {
47
-            $this->assignCSRFToken();
48
-            $this->setTemplate('forgot-password/forgotpw.tpl');
49
-        }
50
-    }
51
-
52
-    /**
53
-     * Sends a reset email if the user is authenticated
54
-     *
55
-     * @param User|boolean $user  The user located from the database, or false. Doesn't really matter, since we do the
56
-     *                            check anyway within this method and silently skip if we don't have a user.
57
-     * @param string       $email The provided email address
58
-     */
59
-    private function sendResetMail($user, $email)
60
-    {
61
-        // If the user isn't found, or the email address is wrong, skip sending the details silently.
62
-        if (!$user instanceof User) {
63
-            return;
64
-        }
65
-
66
-        if (strtolower($user->getEmail()) === strtolower($email)) {
67
-            $clientIp = $this->getXffTrustProvider()
68
-                ->getTrustedClientIp(WebRequest::remoteAddress(), WebRequest::forwardedAddress());
69
-
70
-            $this->assign("user", $user);
71
-            $this->assign("hash", $user->getForgottenPasswordHash());
72
-            $this->assign("remoteAddress", $clientIp);
73
-
74
-            $emailContent = $this->fetchTemplate('forgot-password/reset-mail.tpl');
75
-
76
-            $this->getEmailHelper()->sendMail($user->getEmail(), "", $emailContent);
77
-        }
78
-    }
79
-
80
-    /**
81
-     * Entry point for the reset action
82
-     *
83
-     * This is the reset password part of the form.
84
-     * @category Security-Critical
85
-     */
86
-    protected function reset()
87
-    {
88
-        $si = WebRequest::getString('si');
89
-        $id = WebRequest::getString('id');
90
-
91
-        if ($si === null || trim($si) === "" || $id === null || trim($id) === "") {
92
-            throw new ApplicationLogicException("Link not valid, please ensure it has copied correctly");
93
-        }
94
-
95
-        $database = $this->getDatabase();
96
-        $user = $this->getResettingUser($id, $database, $si);
97
-
98
-        // Dual mode
99
-        if (WebRequest::wasPosted()) {
100
-            $this->validateCSRFToken();
101
-            try {
102
-                $this->doReset($user);
103
-            }
104
-            catch (ApplicationLogicException $ex) {
105
-                SessionAlert::error($ex->getMessage());
106
-                $this->redirect('forgotPassword', 'reset', array('si' => $si, 'id' => $id));
107
-
108
-                return;
109
-            }
110
-        }
111
-        else {
112
-            $this->assignCSRFToken();
113
-            $this->assign('user', $user);
114
-            $this->setTemplate('forgot-password/forgotpwreset.tpl');
115
-        }
116
-    }
117
-
118
-    /**
119
-     * Gets the user resetting their password from the database, or throwing an exception if that is not possible.
120
-     *
121
-     * @param integer     $id       The ID of the user to retrieve
122
-     * @param PdoDatabase $database The database object to use
123
-     * @param string      $si       The reset hash provided
124
-     *
125
-     * @return User
126
-     * @throws ApplicationLogicException
127
-     */
128
-    private function getResettingUser($id, $database, $si)
129
-    {
130
-        $user = User::getById($id, $database);
131
-
132
-        if ($user === false || $user->getForgottenPasswordHash() !== $si || $user->isCommunityUser()) {
133
-            throw new ApplicationLogicException("User not found");
134
-        }
135
-
136
-        return $user;
137
-    }
138
-
139
-    /**
140
-     * Performs the setting of the new password
141
-     *
142
-     * @param User $user The user to set the password for
143
-     *
144
-     * @throws ApplicationLogicException
145
-     */
146
-    private function doReset(User $user)
147
-    {
148
-        $pw = WebRequest::postString('pw');
149
-        $pw2 = WebRequest::postString('pw2');
150
-
151
-        if ($pw !== $pw2) {
152
-            throw new ApplicationLogicException('Passwords do not match!');
153
-        }
154
-
155
-        $user->setPassword($pw);
156
-        $user->save();
157
-
158
-        SessionAlert::success('You may now log in!');
159
-        $this->redirect('login');
160
-    }
161
-
162
-    /**
163
-     * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
164
-     * the return value from this function.
165
-     *
166
-     * If this page even supports actions, you will need to check the route
167
-     *
168
-     * @return SecurityConfiguration
169
-     * @category Security-Critical
170
-     */
171
-    protected function getSecurityConfiguration()
172
-    {
173
-        return $this->getSecurityManager()->configure()->asPublicPage();
174
-    }
21
+	/**
22
+	 * Main function for this page, when no specific actions are called.
23
+	 *
24
+	 * This is the forgotten password reset form
25
+	 * @category Security-Critical
26
+	 */
27
+	protected function main()
28
+	{
29
+		if (WebRequest::wasPosted()) {
30
+			$this->validateCSRFToken();
31
+			$username = WebRequest::postString('username');
32
+			$email = WebRequest::postEmail('email');
33
+			$database = $this->getDatabase();
34
+
35
+			if ($username === null || trim($username) === "" || $email === null || trim($email) === "") {
36
+				throw new ApplicationLogicException("Both username and email address must be specified!");
37
+			}
38
+
39
+			$user = User::getByUsername($username, $database);
40
+			$this->sendResetMail($user, $email);
41
+
42
+			SessionAlert::success('<strong>Your password reset request has been completed.</strong> Please check your e-mail.');
43
+
44
+			$this->redirect('login');
45
+		}
46
+		else {
47
+			$this->assignCSRFToken();
48
+			$this->setTemplate('forgot-password/forgotpw.tpl');
49
+		}
50
+	}
51
+
52
+	/**
53
+	 * Sends a reset email if the user is authenticated
54
+	 *
55
+	 * @param User|boolean $user  The user located from the database, or false. Doesn't really matter, since we do the
56
+	 *                            check anyway within this method and silently skip if we don't have a user.
57
+	 * @param string       $email The provided email address
58
+	 */
59
+	private function sendResetMail($user, $email)
60
+	{
61
+		// If the user isn't found, or the email address is wrong, skip sending the details silently.
62
+		if (!$user instanceof User) {
63
+			return;
64
+		}
65
+
66
+		if (strtolower($user->getEmail()) === strtolower($email)) {
67
+			$clientIp = $this->getXffTrustProvider()
68
+				->getTrustedClientIp(WebRequest::remoteAddress(), WebRequest::forwardedAddress());
69
+
70
+			$this->assign("user", $user);
71
+			$this->assign("hash", $user->getForgottenPasswordHash());
72
+			$this->assign("remoteAddress", $clientIp);
73
+
74
+			$emailContent = $this->fetchTemplate('forgot-password/reset-mail.tpl');
75
+
76
+			$this->getEmailHelper()->sendMail($user->getEmail(), "", $emailContent);
77
+		}
78
+	}
79
+
80
+	/**
81
+	 * Entry point for the reset action
82
+	 *
83
+	 * This is the reset password part of the form.
84
+	 * @category Security-Critical
85
+	 */
86
+	protected function reset()
87
+	{
88
+		$si = WebRequest::getString('si');
89
+		$id = WebRequest::getString('id');
90
+
91
+		if ($si === null || trim($si) === "" || $id === null || trim($id) === "") {
92
+			throw new ApplicationLogicException("Link not valid, please ensure it has copied correctly");
93
+		}
94
+
95
+		$database = $this->getDatabase();
96
+		$user = $this->getResettingUser($id, $database, $si);
97
+
98
+		// Dual mode
99
+		if (WebRequest::wasPosted()) {
100
+			$this->validateCSRFToken();
101
+			try {
102
+				$this->doReset($user);
103
+			}
104
+			catch (ApplicationLogicException $ex) {
105
+				SessionAlert::error($ex->getMessage());
106
+				$this->redirect('forgotPassword', 'reset', array('si' => $si, 'id' => $id));
107
+
108
+				return;
109
+			}
110
+		}
111
+		else {
112
+			$this->assignCSRFToken();
113
+			$this->assign('user', $user);
114
+			$this->setTemplate('forgot-password/forgotpwreset.tpl');
115
+		}
116
+	}
117
+
118
+	/**
119
+	 * Gets the user resetting their password from the database, or throwing an exception if that is not possible.
120
+	 *
121
+	 * @param integer     $id       The ID of the user to retrieve
122
+	 * @param PdoDatabase $database The database object to use
123
+	 * @param string      $si       The reset hash provided
124
+	 *
125
+	 * @return User
126
+	 * @throws ApplicationLogicException
127
+	 */
128
+	private function getResettingUser($id, $database, $si)
129
+	{
130
+		$user = User::getById($id, $database);
131
+
132
+		if ($user === false || $user->getForgottenPasswordHash() !== $si || $user->isCommunityUser()) {
133
+			throw new ApplicationLogicException("User not found");
134
+		}
135
+
136
+		return $user;
137
+	}
138
+
139
+	/**
140
+	 * Performs the setting of the new password
141
+	 *
142
+	 * @param User $user The user to set the password for
143
+	 *
144
+	 * @throws ApplicationLogicException
145
+	 */
146
+	private function doReset(User $user)
147
+	{
148
+		$pw = WebRequest::postString('pw');
149
+		$pw2 = WebRequest::postString('pw2');
150
+
151
+		if ($pw !== $pw2) {
152
+			throw new ApplicationLogicException('Passwords do not match!');
153
+		}
154
+
155
+		$user->setPassword($pw);
156
+		$user->save();
157
+
158
+		SessionAlert::success('You may now log in!');
159
+		$this->redirect('login');
160
+	}
161
+
162
+	/**
163
+	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
164
+	 * the return value from this function.
165
+	 *
166
+	 * If this page even supports actions, you will need to check the route
167
+	 *
168
+	 * @return SecurityConfiguration
169
+	 * @category Security-Critical
170
+	 */
171
+	protected function getSecurityConfiguration()
172
+	{
173
+		return $this->getSecurityManager()->configure()->asPublicPage();
174
+	}
175 175
 }
176 176
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/PageEditComment.php 1 patch
Indentation   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -21,86 +21,86 @@
 block discarded – undo
21 21
 
22 22
 class PageEditComment extends InternalPageBase
23 23
 {
24
-    /**
25
-     * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
26
-     * the return value from this function.
27
-     *
28
-     * If this page even supports actions, you will need to check the route
29
-     *
30
-     * @return SecurityConfiguration
31
-     * @category Security-Critical
32
-     */
33
-    protected function getSecurityConfiguration()
34
-    {
35
-        switch ($this->getRouteName()) {
36
-            case 'editOthers':
37
-                return $this->getSecurityManager()->configure()->asAdminPage();
38
-            default:
39
-                return $this->getSecurityManager()->configure()->asInternalPage();
40
-        }
41
-    }
42
-
43
-    /**
44
-     * Main function for this page, when no specific actions are called.
45
-     * @throws ApplicationLogicException
46
-     */
47
-    protected function main()
48
-    {
49
-        $commentId = WebRequest::getInt('id');
50
-        if ($commentId === null) {
51
-            throw new ApplicationLogicException('Comment ID not specified');
52
-        }
53
-
54
-        $database = $this->getDatabase();
55
-
56
-        /** @var Comment $comment */
57
-        $comment = Comment::getById($commentId, $database);
58
-        if ($comment === false) {
59
-            throw new ApplicationLogicException('Comment not found');
60
-        }
61
-
62
-        $currentUser = User::getCurrent($database);
63
-        if ($comment->getUser() !== $currentUser->getId() && !$this->barrierTest('editOthers')) {
64
-            throw new AccessDeniedException();
65
-        }
66
-
67
-        /** @var Request $request */
68
-        $request = Request::getById($comment->getRequest(), $database);
69
-
70
-        if ($request === false) {
71
-            throw new ApplicationLogicException('Request was not found.');
72
-        }
73
-
74
-        if (WebRequest::wasPosted()) {
75
-            $this->validateCSRFToken();
76
-            $newComment = WebRequest::postString('newcomment');
77
-            $visibility = WebRequest::postString('visibility');
78
-
79
-            if ($visibility !== 'user' && $visibility !== 'admin') {
80
-                throw new ApplicationLogicException('Comment visibility is not valid');
81
-            }
82
-
83
-            // optimisticly lock from the load of the edit comment form
84
-            $updateVersion = WebRequest::postInt('updateversion');
85
-            $comment->setUpdateVersion($updateVersion);
86
-
87
-            $comment->setComment($newComment);
88
-            $comment->setVisibility($visibility);
89
-
90
-            $comment->save();
91
-
92
-            Logger::editComment($database, $comment, $request);
93
-            $this->getNotificationHelper()->commentEdited($comment, $request);
94
-            SessionAlert::success("Comment has been saved successfully");
95
-
96
-            $this->redirect('viewRequest', null, array('id' => $comment->getRequest()));
97
-        }
98
-        else {
99
-            $this->assignCSRFToken();
100
-            $this->assign('comment', $comment);
101
-            $this->assign('request', $request);
102
-            $this->assign('user', User::getById($comment->getUser(), $database));
103
-            $this->setTemplate('edit-comment.tpl');
104
-        }
105
-    }
24
+	/**
25
+	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
26
+	 * the return value from this function.
27
+	 *
28
+	 * If this page even supports actions, you will need to check the route
29
+	 *
30
+	 * @return SecurityConfiguration
31
+	 * @category Security-Critical
32
+	 */
33
+	protected function getSecurityConfiguration()
34
+	{
35
+		switch ($this->getRouteName()) {
36
+			case 'editOthers':
37
+				return $this->getSecurityManager()->configure()->asAdminPage();
38
+			default:
39
+				return $this->getSecurityManager()->configure()->asInternalPage();
40
+		}
41
+	}
42
+
43
+	/**
44
+	 * Main function for this page, when no specific actions are called.
45
+	 * @throws ApplicationLogicException
46
+	 */
47
+	protected function main()
48
+	{
49
+		$commentId = WebRequest::getInt('id');
50
+		if ($commentId === null) {
51
+			throw new ApplicationLogicException('Comment ID not specified');
52
+		}
53
+
54
+		$database = $this->getDatabase();
55
+
56
+		/** @var Comment $comment */
57
+		$comment = Comment::getById($commentId, $database);
58
+		if ($comment === false) {
59
+			throw new ApplicationLogicException('Comment not found');
60
+		}
61
+
62
+		$currentUser = User::getCurrent($database);
63
+		if ($comment->getUser() !== $currentUser->getId() && !$this->barrierTest('editOthers')) {
64
+			throw new AccessDeniedException();
65
+		}
66
+
67
+		/** @var Request $request */
68
+		$request = Request::getById($comment->getRequest(), $database);
69
+
70
+		if ($request === false) {
71
+			throw new ApplicationLogicException('Request was not found.');
72
+		}
73
+
74
+		if (WebRequest::wasPosted()) {
75
+			$this->validateCSRFToken();
76
+			$newComment = WebRequest::postString('newcomment');
77
+			$visibility = WebRequest::postString('visibility');
78
+
79
+			if ($visibility !== 'user' && $visibility !== 'admin') {
80
+				throw new ApplicationLogicException('Comment visibility is not valid');
81
+			}
82
+
83
+			// optimisticly lock from the load of the edit comment form
84
+			$updateVersion = WebRequest::postInt('updateversion');
85
+			$comment->setUpdateVersion($updateVersion);
86
+
87
+			$comment->setComment($newComment);
88
+			$comment->setVisibility($visibility);
89
+
90
+			$comment->save();
91
+
92
+			Logger::editComment($database, $comment, $request);
93
+			$this->getNotificationHelper()->commentEdited($comment, $request);
94
+			SessionAlert::success("Comment has been saved successfully");
95
+
96
+			$this->redirect('viewRequest', null, array('id' => $comment->getRequest()));
97
+		}
98
+		else {
99
+			$this->assignCSRFToken();
100
+			$this->assign('comment', $comment);
101
+			$this->assign('request', $request);
102
+			$this->assign('user', User::getById($comment->getUser(), $database));
103
+			$this->setTemplate('edit-comment.tpl');
104
+		}
105
+	}
106 106
 }
107 107
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/PageUserManagement.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
             Logger::suspendedUser($database, $user, $reason);
100 100
 
101 101
             $this->getNotificationHelper()->userSuspended($user, $reason);
102
-            SessionAlert::quick('Suspended user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
102
+            SessionAlert::quick('Suspended user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
103 103
 
104 104
             // send email
105 105
             $this->sendStatusChangeEmail(
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
             Logger::declinedUser($database, $user, $reason);
161 161
 
162 162
             $this->getNotificationHelper()->userDeclined($user, $reason);
163
-            SessionAlert::quick('Declined user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
163
+            SessionAlert::quick('Declined user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
164 164
 
165 165
             // send email
166 166
             $this->sendStatusChangeEmail(
@@ -221,7 +221,7 @@  discard block
 block discarded – undo
221 221
             Logger::demotedUser($database, $user, $reason);
222 222
 
223 223
             $this->getNotificationHelper()->userDemoted($user, $reason);
224
-            SessionAlert::quick('Demoted user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
224
+            SessionAlert::quick('Demoted user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
225 225
 
226 226
             // send email
227 227
             $this->sendStatusChangeEmail(
@@ -276,7 +276,7 @@  discard block
 block discarded – undo
276 276
             Logger::approvedUser($database, $user);
277 277
 
278 278
             $this->getNotificationHelper()->userApproved($user);
279
-            SessionAlert::quick('Approved user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
279
+            SessionAlert::quick('Approved user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
280 280
 
281 281
             // send email
282 282
             $this->sendStatusChangeEmail(
@@ -331,7 +331,7 @@  discard block
 block discarded – undo
331 331
             Logger::promotedUser($database, $user);
332 332
 
333 333
             $this->getNotificationHelper()->userPromoted($user);
334
-            SessionAlert::quick('Promoted user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
334
+            SessionAlert::quick('Promoted user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
335 335
 
336 336
             // send email
337 337
             $this->sendStatusChangeEmail(
Please login to merge, or discard this patch.
Indentation   +508 added lines, -508 removed lines patch added patch discarded remove patch
@@ -22,512 +22,512 @@
 block discarded – undo
22 22
  */
23 23
 class PageUserManagement extends InternalPageBase
24 24
 {
25
-    /** @var string */
26
-    private $adminMailingList = '[email protected]';
27
-
28
-    /**
29
-     * Main function for this page, when no specific actions are called.
30
-     */
31
-    protected function main()
32
-    {
33
-        $this->setHtmlTitle('User Management');
34
-
35
-        $database = $this->getDatabase();
36
-
37
-        if (WebRequest::getBoolean("showAll")) {
38
-            $this->assign("showAll", true);
39
-
40
-            $this->assign("suspendedUsers", User::getAllWithStatus(User::STATUS_SUSPENDED, $database));
41
-            $this->assign("declinedUsers", User::getAllWithStatus(User::STATUS_DECLINED, $database));
42
-        }
43
-        else {
44
-            $this->assign("showAll", false);
45
-            $this->assign("suspendedUsers", array());
46
-            $this->assign("declinedUsers", array());
47
-        }
48
-
49
-        $this->assign("newUsers", User::getAllWithStatus(User::STATUS_NEW, $database));
50
-        $this->assign("normalUsers", User::getAllWithStatus(User::STATUS_USER, $database));
51
-        $this->assign("adminUsers", User::getAllWithStatus(User::STATUS_ADMIN, $database));
52
-        $this->assign("checkUsers", User::getAllCheckusers($database));
53
-
54
-        $this->getTypeAheadHelper()->defineTypeAheadSource('username-typeahead', function() use ($database) {
55
-            return User::getAllUsernames($database);
56
-        });
57
-
58
-        $this->setTemplate("usermanagement/main.tpl");
59
-    }
60
-
61
-    #region Access control
62
-
63
-    /**
64
-     * Action target for suspending users
65
-     *
66
-     * @throws ApplicationLogicException
67
-     */
68
-    protected function suspend()
69
-    {
70
-        $this->setHtmlTitle('User Management');
71
-
72
-        $database = $this->getDatabase();
73
-
74
-        $userId = WebRequest::getInt('user');
75
-
76
-        /** @var User $user */
77
-        $user = User::getById($userId, $database);
78
-
79
-        if ($user === false) {
80
-            throw new ApplicationLogicException('Sorry, the user you are trying to suspend could not be found.');
81
-        }
82
-
83
-        if ($user->isSuspended()) {
84
-            throw new ApplicationLogicException('Sorry, the user you are trying to suspend is already suspended.');
85
-        }
86
-
87
-        // Dual-mode action
88
-        if (WebRequest::wasPosted()) {
89
-            $this->validateCSRFToken();
90
-            $reason = WebRequest::postString('reason');
91
-
92
-            if ($reason === null || trim($reason) === "") {
93
-                throw new ApplicationLogicException('No reason provided');
94
-            }
95
-
96
-            $user->setStatus(User::STATUS_SUSPENDED);
97
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
98
-            $user->save();
99
-            Logger::suspendedUser($database, $user, $reason);
100
-
101
-            $this->getNotificationHelper()->userSuspended($user, $reason);
102
-            SessionAlert::quick('Suspended user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
103
-
104
-            // send email
105
-            $this->sendStatusChangeEmail(
106
-                'Your WP:ACC account has been suspended',
107
-                'usermanagement/emails/suspended.tpl',
108
-                $reason,
109
-                $user,
110
-                User::getCurrent($database)->getUsername()
111
-            );
112
-
113
-            $this->redirect('userManagement');
114
-
115
-            return;
116
-        }
117
-        else {
118
-            $this->assignCSRFToken();
119
-            $this->setTemplate('usermanagement/changelevel-reason.tpl');
120
-            $this->assign('user', $user);
121
-            $this->assign('status', 'Suspended');
122
-            $this->assign("showReason", true);
123
-        }
124
-    }
125
-
126
-    /**
127
-     * Entry point for the decline action
128
-     *
129
-     * @throws ApplicationLogicException
130
-     */
131
-    protected function decline()
132
-    {
133
-        $this->setHtmlTitle('User Management');
134
-
135
-        $database = $this->getDatabase();
136
-
137
-        $userId = WebRequest::getInt('user');
138
-        $user = User::getById($userId, $database);
139
-
140
-        if ($user === false) {
141
-            throw new ApplicationLogicException('Sorry, the user you are trying to decline could not be found.');
142
-        }
143
-
144
-        if (!$user->isNewUser()) {
145
-            throw new ApplicationLogicException('Sorry, the user you are trying to decline is not new.');
146
-        }
147
-
148
-        // Dual-mode action
149
-        if (WebRequest::wasPosted()) {
150
-            $this->validateCSRFToken();
151
-            $reason = WebRequest::postString('reason');
152
-
153
-            if ($reason === null || trim($reason) === "") {
154
-                throw new ApplicationLogicException('No reason provided');
155
-            }
156
-
157
-            $user->setStatus(User::STATUS_DECLINED);
158
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
159
-            $user->save();
160
-            Logger::declinedUser($database, $user, $reason);
161
-
162
-            $this->getNotificationHelper()->userDeclined($user, $reason);
163
-            SessionAlert::quick('Declined user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
164
-
165
-            // send email
166
-            $this->sendStatusChangeEmail(
167
-                'Your WP:ACC account has been declined',
168
-                'usermanagement/emails/declined.tpl',
169
-                $reason,
170
-                $user,
171
-                User::getCurrent($database)->getUsername()
172
-            );
173
-
174
-            $this->redirect('userManagement');
175
-
176
-            return;
177
-        }
178
-        else {
179
-            $this->assignCSRFToken();
180
-            $this->setTemplate('usermanagement/changelevel-reason.tpl');
181
-            $this->assign('user', $user);
182
-            $this->assign('status', 'Declined');
183
-            $this->assign("showReason", true);
184
-        }
185
-    }
186
-
187
-    /**
188
-     * Entry point for the demote action
189
-     *
190
-     * @throws ApplicationLogicException
191
-     */
192
-    protected function demote()
193
-    {
194
-        $this->setHtmlTitle('User Management');
195
-
196
-        $database = $this->getDatabase();
197
-
198
-        $userId = WebRequest::getInt('user');
199
-        $user = User::getById($userId, $database);
200
-
201
-        if ($user === false) {
202
-            throw new ApplicationLogicException('Sorry, the user you are trying to demote could not be found.');
203
-        }
204
-
205
-        if (!$user->isAdmin()) {
206
-            throw new ApplicationLogicException('Sorry, the user you are trying to demote is not an admin.');
207
-        }
208
-
209
-        // Dual-mode action
210
-        if (WebRequest::wasPosted()) {
211
-            $this->validateCSRFToken();
212
-            $reason = WebRequest::postString('reason');
213
-
214
-            if ($reason === null || trim($reason) === "") {
215
-                throw new ApplicationLogicException('No reason provided');
216
-            }
217
-
218
-            $user->setStatus(User::STATUS_USER);
219
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
220
-            $user->save();
221
-            Logger::demotedUser($database, $user, $reason);
222
-
223
-            $this->getNotificationHelper()->userDemoted($user, $reason);
224
-            SessionAlert::quick('Demoted user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
225
-
226
-            // send email
227
-            $this->sendStatusChangeEmail(
228
-                'Your WP:ACC account has been demoted',
229
-                'usermanagement/emails/demoted.tpl',
230
-                $reason,
231
-                $user,
232
-                User::getCurrent($database)->getUsername()
233
-            );
234
-
235
-            $this->redirect('userManagement');
236
-
237
-            return;
238
-        }
239
-        else {
240
-            $this->assignCSRFToken();
241
-            $this->setTemplate('usermanagement/changelevel-reason.tpl');
242
-            $this->assign('user', $user);
243
-            $this->assign('status', 'User');
244
-            $this->assign("showReason", true);
245
-        }
246
-    }
247
-
248
-    /**
249
-     * Entry point for the approve action
250
-     *
251
-     * @throws ApplicationLogicException
252
-     */
253
-    protected function approve()
254
-    {
255
-        $this->setHtmlTitle('User Management');
256
-
257
-        $database = $this->getDatabase();
258
-
259
-        $userId = WebRequest::getInt('user');
260
-        $user = User::getById($userId, $database);
261
-
262
-        if ($user === false) {
263
-            throw new ApplicationLogicException('Sorry, the user you are trying to approve could not be found.');
264
-        }
265
-
266
-        if ($user->isUser() || $user->isAdmin()) {
267
-            throw new ApplicationLogicException('Sorry, the user you are trying to approve is already an active user.');
268
-        }
269
-
270
-        // Dual-mode action
271
-        if (WebRequest::wasPosted()) {
272
-            $this->validateCSRFToken();
273
-            $user->setStatus(User::STATUS_USER);
274
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
275
-            $user->save();
276
-            Logger::approvedUser($database, $user);
277
-
278
-            $this->getNotificationHelper()->userApproved($user);
279
-            SessionAlert::quick('Approved user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
280
-
281
-            // send email
282
-            $this->sendStatusChangeEmail(
283
-                'Your WP:ACC account has been approved',
284
-                'usermanagement/emails/approved.tpl',
285
-                null,
286
-                $user,
287
-                User::getCurrent($database)->getUsername()
288
-            );
289
-
290
-            $this->redirect("userManagement");
291
-
292
-            return;
293
-        }
294
-        else {
295
-            $this->assignCSRFToken();
296
-            $this->setTemplate("usermanagement/changelevel-reason.tpl");
297
-            $this->assign("user", $user);
298
-            $this->assign("status", "User");
299
-            $this->assign("showReason", false);
300
-        }
301
-    }
302
-
303
-    /**
304
-     * Entry point for the promote action
305
-     *
306
-     * @throws ApplicationLogicException
307
-     */
308
-    protected function promote()
309
-    {
310
-        $this->setHtmlTitle('User Management');
311
-
312
-        $database = $this->getDatabase();
313
-
314
-        $userId = WebRequest::getInt('user');
315
-        $user = User::getById($userId, $database);
316
-
317
-        if ($user === false) {
318
-            throw new ApplicationLogicException('Sorry, the user you are trying to promote could not be found.');
319
-        }
320
-
321
-        if ($user->isAdmin()) {
322
-            throw new ApplicationLogicException('Sorry, the user you are trying to promote is already an admin.');
323
-        }
324
-
325
-        // Dual-mode action
326
-        if (WebRequest::wasPosted()) {
327
-            $this->validateCSRFToken();
328
-            $user->setStatus(User::STATUS_ADMIN);
329
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
330
-            $user->save();
331
-            Logger::promotedUser($database, $user);
332
-
333
-            $this->getNotificationHelper()->userPromoted($user);
334
-            SessionAlert::quick('Promoted user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
335
-
336
-            // send email
337
-            $this->sendStatusChangeEmail(
338
-                'Your WP:ACC account has been promoted',
339
-                'usermanagement/emails/promoted.tpl',
340
-                null,
341
-                $user,
342
-                User::getCurrent($database)->getUsername()
343
-            );
344
-
345
-            $this->redirect("userManagement");
346
-
347
-            return;
348
-        }
349
-        else {
350
-            $this->assignCSRFToken();
351
-            $this->setTemplate("usermanagement/changelevel-reason.tpl");
352
-            $this->assign("user", $user);
353
-            $this->assign("status", "Admin");
354
-            $this->assign("showReason", false);
355
-        }
356
-    }
357
-
358
-    #endregion
359
-
360
-    #region Renaming / Editing
361
-
362
-    /**
363
-     * Entry point for the rename action
364
-     *
365
-     * @throws ApplicationLogicException
366
-     */
367
-    protected function rename()
368
-    {
369
-        $this->setHtmlTitle('User Management');
370
-
371
-        $database = $this->getDatabase();
372
-
373
-        $userId = WebRequest::getInt('user');
374
-        $user = User::getById($userId, $database);
375
-
376
-        if ($user === false) {
377
-            throw new ApplicationLogicException('Sorry, the user you are trying to rename could not be found.');
378
-        }
379
-
380
-        // Dual-mode action
381
-        if (WebRequest::wasPosted()) {
382
-            $this->validateCSRFToken();
383
-            $newUsername = WebRequest::postString('newname');
384
-
385
-            if ($newUsername === null || trim($newUsername) === "") {
386
-                throw new ApplicationLogicException('The new username cannot be empty');
387
-            }
388
-
389
-            if (User::getByUsername($newUsername, $database) != false) {
390
-                throw new ApplicationLogicException('The new username already exists');
391
-            }
392
-
393
-            $oldUsername = $user->getUsername();
394
-            $user->setUsername($newUsername);
395
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
396
-
397
-            $user->save();
398
-
399
-            $logEntryData = serialize(array(
400
-                'old' => $oldUsername,
401
-                'new' => $newUsername,
402
-            ));
403
-
404
-            Logger::renamedUser($database, $user, $logEntryData);
405
-
406
-            SessionAlert::quick("Changed User "
407
-                . htmlentities($oldUsername, ENT_COMPAT, 'UTF-8')
408
-                . " name to "
409
-                . htmlentities($newUsername, ENT_COMPAT, 'UTF-8'));
410
-
411
-            $this->getNotificationHelper()->userRenamed($user, $oldUsername);
412
-
413
-            // send an email to the user.
414
-            $this->assign('targetUsername', $user->getUsername());
415
-            $this->assign('toolAdmin', User::getCurrent($database)->getUsername());
416
-            $this->assign('oldUsername', $oldUsername);
417
-            $this->assign('mailingList', $this->adminMailingList);
418
-
419
-            $this->getEmailHelper()->sendMail(
420
-                $user->getEmail(),
421
-                'Your username on WP:ACC has been changed',
422
-                $this->fetchTemplate('usermanagement/emails/renamed.tpl'),
423
-                array('Reply-To' => $this->adminMailingList)
424
-            );
425
-
426
-            $this->redirect("userManagement");
427
-
428
-            return;
429
-        }
430
-        else {
431
-            $this->assignCSRFToken();
432
-            $this->setTemplate('usermanagement/renameuser.tpl');
433
-            $this->assign('user', $user);
434
-        }
435
-    }
436
-
437
-    /**
438
-     * Entry point for the edit action
439
-     *
440
-     * @throws ApplicationLogicException
441
-     */
442
-    protected function editUser()
443
-    {
444
-        $this->setHtmlTitle('User Management');
445
-
446
-        $database = $this->getDatabase();
447
-
448
-        $userId = WebRequest::getInt('user');
449
-        $user = User::getById($userId, $database);
450
-
451
-        if ($user === false) {
452
-            throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
453
-        }
454
-
455
-        // Dual-mode action
456
-        if (WebRequest::wasPosted()) {
457
-            $this->validateCSRFToken();
458
-            $newEmail = WebRequest::postEmail('user_email');
459
-            $newOnWikiName = WebRequest::postString('user_onwikiname');
460
-
461
-            if ($newEmail === null) {
462
-                throw new ApplicationLogicException('Invalid email address');
463
-            }
464
-
465
-            if (!$user->isOAuthLinked()) {
466
-                if (trim($newOnWikiName) == "") {
467
-                    throw new ApplicationLogicException('New on-wiki username cannot be blank');
468
-                }
469
-
470
-                $user->setOnWikiName($newOnWikiName);
471
-            }
472
-
473
-            $user->setEmail($newEmail);
474
-
475
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
476
-
477
-            $user->save();
478
-
479
-            Logger::userPreferencesChange($database, $user);
480
-            $this->getNotificationHelper()->userPrefChange($user);
481
-            SessionAlert::quick('Changes to user\'s preferences have been saved');
482
-
483
-            $this->redirect("userManagement");
484
-
485
-            return;
486
-        }
487
-        else {
488
-            $this->assignCSRFToken();
489
-            $this->setTemplate('usermanagement/edituser.tpl');
490
-            $this->assign('user', $user);
491
-        }
492
-    }
493
-
494
-    #endregion
495
-
496
-    /**
497
-     * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
498
-     * the return value from this function.
499
-     *
500
-     * If this page even supports actions, you will need to check the route
501
-     *
502
-     * @return SecurityConfiguration
503
-     * @category Security-Critical
504
-     */
505
-    protected function getSecurityConfiguration()
506
-    {
507
-        return $this->getSecurityManager()->configure()->asAdminPage();
508
-    }
509
-
510
-    /**
511
-     * Sends a status change email to the user.
512
-     *
513
-     * @param string      $subject           The subject of the email
514
-     * @param string      $template          The smarty template to use
515
-     * @param string|null $reason            The reason for performing the status change
516
-     * @param User        $user              The user affected
517
-     * @param string      $toolAdminUsername The tool admin's username who is making the edit
518
-     */
519
-    private function sendStatusChangeEmail($subject, $template, $reason, $user, $toolAdminUsername)
520
-    {
521
-        $this->assign('targetUsername', $user->getUsername());
522
-        $this->assign('toolAdmin', $toolAdminUsername);
523
-        $this->assign('actionReason', $reason);
524
-        $this->assign('mailingList', $this->adminMailingList);
525
-
526
-        $this->getEmailHelper()->sendMail(
527
-            $user->getEmail(),
528
-            $subject,
529
-            $this->fetchTemplate($template),
530
-            array('Reply-To' => $this->adminMailingList)
531
-        );
532
-    }
25
+	/** @var string */
26
+	private $adminMailingList = '[email protected]';
27
+
28
+	/**
29
+	 * Main function for this page, when no specific actions are called.
30
+	 */
31
+	protected function main()
32
+	{
33
+		$this->setHtmlTitle('User Management');
34
+
35
+		$database = $this->getDatabase();
36
+
37
+		if (WebRequest::getBoolean("showAll")) {
38
+			$this->assign("showAll", true);
39
+
40
+			$this->assign("suspendedUsers", User::getAllWithStatus(User::STATUS_SUSPENDED, $database));
41
+			$this->assign("declinedUsers", User::getAllWithStatus(User::STATUS_DECLINED, $database));
42
+		}
43
+		else {
44
+			$this->assign("showAll", false);
45
+			$this->assign("suspendedUsers", array());
46
+			$this->assign("declinedUsers", array());
47
+		}
48
+
49
+		$this->assign("newUsers", User::getAllWithStatus(User::STATUS_NEW, $database));
50
+		$this->assign("normalUsers", User::getAllWithStatus(User::STATUS_USER, $database));
51
+		$this->assign("adminUsers", User::getAllWithStatus(User::STATUS_ADMIN, $database));
52
+		$this->assign("checkUsers", User::getAllCheckusers($database));
53
+
54
+		$this->getTypeAheadHelper()->defineTypeAheadSource('username-typeahead', function() use ($database) {
55
+			return User::getAllUsernames($database);
56
+		});
57
+
58
+		$this->setTemplate("usermanagement/main.tpl");
59
+	}
60
+
61
+	#region Access control
62
+
63
+	/**
64
+	 * Action target for suspending users
65
+	 *
66
+	 * @throws ApplicationLogicException
67
+	 */
68
+	protected function suspend()
69
+	{
70
+		$this->setHtmlTitle('User Management');
71
+
72
+		$database = $this->getDatabase();
73
+
74
+		$userId = WebRequest::getInt('user');
75
+
76
+		/** @var User $user */
77
+		$user = User::getById($userId, $database);
78
+
79
+		if ($user === false) {
80
+			throw new ApplicationLogicException('Sorry, the user you are trying to suspend could not be found.');
81
+		}
82
+
83
+		if ($user->isSuspended()) {
84
+			throw new ApplicationLogicException('Sorry, the user you are trying to suspend is already suspended.');
85
+		}
86
+
87
+		// Dual-mode action
88
+		if (WebRequest::wasPosted()) {
89
+			$this->validateCSRFToken();
90
+			$reason = WebRequest::postString('reason');
91
+
92
+			if ($reason === null || trim($reason) === "") {
93
+				throw new ApplicationLogicException('No reason provided');
94
+			}
95
+
96
+			$user->setStatus(User::STATUS_SUSPENDED);
97
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
98
+			$user->save();
99
+			Logger::suspendedUser($database, $user, $reason);
100
+
101
+			$this->getNotificationHelper()->userSuspended($user, $reason);
102
+			SessionAlert::quick('Suspended user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
103
+
104
+			// send email
105
+			$this->sendStatusChangeEmail(
106
+				'Your WP:ACC account has been suspended',
107
+				'usermanagement/emails/suspended.tpl',
108
+				$reason,
109
+				$user,
110
+				User::getCurrent($database)->getUsername()
111
+			);
112
+
113
+			$this->redirect('userManagement');
114
+
115
+			return;
116
+		}
117
+		else {
118
+			$this->assignCSRFToken();
119
+			$this->setTemplate('usermanagement/changelevel-reason.tpl');
120
+			$this->assign('user', $user);
121
+			$this->assign('status', 'Suspended');
122
+			$this->assign("showReason", true);
123
+		}
124
+	}
125
+
126
+	/**
127
+	 * Entry point for the decline action
128
+	 *
129
+	 * @throws ApplicationLogicException
130
+	 */
131
+	protected function decline()
132
+	{
133
+		$this->setHtmlTitle('User Management');
134
+
135
+		$database = $this->getDatabase();
136
+
137
+		$userId = WebRequest::getInt('user');
138
+		$user = User::getById($userId, $database);
139
+
140
+		if ($user === false) {
141
+			throw new ApplicationLogicException('Sorry, the user you are trying to decline could not be found.');
142
+		}
143
+
144
+		if (!$user->isNewUser()) {
145
+			throw new ApplicationLogicException('Sorry, the user you are trying to decline is not new.');
146
+		}
147
+
148
+		// Dual-mode action
149
+		if (WebRequest::wasPosted()) {
150
+			$this->validateCSRFToken();
151
+			$reason = WebRequest::postString('reason');
152
+
153
+			if ($reason === null || trim($reason) === "") {
154
+				throw new ApplicationLogicException('No reason provided');
155
+			}
156
+
157
+			$user->setStatus(User::STATUS_DECLINED);
158
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
159
+			$user->save();
160
+			Logger::declinedUser($database, $user, $reason);
161
+
162
+			$this->getNotificationHelper()->userDeclined($user, $reason);
163
+			SessionAlert::quick('Declined user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
164
+
165
+			// send email
166
+			$this->sendStatusChangeEmail(
167
+				'Your WP:ACC account has been declined',
168
+				'usermanagement/emails/declined.tpl',
169
+				$reason,
170
+				$user,
171
+				User::getCurrent($database)->getUsername()
172
+			);
173
+
174
+			$this->redirect('userManagement');
175
+
176
+			return;
177
+		}
178
+		else {
179
+			$this->assignCSRFToken();
180
+			$this->setTemplate('usermanagement/changelevel-reason.tpl');
181
+			$this->assign('user', $user);
182
+			$this->assign('status', 'Declined');
183
+			$this->assign("showReason", true);
184
+		}
185
+	}
186
+
187
+	/**
188
+	 * Entry point for the demote action
189
+	 *
190
+	 * @throws ApplicationLogicException
191
+	 */
192
+	protected function demote()
193
+	{
194
+		$this->setHtmlTitle('User Management');
195
+
196
+		$database = $this->getDatabase();
197
+
198
+		$userId = WebRequest::getInt('user');
199
+		$user = User::getById($userId, $database);
200
+
201
+		if ($user === false) {
202
+			throw new ApplicationLogicException('Sorry, the user you are trying to demote could not be found.');
203
+		}
204
+
205
+		if (!$user->isAdmin()) {
206
+			throw new ApplicationLogicException('Sorry, the user you are trying to demote is not an admin.');
207
+		}
208
+
209
+		// Dual-mode action
210
+		if (WebRequest::wasPosted()) {
211
+			$this->validateCSRFToken();
212
+			$reason = WebRequest::postString('reason');
213
+
214
+			if ($reason === null || trim($reason) === "") {
215
+				throw new ApplicationLogicException('No reason provided');
216
+			}
217
+
218
+			$user->setStatus(User::STATUS_USER);
219
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
220
+			$user->save();
221
+			Logger::demotedUser($database, $user, $reason);
222
+
223
+			$this->getNotificationHelper()->userDemoted($user, $reason);
224
+			SessionAlert::quick('Demoted user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
225
+
226
+			// send email
227
+			$this->sendStatusChangeEmail(
228
+				'Your WP:ACC account has been demoted',
229
+				'usermanagement/emails/demoted.tpl',
230
+				$reason,
231
+				$user,
232
+				User::getCurrent($database)->getUsername()
233
+			);
234
+
235
+			$this->redirect('userManagement');
236
+
237
+			return;
238
+		}
239
+		else {
240
+			$this->assignCSRFToken();
241
+			$this->setTemplate('usermanagement/changelevel-reason.tpl');
242
+			$this->assign('user', $user);
243
+			$this->assign('status', 'User');
244
+			$this->assign("showReason", true);
245
+		}
246
+	}
247
+
248
+	/**
249
+	 * Entry point for the approve action
250
+	 *
251
+	 * @throws ApplicationLogicException
252
+	 */
253
+	protected function approve()
254
+	{
255
+		$this->setHtmlTitle('User Management');
256
+
257
+		$database = $this->getDatabase();
258
+
259
+		$userId = WebRequest::getInt('user');
260
+		$user = User::getById($userId, $database);
261
+
262
+		if ($user === false) {
263
+			throw new ApplicationLogicException('Sorry, the user you are trying to approve could not be found.');
264
+		}
265
+
266
+		if ($user->isUser() || $user->isAdmin()) {
267
+			throw new ApplicationLogicException('Sorry, the user you are trying to approve is already an active user.');
268
+		}
269
+
270
+		// Dual-mode action
271
+		if (WebRequest::wasPosted()) {
272
+			$this->validateCSRFToken();
273
+			$user->setStatus(User::STATUS_USER);
274
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
275
+			$user->save();
276
+			Logger::approvedUser($database, $user);
277
+
278
+			$this->getNotificationHelper()->userApproved($user);
279
+			SessionAlert::quick('Approved user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
280
+
281
+			// send email
282
+			$this->sendStatusChangeEmail(
283
+				'Your WP:ACC account has been approved',
284
+				'usermanagement/emails/approved.tpl',
285
+				null,
286
+				$user,
287
+				User::getCurrent($database)->getUsername()
288
+			);
289
+
290
+			$this->redirect("userManagement");
291
+
292
+			return;
293
+		}
294
+		else {
295
+			$this->assignCSRFToken();
296
+			$this->setTemplate("usermanagement/changelevel-reason.tpl");
297
+			$this->assign("user", $user);
298
+			$this->assign("status", "User");
299
+			$this->assign("showReason", false);
300
+		}
301
+	}
302
+
303
+	/**
304
+	 * Entry point for the promote action
305
+	 *
306
+	 * @throws ApplicationLogicException
307
+	 */
308
+	protected function promote()
309
+	{
310
+		$this->setHtmlTitle('User Management');
311
+
312
+		$database = $this->getDatabase();
313
+
314
+		$userId = WebRequest::getInt('user');
315
+		$user = User::getById($userId, $database);
316
+
317
+		if ($user === false) {
318
+			throw new ApplicationLogicException('Sorry, the user you are trying to promote could not be found.');
319
+		}
320
+
321
+		if ($user->isAdmin()) {
322
+			throw new ApplicationLogicException('Sorry, the user you are trying to promote is already an admin.');
323
+		}
324
+
325
+		// Dual-mode action
326
+		if (WebRequest::wasPosted()) {
327
+			$this->validateCSRFToken();
328
+			$user->setStatus(User::STATUS_ADMIN);
329
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
330
+			$user->save();
331
+			Logger::promotedUser($database, $user);
332
+
333
+			$this->getNotificationHelper()->userPromoted($user);
334
+			SessionAlert::quick('Promoted user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
335
+
336
+			// send email
337
+			$this->sendStatusChangeEmail(
338
+				'Your WP:ACC account has been promoted',
339
+				'usermanagement/emails/promoted.tpl',
340
+				null,
341
+				$user,
342
+				User::getCurrent($database)->getUsername()
343
+			);
344
+
345
+			$this->redirect("userManagement");
346
+
347
+			return;
348
+		}
349
+		else {
350
+			$this->assignCSRFToken();
351
+			$this->setTemplate("usermanagement/changelevel-reason.tpl");
352
+			$this->assign("user", $user);
353
+			$this->assign("status", "Admin");
354
+			$this->assign("showReason", false);
355
+		}
356
+	}
357
+
358
+	#endregion
359
+
360
+	#region Renaming / Editing
361
+
362
+	/**
363
+	 * Entry point for the rename action
364
+	 *
365
+	 * @throws ApplicationLogicException
366
+	 */
367
+	protected function rename()
368
+	{
369
+		$this->setHtmlTitle('User Management');
370
+
371
+		$database = $this->getDatabase();
372
+
373
+		$userId = WebRequest::getInt('user');
374
+		$user = User::getById($userId, $database);
375
+
376
+		if ($user === false) {
377
+			throw new ApplicationLogicException('Sorry, the user you are trying to rename could not be found.');
378
+		}
379
+
380
+		// Dual-mode action
381
+		if (WebRequest::wasPosted()) {
382
+			$this->validateCSRFToken();
383
+			$newUsername = WebRequest::postString('newname');
384
+
385
+			if ($newUsername === null || trim($newUsername) === "") {
386
+				throw new ApplicationLogicException('The new username cannot be empty');
387
+			}
388
+
389
+			if (User::getByUsername($newUsername, $database) != false) {
390
+				throw new ApplicationLogicException('The new username already exists');
391
+			}
392
+
393
+			$oldUsername = $user->getUsername();
394
+			$user->setUsername($newUsername);
395
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
396
+
397
+			$user->save();
398
+
399
+			$logEntryData = serialize(array(
400
+				'old' => $oldUsername,
401
+				'new' => $newUsername,
402
+			));
403
+
404
+			Logger::renamedUser($database, $user, $logEntryData);
405
+
406
+			SessionAlert::quick("Changed User "
407
+				. htmlentities($oldUsername, ENT_COMPAT, 'UTF-8')
408
+				. " name to "
409
+				. htmlentities($newUsername, ENT_COMPAT, 'UTF-8'));
410
+
411
+			$this->getNotificationHelper()->userRenamed($user, $oldUsername);
412
+
413
+			// send an email to the user.
414
+			$this->assign('targetUsername', $user->getUsername());
415
+			$this->assign('toolAdmin', User::getCurrent($database)->getUsername());
416
+			$this->assign('oldUsername', $oldUsername);
417
+			$this->assign('mailingList', $this->adminMailingList);
418
+
419
+			$this->getEmailHelper()->sendMail(
420
+				$user->getEmail(),
421
+				'Your username on WP:ACC has been changed',
422
+				$this->fetchTemplate('usermanagement/emails/renamed.tpl'),
423
+				array('Reply-To' => $this->adminMailingList)
424
+			);
425
+
426
+			$this->redirect("userManagement");
427
+
428
+			return;
429
+		}
430
+		else {
431
+			$this->assignCSRFToken();
432
+			$this->setTemplate('usermanagement/renameuser.tpl');
433
+			$this->assign('user', $user);
434
+		}
435
+	}
436
+
437
+	/**
438
+	 * Entry point for the edit action
439
+	 *
440
+	 * @throws ApplicationLogicException
441
+	 */
442
+	protected function editUser()
443
+	{
444
+		$this->setHtmlTitle('User Management');
445
+
446
+		$database = $this->getDatabase();
447
+
448
+		$userId = WebRequest::getInt('user');
449
+		$user = User::getById($userId, $database);
450
+
451
+		if ($user === false) {
452
+			throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
453
+		}
454
+
455
+		// Dual-mode action
456
+		if (WebRequest::wasPosted()) {
457
+			$this->validateCSRFToken();
458
+			$newEmail = WebRequest::postEmail('user_email');
459
+			$newOnWikiName = WebRequest::postString('user_onwikiname');
460
+
461
+			if ($newEmail === null) {
462
+				throw new ApplicationLogicException('Invalid email address');
463
+			}
464
+
465
+			if (!$user->isOAuthLinked()) {
466
+				if (trim($newOnWikiName) == "") {
467
+					throw new ApplicationLogicException('New on-wiki username cannot be blank');
468
+				}
469
+
470
+				$user->setOnWikiName($newOnWikiName);
471
+			}
472
+
473
+			$user->setEmail($newEmail);
474
+
475
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
476
+
477
+			$user->save();
478
+
479
+			Logger::userPreferencesChange($database, $user);
480
+			$this->getNotificationHelper()->userPrefChange($user);
481
+			SessionAlert::quick('Changes to user\'s preferences have been saved');
482
+
483
+			$this->redirect("userManagement");
484
+
485
+			return;
486
+		}
487
+		else {
488
+			$this->assignCSRFToken();
489
+			$this->setTemplate('usermanagement/edituser.tpl');
490
+			$this->assign('user', $user);
491
+		}
492
+	}
493
+
494
+	#endregion
495
+
496
+	/**
497
+	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
498
+	 * the return value from this function.
499
+	 *
500
+	 * If this page even supports actions, you will need to check the route
501
+	 *
502
+	 * @return SecurityConfiguration
503
+	 * @category Security-Critical
504
+	 */
505
+	protected function getSecurityConfiguration()
506
+	{
507
+		return $this->getSecurityManager()->configure()->asAdminPage();
508
+	}
509
+
510
+	/**
511
+	 * Sends a status change email to the user.
512
+	 *
513
+	 * @param string      $subject           The subject of the email
514
+	 * @param string      $template          The smarty template to use
515
+	 * @param string|null $reason            The reason for performing the status change
516
+	 * @param User        $user              The user affected
517
+	 * @param string      $toolAdminUsername The tool admin's username who is making the edit
518
+	 */
519
+	private function sendStatusChangeEmail($subject, $template, $reason, $user, $toolAdminUsername)
520
+	{
521
+		$this->assign('targetUsername', $user->getUsername());
522
+		$this->assign('toolAdmin', $toolAdminUsername);
523
+		$this->assign('actionReason', $reason);
524
+		$this->assign('mailingList', $this->adminMailingList);
525
+
526
+		$this->getEmailHelper()->sendMail(
527
+			$user->getEmail(),
528
+			$subject,
529
+			$this->fetchTemplate($template),
530
+			array('Reply-To' => $this->adminMailingList)
531
+		);
532
+	}
533 533
 }
534 534
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/PageMain.php 1 patch
Indentation   +89 added lines, -89 removed lines patch added patch discarded remove patch
@@ -16,71 +16,71 @@  discard block
 block discarded – undo
16 16
 
17 17
 class PageMain extends InternalPageBase
18 18
 {
19
-    /**
20
-     * Main function for this page, when no actions are called.
21
-     */
22
-    protected function main()
23
-    {
24
-        $this->assignCSRFToken();
25
-
26
-        $config = $this->getSiteConfiguration();
27
-
28
-        $database = $this->getDatabase();
29
-
30
-        $requestSectionData = array();
31
-
32
-        if ($config->getEmailConfirmationEnabled()) {
33
-            $query = "SELECT * FROM request WHERE status = :type AND emailconfirm = 'Confirmed' LIMIT :lim;";
34
-            $totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
35
-        }
36
-        else {
37
-            $query = "SELECT * FROM request WHERE status = :type LIMIT :lim;";
38
-            $totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type;";
39
-        }
40
-
41
-        $statement = $database->prepare($query);
42
-        $statement->bindValue(':lim', $config->getMiserModeLimit(), PDO::PARAM_INT);
43
-
44
-        $totalRequestsStatement = $database->prepare($totalQuery);
45
-
46
-        $this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
47
-
48
-        foreach ($config->getRequestStates() as $type => $v) {
49
-            $statement->bindValue(":type", $type);
50
-            $statement->execute();
51
-
52
-            $requests = $statement->fetchAll(PDO::FETCH_CLASS, Request::class);
53
-
54
-            /** @var Request $req */
55
-            foreach ($requests as $req) {
56
-                $req->setDatabase($database);
57
-            }
58
-
59
-            $totalRequestsStatement->bindValue(':type', $type);
60
-            $totalRequestsStatement->execute();
61
-            $totalRequests = $totalRequestsStatement->fetchColumn();
62
-            $totalRequestsStatement->closeCursor();
63
-
64
-            $userIds = array_map(
65
-                function(Request $entry) {
66
-                    return $entry->getReserved();
67
-                },
68
-                $requests);
69
-            $userList = User::getUsernames($userIds, $this->getDatabase());
70
-            $this->assign('userlist', $userList);
71
-
72
-            $requestSectionData[$v['header']] = array(
73
-                'requests' => $requests,
74
-                'total'    => $totalRequests,
75
-                'api'      => $v['api'],
76
-                'type'     => $type,
77
-                'userlist' => $userList,
78
-            );
79
-        }
80
-
81
-        $this->assign('requestLimitShowOnly', $config->getMiserModeLimit());
82
-
83
-        $query = <<<SQL
19
+	/**
20
+	 * Main function for this page, when no actions are called.
21
+	 */
22
+	protected function main()
23
+	{
24
+		$this->assignCSRFToken();
25
+
26
+		$config = $this->getSiteConfiguration();
27
+
28
+		$database = $this->getDatabase();
29
+
30
+		$requestSectionData = array();
31
+
32
+		if ($config->getEmailConfirmationEnabled()) {
33
+			$query = "SELECT * FROM request WHERE status = :type AND emailconfirm = 'Confirmed' LIMIT :lim;";
34
+			$totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
35
+		}
36
+		else {
37
+			$query = "SELECT * FROM request WHERE status = :type LIMIT :lim;";
38
+			$totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type;";
39
+		}
40
+
41
+		$statement = $database->prepare($query);
42
+		$statement->bindValue(':lim', $config->getMiserModeLimit(), PDO::PARAM_INT);
43
+
44
+		$totalRequestsStatement = $database->prepare($totalQuery);
45
+
46
+		$this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
47
+
48
+		foreach ($config->getRequestStates() as $type => $v) {
49
+			$statement->bindValue(":type", $type);
50
+			$statement->execute();
51
+
52
+			$requests = $statement->fetchAll(PDO::FETCH_CLASS, Request::class);
53
+
54
+			/** @var Request $req */
55
+			foreach ($requests as $req) {
56
+				$req->setDatabase($database);
57
+			}
58
+
59
+			$totalRequestsStatement->bindValue(':type', $type);
60
+			$totalRequestsStatement->execute();
61
+			$totalRequests = $totalRequestsStatement->fetchColumn();
62
+			$totalRequestsStatement->closeCursor();
63
+
64
+			$userIds = array_map(
65
+				function(Request $entry) {
66
+					return $entry->getReserved();
67
+				},
68
+				$requests);
69
+			$userList = User::getUsernames($userIds, $this->getDatabase());
70
+			$this->assign('userlist', $userList);
71
+
72
+			$requestSectionData[$v['header']] = array(
73
+				'requests' => $requests,
74
+				'total'    => $totalRequests,
75
+				'api'      => $v['api'],
76
+				'type'     => $type,
77
+				'userlist' => $userList,
78
+			);
79
+		}
80
+
81
+		$this->assign('requestLimitShowOnly', $config->getMiserModeLimit());
82
+
83
+		$query = <<<SQL
84 84
 		SELECT request.id, request.name, request.updateversion
85 85
 		FROM request /* PageMain::main() */
86 86
 		JOIN log ON log.objectid = request.id AND log.objecttype = 'Request'
@@ -89,28 +89,28 @@  discard block
 block discarded – undo
89 89
 		LIMIT 5;
90 90
 SQL;
91 91
 
92
-        $statement = $database->prepare($query);
93
-        $statement->execute();
94
-
95
-        $last5result = $statement->fetchAll(PDO::FETCH_ASSOC);
96
-
97
-        $this->assign('lastFive', $last5result);
98
-        $this->assign('requestSectionData', $requestSectionData);
99
-
100
-        $this->setTemplate('mainpage/mainpage.tpl');
101
-    }
102
-
103
-    /**
104
-     * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
105
-     * the return value from this function.
106
-     *
107
-     * If this page even supports actions, you will need to check the route
108
-     *
109
-     * @return SecurityConfiguration
110
-     * @category Security-Critical
111
-     */
112
-    protected function getSecurityConfiguration()
113
-    {
114
-        return $this->getSecurityManager()->configure()->asInternalPage();
115
-    }
92
+		$statement = $database->prepare($query);
93
+		$statement->execute();
94
+
95
+		$last5result = $statement->fetchAll(PDO::FETCH_ASSOC);
96
+
97
+		$this->assign('lastFive', $last5result);
98
+		$this->assign('requestSectionData', $requestSectionData);
99
+
100
+		$this->setTemplate('mainpage/mainpage.tpl');
101
+	}
102
+
103
+	/**
104
+	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
105
+	 * the return value from this function.
106
+	 *
107
+	 * If this page even supports actions, you will need to check the route
108
+	 *
109
+	 * @return SecurityConfiguration
110
+	 * @category Security-Critical
111
+	 */
112
+	protected function getSecurityConfiguration()
113
+	{
114
+		return $this->getSecurityManager()->configure()->asInternalPage();
115
+	}
116 116
 }
117 117
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/PageOAuth.php 1 patch
Indentation   +149 added lines, -149 removed lines patch added patch discarded remove patch
@@ -17,153 +17,153 @@
 block discarded – undo
17 17
 
18 18
 class PageOAuth extends InternalPageBase
19 19
 {
20
-    /**
21
-     * Attach entry point
22
-     *
23
-     * must be posted, or will redirect to preferences
24
-     */
25
-    protected function attach()
26
-    {
27
-        if (!WebRequest::wasPosted()) {
28
-            $this->redirect('preferences');
29
-
30
-            return;
31
-        }
32
-
33
-        $this->validateCSRFToken();
34
-
35
-        $oauthHelper = $this->getOAuthHelper();
36
-        $user = User::getCurrent($this->getDatabase());
37
-
38
-        $requestToken = $oauthHelper->getRequestToken();
39
-
40
-        $user->setOAuthRequestToken($requestToken->key);
41
-        $user->setOAuthRequestSecret($requestToken->secret);
42
-        $user->save();
43
-
44
-        $this->redirectUrl($oauthHelper->getAuthoriseUrl($requestToken->key));
45
-    }
46
-
47
-    /**
48
-     * Detach account entry point
49
-     */
50
-    protected function detach()
51
-    {
52
-        $user = User::getCurrent($this->getDatabase());
53
-
54
-        $user->setOnWikiName($user->getOnWikiName());
55
-        $user->setOAuthAccessSecret(null);
56
-        $user->setOAuthAccessToken(null);
57
-        $user->setOAuthRequestSecret(null);
58
-        $user->setOAuthRequestToken(null);
59
-
60
-        $user->clearOAuthData();
61
-
62
-        $user->setForcelogout(true);
63
-
64
-        $user->save();
65
-
66
-        // force the user to log out
67
-        Session::destroy();
68
-
69
-        $this->redirect('login');
70
-    }
71
-
72
-    /**
73
-     * Callback entry point
74
-     */
75
-    protected function callback()
76
-    {
77
-        $oauthToken = WebRequest::getString('oauth_token');
78
-        $oauthVerifier = WebRequest::getString('oauth_verifier');
79
-
80
-        $this->doCallbackValidation($oauthToken, $oauthVerifier);
81
-
82
-        $user = User::getByRequestToken($oauthToken, $this->getDatabase());
83
-        if ($user === false) {
84
-            throw new ApplicationLogicException('Token not found in store, please try again');
85
-        }
86
-
87
-        $accessToken = $this->getOAuthHelper()->callbackCompleted(
88
-            $user->getOAuthRequestToken(),
89
-            $user->getOAuthRequestSecret(),
90
-            $oauthVerifier);
91
-
92
-        $user->setOAuthRequestSecret(null);
93
-        $user->setOAuthRequestToken(null);
94
-        $user->setOAuthAccessToken($accessToken->key);
95
-        $user->setOAuthAccessSecret($accessToken->secret);
96
-
97
-        // @todo we really should stop doing this kind of thing... it adds performance bottlenecks and breaks 3NF
98
-        $user->setOnWikiName('##OAUTH##');
99
-
100
-        $user->save();
101
-
102
-        // OK, we're the same session that just did a partial login that was redirected to OAuth. Let's upgrade the
103
-        // login to a full login
104
-        if (WebRequest::getPartialLogin() === $user->getId()) {
105
-            WebRequest::setLoggedInUser($user);
106
-        }
107
-
108
-        // My thinking is there are three cases here:
109
-        //   a) new user => redirect to prefs - it's the only thing they can access other than stats
110
-        //   b) existing user hit the connect button in prefs => redirect to prefs since it's where they were
111
-        //   c) existing user logging in => redirect to wherever they came from
112
-        $redirectDestination = WebRequest::clearPostLoginRedirect();
113
-        if ($redirectDestination !== null && !$user->isNewUser()) {
114
-            $this->redirectUrl($redirectDestination);
115
-        }
116
-        else {
117
-            $this->redirect('preferences', null, null, 'internal.php');
118
-        }
119
-    }
120
-
121
-    /**
122
-     * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
123
-     * the return value from this function.
124
-     *
125
-     * If this page even supports actions, you will need to check the route
126
-     *
127
-     * @return SecurityConfiguration
128
-     * @category Security-Critical
129
-     */
130
-    protected function getSecurityConfiguration()
131
-    {
132
-        if ($this->getRouteName() === 'callback') {
133
-            return $this->getSecurityManager()->configure()->asPublicPage();
134
-        }
135
-
136
-        if ($this->getRouteName() === 'detach' && $this->getSiteConfiguration()->getEnforceOAuth()) {
137
-            // Deny detach when this OAuth is enforced.
138
-            return $this->getSecurityManager()->configure()->asNone();
139
-        }
140
-
141
-        return $this->getSecurityManager()->configure()->asAllLoggedInUsersPage();
142
-    }
143
-
144
-    /**
145
-     * Main function for this page, when no specific actions are called.
146
-     * @return void
147
-     */
148
-    protected function main()
149
-    {
150
-        $this->redirect('preferences');
151
-    }
152
-
153
-    /**
154
-     * @param string $oauthToken
155
-     * @param string $oauthVerifier
156
-     *
157
-     * @throws ApplicationLogicException
158
-     */
159
-    protected function doCallbackValidation($oauthToken, $oauthVerifier)
160
-    {
161
-        if ($oauthToken === null) {
162
-            throw new ApplicationLogicException('No token provided');
163
-        }
164
-
165
-        if ($oauthVerifier === null) {
166
-            throw new ApplicationLogicException('No oauth verifier provided.');
167
-        }
168
-    }
20
+	/**
21
+	 * Attach entry point
22
+	 *
23
+	 * must be posted, or will redirect to preferences
24
+	 */
25
+	protected function attach()
26
+	{
27
+		if (!WebRequest::wasPosted()) {
28
+			$this->redirect('preferences');
29
+
30
+			return;
31
+		}
32
+
33
+		$this->validateCSRFToken();
34
+
35
+		$oauthHelper = $this->getOAuthHelper();
36
+		$user = User::getCurrent($this->getDatabase());
37
+
38
+		$requestToken = $oauthHelper->getRequestToken();
39
+
40
+		$user->setOAuthRequestToken($requestToken->key);
41
+		$user->setOAuthRequestSecret($requestToken->secret);
42
+		$user->save();
43
+
44
+		$this->redirectUrl($oauthHelper->getAuthoriseUrl($requestToken->key));
45
+	}
46
+
47
+	/**
48
+	 * Detach account entry point
49
+	 */
50
+	protected function detach()
51
+	{
52
+		$user = User::getCurrent($this->getDatabase());
53
+
54
+		$user->setOnWikiName($user->getOnWikiName());
55
+		$user->setOAuthAccessSecret(null);
56
+		$user->setOAuthAccessToken(null);
57
+		$user->setOAuthRequestSecret(null);
58
+		$user->setOAuthRequestToken(null);
59
+
60
+		$user->clearOAuthData();
61
+
62
+		$user->setForcelogout(true);
63
+
64
+		$user->save();
65
+
66
+		// force the user to log out
67
+		Session::destroy();
68
+
69
+		$this->redirect('login');
70
+	}
71
+
72
+	/**
73
+	 * Callback entry point
74
+	 */
75
+	protected function callback()
76
+	{
77
+		$oauthToken = WebRequest::getString('oauth_token');
78
+		$oauthVerifier = WebRequest::getString('oauth_verifier');
79
+
80
+		$this->doCallbackValidation($oauthToken, $oauthVerifier);
81
+
82
+		$user = User::getByRequestToken($oauthToken, $this->getDatabase());
83
+		if ($user === false) {
84
+			throw new ApplicationLogicException('Token not found in store, please try again');
85
+		}
86
+
87
+		$accessToken = $this->getOAuthHelper()->callbackCompleted(
88
+			$user->getOAuthRequestToken(),
89
+			$user->getOAuthRequestSecret(),
90
+			$oauthVerifier);
91
+
92
+		$user->setOAuthRequestSecret(null);
93
+		$user->setOAuthRequestToken(null);
94
+		$user->setOAuthAccessToken($accessToken->key);
95
+		$user->setOAuthAccessSecret($accessToken->secret);
96
+
97
+		// @todo we really should stop doing this kind of thing... it adds performance bottlenecks and breaks 3NF
98
+		$user->setOnWikiName('##OAUTH##');
99
+
100
+		$user->save();
101
+
102
+		// OK, we're the same session that just did a partial login that was redirected to OAuth. Let's upgrade the
103
+		// login to a full login
104
+		if (WebRequest::getPartialLogin() === $user->getId()) {
105
+			WebRequest::setLoggedInUser($user);
106
+		}
107
+
108
+		// My thinking is there are three cases here:
109
+		//   a) new user => redirect to prefs - it's the only thing they can access other than stats
110
+		//   b) existing user hit the connect button in prefs => redirect to prefs since it's where they were
111
+		//   c) existing user logging in => redirect to wherever they came from
112
+		$redirectDestination = WebRequest::clearPostLoginRedirect();
113
+		if ($redirectDestination !== null && !$user->isNewUser()) {
114
+			$this->redirectUrl($redirectDestination);
115
+		}
116
+		else {
117
+			$this->redirect('preferences', null, null, 'internal.php');
118
+		}
119
+	}
120
+
121
+	/**
122
+	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
123
+	 * the return value from this function.
124
+	 *
125
+	 * If this page even supports actions, you will need to check the route
126
+	 *
127
+	 * @return SecurityConfiguration
128
+	 * @category Security-Critical
129
+	 */
130
+	protected function getSecurityConfiguration()
131
+	{
132
+		if ($this->getRouteName() === 'callback') {
133
+			return $this->getSecurityManager()->configure()->asPublicPage();
134
+		}
135
+
136
+		if ($this->getRouteName() === 'detach' && $this->getSiteConfiguration()->getEnforceOAuth()) {
137
+			// Deny detach when this OAuth is enforced.
138
+			return $this->getSecurityManager()->configure()->asNone();
139
+		}
140
+
141
+		return $this->getSecurityManager()->configure()->asAllLoggedInUsersPage();
142
+	}
143
+
144
+	/**
145
+	 * Main function for this page, when no specific actions are called.
146
+	 * @return void
147
+	 */
148
+	protected function main()
149
+	{
150
+		$this->redirect('preferences');
151
+	}
152
+
153
+	/**
154
+	 * @param string $oauthToken
155
+	 * @param string $oauthVerifier
156
+	 *
157
+	 * @throws ApplicationLogicException
158
+	 */
159
+	protected function doCallbackValidation($oauthToken, $oauthVerifier)
160
+	{
161
+		if ($oauthToken === null) {
162
+			throw new ApplicationLogicException('No token provided');
163
+		}
164
+
165
+		if ($oauthVerifier === null) {
166
+			throw new ApplicationLogicException('No oauth verifier provided.');
167
+		}
168
+	}
169 169
 }
170 170
\ No newline at end of file
Please login to merge, or discard this patch.