Completed
Pull Request — newinternal (#547)
by Simon
29:08 queued 19:13
created
includes/Fragments/RequestData.php 1 patch
Indentation   +312 added lines, -312 removed lines patch added patch discarded remove patch
@@ -24,316 +24,316 @@
 block discarded – undo
24 24
 
25 25
 trait RequestData
26 26
 {
27
-    /**
28
-     * @var array Array of IP address classed as 'private' by RFC1918.
29
-     */
30
-    protected static $rfc1918ips = array(
31
-        "10.0.0.0"    => "10.255.255.255",
32
-        "172.16.0.0"  => "172.31.255.255",
33
-        "192.168.0.0" => "192.168.255.255",
34
-        "169.254.0.0" => "169.254.255.255",
35
-        "127.0.0.0"   => "127.255.255.255",
36
-    );
37
-
38
-    /**
39
-     * Gets a request object
40
-     *
41
-     * @param PdoDatabase $database  The database connection
42
-     * @param int         $requestId The ID of the request to retrieve
43
-     *
44
-     * @return Request
45
-     * @throws ApplicationLogicException
46
-     */
47
-    protected function getRequest(PdoDatabase $database, $requestId)
48
-    {
49
-        if ($requestId === null) {
50
-            throw new ApplicationLogicException("No request specified");
51
-        }
52
-
53
-        $request = Request::getById($requestId, $database);
54
-        if ($request === false || !is_a($request, Request::class)) {
55
-            throw new ApplicationLogicException('Could not load the requested request!');
56
-        }
57
-
58
-        return $request;
59
-    }
60
-
61
-    /**
62
-     * Returns a value stating whether the user is allowed to see private data or not
63
-     *
64
-     * @param Request $request
65
-     * @param User    $currentUser
66
-     *
67
-     * @return bool
68
-     * @category Security-Critical
69
-     */
70
-    protected function isAllowedPrivateData(Request $request, User $currentUser)
71
-    {
72
-        // Test the main security barrier for private data access using SecurityManager
73
-        if ($this->barrierTest('alwaysSeePrivateData', $currentUser, 'RequestData')) {
74
-            // Tool admins/check-users can always see private data
75
-            return true;
76
-        }
77
-
78
-        // reserving user is allowed to see the data
79
-        if ($currentUser->getId() === $request->getReserved()
80
-            && $request->getReserved() !== null
81
-            && $this->barrierTest('seePrivateDataWhenReserved', $currentUser, 'RequestData')
82
-        ) {
83
-            return true;
84
-        }
85
-
86
-        // user has the reveal hash
87
-        if (WebRequest::getString('hash') === $request->getRevealHash()
88
-            && $this->barrierTest('seePrivateDataWithHash', $currentUser, 'RequestData')
89
-        ) {
90
-            return true;
91
-        }
92
-
93
-        // nope. Not allowed.
94
-        return false;
95
-    }
96
-
97
-    /**
98
-     * Tests the security barrier for a specified action.
99
-     *
100
-     * Don't use within templates
101
-     *
102
-     * @param string      $action
103
-     *
104
-     * @param User        $user
105
-     * @param null|string $pageName
106
-     *
107
-     * @return bool
108
-     * @category Security-Critical
109
-     */
110
-    abstract protected function barrierTest($action, User $user, $pageName = null);
111
-
112
-    /**
113
-     * Gets the name of the route that has been passed from the request router.
114
-     * @return string
115
-     */
116
-    abstract protected function getRouteName();
117
-
118
-    /** @return SecurityManager */
119
-    abstract protected function getSecurityManager();
120
-
121
-    /**
122
-     * Sets the name of the template this page should display.
123
-     *
124
-     * @param string $name
125
-     */
126
-    abstract protected function setTemplate($name);
127
-
128
-    /** @return IXffTrustProvider */
129
-    abstract protected function getXffTrustProvider();
130
-
131
-    /** @return ILocationProvider */
132
-    abstract protected function getLocationProvider();
133
-
134
-    /** @return IRDnsProvider */
135
-    abstract protected function getRdnsProvider();
136
-
137
-    /**
138
-     * Assigns a Smarty variable
139
-     *
140
-     * @param  array|string $name  the template variable name(s)
141
-     * @param  mixed        $value the value to assign
142
-     */
143
-    abstract protected function assign($name, $value);
144
-
145
-    /**
146
-     * @param int         $requestReservationId
147
-     * @param PdoDatabase $database
148
-     * @param User        $currentUser
149
-     */
150
-    protected function setupReservationDetails($requestReservationId, PdoDatabase $database, User $currentUser)
151
-    {
152
-        $requestIsReserved = $requestReservationId !== null;
153
-        $this->assign('requestIsReserved', $requestIsReserved);
154
-        $this->assign('requestIsReservedByMe', false);
155
-
156
-        if ($requestIsReserved) {
157
-            $this->assign('requestReservedByName', User::getById($requestReservationId, $database)->getUsername());
158
-            $this->assign('requestReservedById', $requestReservationId);
159
-
160
-            if ($requestReservationId === $currentUser->getId()) {
161
-                $this->assign('requestIsReservedByMe', true);
162
-            }
163
-        }
164
-
165
-        $this->assign('canBreakReservation', $this->barrierTest('force', $currentUser, PageBreakReservation::class));
166
-    }
167
-
168
-    /**
169
-     * Adds private request data to Smarty. DO NOT USE WITHOUT FIRST CHECKING THAT THE USER IS AUTHORISED!
170
-     *
171
-     * @param Request           $request
172
-     * @param User              $currentUser
173
-     * @param SiteConfiguration $configuration
174
-     *
175
-     * @param PdoDatabase       $database
176
-     */
177
-    protected function setupPrivateData(
178
-        $request,
179
-        User $currentUser,
180
-        SiteConfiguration $configuration,
181
-        PdoDatabase $database
182
-    ) {
183
-        $xffProvider = $this->getXffTrustProvider();
184
-
185
-        $relatedEmailRequests = RequestSearchHelper::get($database)
186
-            ->byEmailAddress($request->getEmail())
187
-            ->withConfirmedEmail()
188
-            ->excludingPurgedData($configuration)
189
-            ->excludingRequest($request->getId())
190
-            ->fetch();
191
-
192
-        $this->assign('requestEmail', $request->getEmail());
193
-        $emailDomain = explode("@", $request->getEmail())[1];
194
-        $this->assign("emailurl", $emailDomain);
195
-        $this->assign('requestRelatedEmailRequestsCount', count($relatedEmailRequests));
196
-        $this->assign('requestRelatedEmailRequests', $relatedEmailRequests);
197
-
198
-        $trustedIp = $xffProvider->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
199
-        $this->assign('requestTrustedIp', $trustedIp);
200
-        $this->assign('requestRealIp', $request->getIp());
201
-        $this->assign('requestForwardedIp', $request->getForwardedIp());
202
-
203
-        $trustedIpLocation = $this->getLocationProvider()->getIpLocation($trustedIp);
204
-        $this->assign('requestTrustedIpLocation', $trustedIpLocation);
205
-
206
-        $this->assign('requestHasForwardedIp', $request->getForwardedIp() !== null);
207
-
208
-        $relatedIpRequests = RequestSearchHelper::get($database)
209
-            ->byIp($trustedIp)
210
-            ->withConfirmedEmail()
211
-            ->excludingPurgedData($configuration)
212
-            ->excludingRequest($request->getId())
213
-            ->fetch();
214
-
215
-        $this->assign('requestRelatedIpRequestsCount', count($relatedIpRequests));
216
-        $this->assign('requestRelatedIpRequests', $relatedIpRequests);
217
-
218
-        $this->setupForwardedIpData($request);
219
-    }
220
-
221
-    /**
222
-     * Adds checkuser request data to Smarty. DO NOT USE WITHOUT FIRST CHECKING THAT THE USER IS AUTHORISED!
223
-     *
224
-     * @param Request $request
225
-     */
226
-    protected function setupCheckUserData(Request $request)
227
-    {
228
-        $this->assign('requestUserAgent', $request->getUserAgent());
229
-    }
230
-
231
-    /**
232
-     * Sets up the basic data for this request, and adds it to Smarty
233
-     *
234
-     * @param Request           $request
235
-     * @param SiteConfiguration $config
236
-     */
237
-    protected function setupBasicData(Request $request, SiteConfiguration $config)
238
-    {
239
-        $this->assign('requestId', $request->getId());
240
-        $this->assign('updateVersion', $request->getUpdateVersion());
241
-        $this->assign('requestName', $request->getName());
242
-        $this->assign('requestDate', $request->getDate());
243
-        $this->assign('requestStatus', $request->getStatus());
244
-
245
-        $isClosed = !array_key_exists($request->getStatus(), $config->getRequestStates())
246
-            && $request->getStatus() !== RequestStatus::HOSPITAL;
247
-        $this->assign('requestIsClosed', $isClosed);
248
-    }
249
-
250
-    /**
251
-     * Sets up the forwarded IP data for this request and adds it to Smarty
252
-     *
253
-     * @param Request $request
254
-     */
255
-    protected function setupForwardedIpData(Request $request)
256
-    {
257
-        if ($request->getForwardedIp() !== null) {
258
-            $requestProxyData = array(); // Initialize array to store data to be output in Smarty template.
259
-            $proxyIndex = 0;
260
-
261
-            // Assuming [client] <=> [proxy1] <=> [proxy2] <=> [proxy3] <=> [us], we will see an XFF header of [client],
262
-            // [proxy1], [proxy2], and our actual IP will be [proxy3]
263
-            $proxies = explode(",", $request->getForwardedIp());
264
-            $proxies[] = $request->getIp();
265
-
266
-            // Origin is the supposed "client" IP.
267
-            $origin = $proxies[0];
268
-            $this->assign("forwardedOrigin", $origin);
269
-
270
-            // We step through the servers in reverse order, from closest to furthest
271
-            $proxies = array_reverse($proxies);
272
-
273
-            // By default, we have trust, because the first in the chain is now REMOTE_ADDR, which is hardest to spoof.
274
-            $trust = true;
275
-
276
-            /**
277
-             * @var int    $index     The zero-based index of the proxy.
278
-             * @var string $proxyData The proxy IP address (although possibly not!)
279
-             */
280
-            foreach ($proxies as $index => $proxyData) {
281
-                $proxyAddress = trim($proxyData);
282
-                $requestProxyData[$proxyIndex]['ip'] = $proxyAddress;
283
-
284
-                // get data on this IP.
285
-                $thisProxyIsTrusted = $this->getXffTrustProvider()->isTrusted($proxyAddress);
286
-
287
-                $proxyIsInPrivateRange = $this->getXffTrustProvider()
288
-                    ->ipInRange(self::$rfc1918ips, $proxyAddress);
289
-
290
-                if (!$proxyIsInPrivateRange) {
291
-                    $proxyReverseDns = $this->getRdnsProvider()->getReverseDNS($proxyAddress);
292
-                    $proxyLocation = $this->getLocationProvider()->getIpLocation($proxyAddress);
293
-                }
294
-                else {
295
-                    // this is going to fail, so why bother trying?
296
-                    $proxyReverseDns = false;
297
-                    $proxyLocation = false;
298
-                }
299
-
300
-                // current trust chain status BEFORE this link
301
-                $preLinkTrust = $trust;
302
-
303
-                // is *this* link trusted? Note, this will be true even if there is an untrusted link before this!
304
-                $requestProxyData[$proxyIndex]['trustedlink'] = $thisProxyIsTrusted;
305
-
306
-                // set the trust status of the chain to this point
307
-                $trust = $trust & $thisProxyIsTrusted;
308
-
309
-                // If this is the origin address, and the chain was trusted before this point, then we can trust
310
-                // the origin.
311
-                if ($preLinkTrust && $proxyAddress == $origin) {
312
-                    // if this is the origin, then we are at the last point in the chain.
313
-                    // @todo: this is probably the cause of some bugs when an IP appears twice - we're missing a check
314
-                    // to see if this is *really* the last in the chain, rather than just the same IP as it.
315
-                    $trust = true;
316
-                }
317
-
318
-                $requestProxyData[$proxyIndex]['trust'] = $trust;
319
-
320
-                $requestProxyData[$proxyIndex]['rdnsfailed'] = $proxyReverseDns === false;
321
-                $requestProxyData[$proxyIndex]['rdns'] = $proxyReverseDns;
322
-                $requestProxyData[$proxyIndex]['routable'] = !$proxyIsInPrivateRange;
323
-
324
-                $requestProxyData[$proxyIndex]['location'] = $proxyLocation;
325
-
326
-                if ($proxyReverseDns === $proxyAddress && $proxyIsInPrivateRange === false) {
327
-                    $requestProxyData[$proxyIndex]['rdns'] = null;
328
-                }
329
-
330
-                $showLinks = (!$trust || $proxyAddress == $origin) && !$proxyIsInPrivateRange;
331
-                $requestProxyData[$proxyIndex]['showlinks'] = $showLinks;
332
-
333
-                $proxyIndex++;
334
-            }
335
-
336
-            $this->assign("requestProxyData", $requestProxyData);
337
-        }
338
-    }
27
+	/**
28
+	 * @var array Array of IP address classed as 'private' by RFC1918.
29
+	 */
30
+	protected static $rfc1918ips = array(
31
+		"10.0.0.0"    => "10.255.255.255",
32
+		"172.16.0.0"  => "172.31.255.255",
33
+		"192.168.0.0" => "192.168.255.255",
34
+		"169.254.0.0" => "169.254.255.255",
35
+		"127.0.0.0"   => "127.255.255.255",
36
+	);
37
+
38
+	/**
39
+	 * Gets a request object
40
+	 *
41
+	 * @param PdoDatabase $database  The database connection
42
+	 * @param int         $requestId The ID of the request to retrieve
43
+	 *
44
+	 * @return Request
45
+	 * @throws ApplicationLogicException
46
+	 */
47
+	protected function getRequest(PdoDatabase $database, $requestId)
48
+	{
49
+		if ($requestId === null) {
50
+			throw new ApplicationLogicException("No request specified");
51
+		}
52
+
53
+		$request = Request::getById($requestId, $database);
54
+		if ($request === false || !is_a($request, Request::class)) {
55
+			throw new ApplicationLogicException('Could not load the requested request!');
56
+		}
57
+
58
+		return $request;
59
+	}
60
+
61
+	/**
62
+	 * Returns a value stating whether the user is allowed to see private data or not
63
+	 *
64
+	 * @param Request $request
65
+	 * @param User    $currentUser
66
+	 *
67
+	 * @return bool
68
+	 * @category Security-Critical
69
+	 */
70
+	protected function isAllowedPrivateData(Request $request, User $currentUser)
71
+	{
72
+		// Test the main security barrier for private data access using SecurityManager
73
+		if ($this->barrierTest('alwaysSeePrivateData', $currentUser, 'RequestData')) {
74
+			// Tool admins/check-users can always see private data
75
+			return true;
76
+		}
77
+
78
+		// reserving user is allowed to see the data
79
+		if ($currentUser->getId() === $request->getReserved()
80
+			&& $request->getReserved() !== null
81
+			&& $this->barrierTest('seePrivateDataWhenReserved', $currentUser, 'RequestData')
82
+		) {
83
+			return true;
84
+		}
85
+
86
+		// user has the reveal hash
87
+		if (WebRequest::getString('hash') === $request->getRevealHash()
88
+			&& $this->barrierTest('seePrivateDataWithHash', $currentUser, 'RequestData')
89
+		) {
90
+			return true;
91
+		}
92
+
93
+		// nope. Not allowed.
94
+		return false;
95
+	}
96
+
97
+	/**
98
+	 * Tests the security barrier for a specified action.
99
+	 *
100
+	 * Don't use within templates
101
+	 *
102
+	 * @param string      $action
103
+	 *
104
+	 * @param User        $user
105
+	 * @param null|string $pageName
106
+	 *
107
+	 * @return bool
108
+	 * @category Security-Critical
109
+	 */
110
+	abstract protected function barrierTest($action, User $user, $pageName = null);
111
+
112
+	/**
113
+	 * Gets the name of the route that has been passed from the request router.
114
+	 * @return string
115
+	 */
116
+	abstract protected function getRouteName();
117
+
118
+	/** @return SecurityManager */
119
+	abstract protected function getSecurityManager();
120
+
121
+	/**
122
+	 * Sets the name of the template this page should display.
123
+	 *
124
+	 * @param string $name
125
+	 */
126
+	abstract protected function setTemplate($name);
127
+
128
+	/** @return IXffTrustProvider */
129
+	abstract protected function getXffTrustProvider();
130
+
131
+	/** @return ILocationProvider */
132
+	abstract protected function getLocationProvider();
133
+
134
+	/** @return IRDnsProvider */
135
+	abstract protected function getRdnsProvider();
136
+
137
+	/**
138
+	 * Assigns a Smarty variable
139
+	 *
140
+	 * @param  array|string $name  the template variable name(s)
141
+	 * @param  mixed        $value the value to assign
142
+	 */
143
+	abstract protected function assign($name, $value);
144
+
145
+	/**
146
+	 * @param int         $requestReservationId
147
+	 * @param PdoDatabase $database
148
+	 * @param User        $currentUser
149
+	 */
150
+	protected function setupReservationDetails($requestReservationId, PdoDatabase $database, User $currentUser)
151
+	{
152
+		$requestIsReserved = $requestReservationId !== null;
153
+		$this->assign('requestIsReserved', $requestIsReserved);
154
+		$this->assign('requestIsReservedByMe', false);
155
+
156
+		if ($requestIsReserved) {
157
+			$this->assign('requestReservedByName', User::getById($requestReservationId, $database)->getUsername());
158
+			$this->assign('requestReservedById', $requestReservationId);
159
+
160
+			if ($requestReservationId === $currentUser->getId()) {
161
+				$this->assign('requestIsReservedByMe', true);
162
+			}
163
+		}
164
+
165
+		$this->assign('canBreakReservation', $this->barrierTest('force', $currentUser, PageBreakReservation::class));
166
+	}
167
+
168
+	/**
169
+	 * Adds private request data to Smarty. DO NOT USE WITHOUT FIRST CHECKING THAT THE USER IS AUTHORISED!
170
+	 *
171
+	 * @param Request           $request
172
+	 * @param User              $currentUser
173
+	 * @param SiteConfiguration $configuration
174
+	 *
175
+	 * @param PdoDatabase       $database
176
+	 */
177
+	protected function setupPrivateData(
178
+		$request,
179
+		User $currentUser,
180
+		SiteConfiguration $configuration,
181
+		PdoDatabase $database
182
+	) {
183
+		$xffProvider = $this->getXffTrustProvider();
184
+
185
+		$relatedEmailRequests = RequestSearchHelper::get($database)
186
+			->byEmailAddress($request->getEmail())
187
+			->withConfirmedEmail()
188
+			->excludingPurgedData($configuration)
189
+			->excludingRequest($request->getId())
190
+			->fetch();
191
+
192
+		$this->assign('requestEmail', $request->getEmail());
193
+		$emailDomain = explode("@", $request->getEmail())[1];
194
+		$this->assign("emailurl", $emailDomain);
195
+		$this->assign('requestRelatedEmailRequestsCount', count($relatedEmailRequests));
196
+		$this->assign('requestRelatedEmailRequests', $relatedEmailRequests);
197
+
198
+		$trustedIp = $xffProvider->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
199
+		$this->assign('requestTrustedIp', $trustedIp);
200
+		$this->assign('requestRealIp', $request->getIp());
201
+		$this->assign('requestForwardedIp', $request->getForwardedIp());
202
+
203
+		$trustedIpLocation = $this->getLocationProvider()->getIpLocation($trustedIp);
204
+		$this->assign('requestTrustedIpLocation', $trustedIpLocation);
205
+
206
+		$this->assign('requestHasForwardedIp', $request->getForwardedIp() !== null);
207
+
208
+		$relatedIpRequests = RequestSearchHelper::get($database)
209
+			->byIp($trustedIp)
210
+			->withConfirmedEmail()
211
+			->excludingPurgedData($configuration)
212
+			->excludingRequest($request->getId())
213
+			->fetch();
214
+
215
+		$this->assign('requestRelatedIpRequestsCount', count($relatedIpRequests));
216
+		$this->assign('requestRelatedIpRequests', $relatedIpRequests);
217
+
218
+		$this->setupForwardedIpData($request);
219
+	}
220
+
221
+	/**
222
+	 * Adds checkuser request data to Smarty. DO NOT USE WITHOUT FIRST CHECKING THAT THE USER IS AUTHORISED!
223
+	 *
224
+	 * @param Request $request
225
+	 */
226
+	protected function setupCheckUserData(Request $request)
227
+	{
228
+		$this->assign('requestUserAgent', $request->getUserAgent());
229
+	}
230
+
231
+	/**
232
+	 * Sets up the basic data for this request, and adds it to Smarty
233
+	 *
234
+	 * @param Request           $request
235
+	 * @param SiteConfiguration $config
236
+	 */
237
+	protected function setupBasicData(Request $request, SiteConfiguration $config)
238
+	{
239
+		$this->assign('requestId', $request->getId());
240
+		$this->assign('updateVersion', $request->getUpdateVersion());
241
+		$this->assign('requestName', $request->getName());
242
+		$this->assign('requestDate', $request->getDate());
243
+		$this->assign('requestStatus', $request->getStatus());
244
+
245
+		$isClosed = !array_key_exists($request->getStatus(), $config->getRequestStates())
246
+			&& $request->getStatus() !== RequestStatus::HOSPITAL;
247
+		$this->assign('requestIsClosed', $isClosed);
248
+	}
249
+
250
+	/**
251
+	 * Sets up the forwarded IP data for this request and adds it to Smarty
252
+	 *
253
+	 * @param Request $request
254
+	 */
255
+	protected function setupForwardedIpData(Request $request)
256
+	{
257
+		if ($request->getForwardedIp() !== null) {
258
+			$requestProxyData = array(); // Initialize array to store data to be output in Smarty template.
259
+			$proxyIndex = 0;
260
+
261
+			// Assuming [client] <=> [proxy1] <=> [proxy2] <=> [proxy3] <=> [us], we will see an XFF header of [client],
262
+			// [proxy1], [proxy2], and our actual IP will be [proxy3]
263
+			$proxies = explode(",", $request->getForwardedIp());
264
+			$proxies[] = $request->getIp();
265
+
266
+			// Origin is the supposed "client" IP.
267
+			$origin = $proxies[0];
268
+			$this->assign("forwardedOrigin", $origin);
269
+
270
+			// We step through the servers in reverse order, from closest to furthest
271
+			$proxies = array_reverse($proxies);
272
+
273
+			// By default, we have trust, because the first in the chain is now REMOTE_ADDR, which is hardest to spoof.
274
+			$trust = true;
275
+
276
+			/**
277
+			 * @var int    $index     The zero-based index of the proxy.
278
+			 * @var string $proxyData The proxy IP address (although possibly not!)
279
+			 */
280
+			foreach ($proxies as $index => $proxyData) {
281
+				$proxyAddress = trim($proxyData);
282
+				$requestProxyData[$proxyIndex]['ip'] = $proxyAddress;
283
+
284
+				// get data on this IP.
285
+				$thisProxyIsTrusted = $this->getXffTrustProvider()->isTrusted($proxyAddress);
286
+
287
+				$proxyIsInPrivateRange = $this->getXffTrustProvider()
288
+					->ipInRange(self::$rfc1918ips, $proxyAddress);
289
+
290
+				if (!$proxyIsInPrivateRange) {
291
+					$proxyReverseDns = $this->getRdnsProvider()->getReverseDNS($proxyAddress);
292
+					$proxyLocation = $this->getLocationProvider()->getIpLocation($proxyAddress);
293
+				}
294
+				else {
295
+					// this is going to fail, so why bother trying?
296
+					$proxyReverseDns = false;
297
+					$proxyLocation = false;
298
+				}
299
+
300
+				// current trust chain status BEFORE this link
301
+				$preLinkTrust = $trust;
302
+
303
+				// is *this* link trusted? Note, this will be true even if there is an untrusted link before this!
304
+				$requestProxyData[$proxyIndex]['trustedlink'] = $thisProxyIsTrusted;
305
+
306
+				// set the trust status of the chain to this point
307
+				$trust = $trust & $thisProxyIsTrusted;
308
+
309
+				// If this is the origin address, and the chain was trusted before this point, then we can trust
310
+				// the origin.
311
+				if ($preLinkTrust && $proxyAddress == $origin) {
312
+					// if this is the origin, then we are at the last point in the chain.
313
+					// @todo: this is probably the cause of some bugs when an IP appears twice - we're missing a check
314
+					// to see if this is *really* the last in the chain, rather than just the same IP as it.
315
+					$trust = true;
316
+				}
317
+
318
+				$requestProxyData[$proxyIndex]['trust'] = $trust;
319
+
320
+				$requestProxyData[$proxyIndex]['rdnsfailed'] = $proxyReverseDns === false;
321
+				$requestProxyData[$proxyIndex]['rdns'] = $proxyReverseDns;
322
+				$requestProxyData[$proxyIndex]['routable'] = !$proxyIsInPrivateRange;
323
+
324
+				$requestProxyData[$proxyIndex]['location'] = $proxyLocation;
325
+
326
+				if ($proxyReverseDns === $proxyAddress && $proxyIsInPrivateRange === false) {
327
+					$requestProxyData[$proxyIndex]['rdns'] = null;
328
+				}
329
+
330
+				$showLinks = (!$trust || $proxyAddress == $origin) && !$proxyIsInPrivateRange;
331
+				$requestProxyData[$proxyIndex]['showlinks'] = $showLinks;
332
+
333
+				$proxyIndex++;
334
+			}
335
+
336
+			$this->assign("requestProxyData", $requestProxyData);
337
+		}
338
+	}
339 339
 }
Please login to merge, or discard this patch.
includes/Pages/PageViewRequest.php 1 patch
Indentation   +284 added lines, -284 removed lines patch added patch discarded remove patch
@@ -25,288 +25,288 @@
 block discarded – undo
25 25
 
26 26
 class PageViewRequest extends InternalPageBase
27 27
 {
28
-    use RequestData;
29
-    const STATUS_SYMBOL_OPEN = '&#x2610';
30
-    const STATUS_SYMBOL_ACCEPTED = '&#x2611';
31
-    const STATUS_SYMBOL_REJECTED = '&#x2612';
32
-
33
-    /**
34
-     * Main function for this page, when no specific actions are called.
35
-     * @throws ApplicationLogicException
36
-     */
37
-    protected function main()
38
-    {
39
-        // set up csrf protection
40
-        $this->assignCSRFToken();
41
-
42
-        // get some useful objects
43
-        $database = $this->getDatabase();
44
-        $request = $this->getRequest($database, WebRequest::getInt('id'));
45
-        $config = $this->getSiteConfiguration();
46
-        $currentUser = User::getCurrent($database);
47
-
48
-        // Test we should be able to look at this request
49
-        if ($config->getEmailConfirmationEnabled()) {
50
-            if ($request->getEmailConfirm() !== 'Confirmed') {
51
-                // Not allowed to look at this yet.
52
-                throw new ApplicationLogicException('The email address has not yet been confirmed for this request.');
53
-            }
54
-        }
55
-
56
-        $this->setupBasicData($request, $config);
57
-
58
-        $this->setupUsernameData($request);
59
-
60
-        $this->setupTitle($request);
61
-
62
-        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
63
-        $this->setupGeneralData($database);
64
-
65
-        $this->assign('requestDataCleared', false);
66
-        if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
67
-            $this->assign('requestDataCleared', true);
68
-        }
69
-
70
-        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
71
-
72
-        $this->setupCreationTypes($currentUser);
73
-
74
-        $this->setupLogData($request, $database);
75
-
76
-        $this->addJs("/api.php?action=templates&targetVariable=templateconfirms");
77
-
78
-        $this->assign('showRevealLink', false);
79
-        if ($request->getReserved() === $currentUser->getId() ||
80
-            $this->barrierTest('alwaysSeeHash', $currentUser, 'RequestData')
81
-        ) {
82
-            $this->assign('showRevealLink', true);
83
-            $this->assign('revealHash', $request->getRevealHash());
84
-        }
85
-
86
-        if ($allowedPrivateData) {
87
-            $this->setTemplate('view-request/main-with-data.tpl');
88
-            $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
89
-
90
-            $this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
91
-            $this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
92
-
93
-            if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
94
-                $this->setTemplate('view-request/main-with-checkuser-data.tpl');
95
-                $this->setupCheckUserData($request);
96
-            }
97
-        }
98
-        else {
99
-            $this->setTemplate('view-request/main.tpl');
100
-        }
101
-    }
102
-
103
-    /**
104
-     * @param Request $request
105
-     */
106
-    protected function setupTitle(Request $request)
107
-    {
108
-        $statusSymbol = self::STATUS_SYMBOL_OPEN;
109
-        if ($request->getStatus() === 'Closed') {
110
-            if ($request->getWasCreated()) {
111
-                $statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
112
-            }
113
-            else {
114
-                $statusSymbol = self::STATUS_SYMBOL_REJECTED;
115
-            }
116
-        }
117
-
118
-        $this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
119
-    }
120
-
121
-    /**
122
-     * Sets up data unrelated to the request, such as the email template information
123
-     *
124
-     * @param PdoDatabase $database
125
-     */
126
-    protected function setupGeneralData(PdoDatabase $database)
127
-    {
128
-        $config = $this->getSiteConfiguration();
129
-
130
-        $this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
131
-
132
-        $this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
133
-
134
-        $this->assign('requestStates', $config->getRequestStates());
135
-
136
-        /** @var EmailTemplate $createdTemplate */
137
-        $createdTemplate = EmailTemplate::getById($config->getDefaultCreatedTemplateId(), $database);
138
-
139
-        $this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
140
-        $this->assign('createdId', $createdTemplate->getId());
141
-        $this->assign('createdName', $createdTemplate->getName());
142
-
143
-        $createReasons = EmailTemplate::getActiveTemplates(EmailTemplate::CREATED, $database);
144
-        $this->assign("createReasons", $createReasons);
145
-        $declineReasons = EmailTemplate::getActiveTemplates(EmailTemplate::NOT_CREATED, $database);
146
-        $this->assign("declineReasons", $declineReasons);
147
-
148
-        $allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::CREATED, $database);
149
-        $this->assign("allCreateReasons", $allCreateReasons);
150
-        $allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::NOT_CREATED, $database);
151
-        $this->assign("allDeclineReasons", $allDeclineReasons);
152
-        $allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
153
-        $this->assign("allOtherReasons", $allOtherReasons);
154
-    }
155
-
156
-    private function setupLogData(Request $request, PdoDatabase $database)
157
-    {
158
-        $currentUser = User::getCurrent($database);
159
-
160
-        $logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
161
-        $requestLogs = array();
162
-
163
-        if (trim($request->getComment()) !== "") {
164
-            $requestLogs[] = array(
165
-                'type'     => 'comment',
166
-                'security' => 'user',
167
-                'userid'   => null,
168
-                'user'     => $request->getName(),
169
-                'entry'    => null,
170
-                'time'     => $request->getDate(),
171
-                'canedit'  => false,
172
-                'id'       => $request->getId(),
173
-                'comment'  => $request->getComment(),
174
-            );
175
-        }
176
-
177
-        /** @var User[] $nameCache */
178
-        $nameCache = array();
179
-
180
-        $editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
181
-
182
-        /** @var Log|Comment $entry */
183
-        foreach ($logs as $entry) {
184
-            // both log and comment have a 'user' field
185
-            if (!array_key_exists($entry->getUser(), $nameCache)) {
186
-                $entryUser = User::getById($entry->getUser(), $database);
187
-                $nameCache[$entry->getUser()] = $entryUser;
188
-            }
189
-
190
-            if ($entry instanceof Comment) {
191
-                $requestLogs[] = array(
192
-                    'type'     => 'comment',
193
-                    'security' => $entry->getVisibility(),
194
-                    'user'     => $nameCache[$entry->getUser()]->getUsername(),
195
-                    'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
196
-                    'entry'    => null,
197
-                    'time'     => $entry->getTime(),
198
-                    'canedit'  => ($editableComments || $entry->getUser() == $currentUser->getId()),
199
-                    'id'       => $entry->getId(),
200
-                    'comment'  => $entry->getComment(),
201
-                );
202
-            }
203
-
204
-            if ($entry instanceof Log) {
205
-                $invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
206
-                $entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
207
-
208
-                $entryComment = $entry->getComment();
209
-
210
-                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
211
-                    $data = unserialize($entry->getComment());
212
-                    /** @var JobQueue $job */
213
-                    $job = JobQueue::getById($data['job'], $database);
214
-                    $requestLogs[] = array(
215
-                        'type'     => 'joblog',
216
-                        'security' => 'user',
217
-                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
218
-                        'user'     => $entryUser->getUsername(),
219
-                        'entry'    => LogHelper::getLogDescription($entry),
220
-                        'time'     => $entry->getTimestamp(),
221
-                        'canedit'  => false,
222
-                        'id'       => $entry->getId(),
223
-                        'jobId'    => $job->getId(),
224
-                        'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
225
-                    );
226
-                } else {
227
-                    $requestLogs[] = array(
228
-                        'type'     => 'log',
229
-                        'security' => 'user',
230
-                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
231
-                        'user'     => $entryUser->getUsername(),
232
-                        'entry'    => LogHelper::getLogDescription($entry),
233
-                        'time'     => $entry->getTimestamp(),
234
-                        'canedit'  => false,
235
-                        'id'       => $entry->getId(),
236
-                        'comment'  => $entryComment,
237
-                    );
238
-                }
239
-            }
240
-        }
241
-
242
-        $this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
243
-
244
-        $this->assign("requestLogs", $requestLogs);
245
-    }
246
-
247
-    /**
248
-     * @param Request $request
249
-     */
250
-    protected function setupUsernameData(Request $request)
251
-    {
252
-        $blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
253
-
254
-        $this->assign('requestIsBlacklisted', $blacklistData !== false);
255
-        $this->assign('requestBlacklist', $blacklistData);
256
-
257
-        try {
258
-            $spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
259
-        }
260
-        catch (Exception $ex) {
261
-            $spoofs = $ex->getMessage();
262
-        }
263
-
264
-        $this->assign("spoofs", $spoofs);
265
-    }
266
-
267
-    private function setupCreationTypes(User $user)
268
-    {
269
-        $this->assign('allowWelcomeSkip', false);
270
-        $this->assign('forceWelcomeSkip', false);
271
-
272
-        $oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
273
-
274
-        if ($user->getWelcomeTemplate() != 0) {
275
-            $this->assign('allowWelcomeSkip', true);
276
-
277
-            if (!$oauth->canWelcome()) {
278
-                $this->assign('forceWelcomeSkip', true);
279
-            }
280
-        }
281
-
282
-        // test credentials
283
-        $canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
284
-        $canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
285
-        $canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
286
-
287
-        $this->assign('canManualCreate', $canManualCreate);
288
-        $this->assign('canOauthCreate', $canOauthCreate);
289
-        $this->assign('canBotCreate', $canBotCreate);
290
-
291
-        // show/hide the type radio buttons
292
-        $creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
293
-
294
-        if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
295
-            // user is not allowed to use their default. Force a choice.
296
-            $creationHasChoice = true;
297
-        }
298
-
299
-        $this->assign('creationHasChoice', $creationHasChoice);
300
-
301
-        // determine problems in creation types
302
-        $this->assign('botProblem', false);
303
-        if ($canBotCreate && $this->getSiteConfiguration()->getCreationBotPassword() === null) {
304
-            $this->assign('botProblem', true);
305
-        }
306
-
307
-        $this->assign('oauthProblem', false);
308
-        if ($canOauthCreate && !$oauth->canCreateAccount()) {
309
-            $this->assign('oauthProblem', true);
310
-        }
311
-    }
28
+	use RequestData;
29
+	const STATUS_SYMBOL_OPEN = '&#x2610';
30
+	const STATUS_SYMBOL_ACCEPTED = '&#x2611';
31
+	const STATUS_SYMBOL_REJECTED = '&#x2612';
32
+
33
+	/**
34
+	 * Main function for this page, when no specific actions are called.
35
+	 * @throws ApplicationLogicException
36
+	 */
37
+	protected function main()
38
+	{
39
+		// set up csrf protection
40
+		$this->assignCSRFToken();
41
+
42
+		// get some useful objects
43
+		$database = $this->getDatabase();
44
+		$request = $this->getRequest($database, WebRequest::getInt('id'));
45
+		$config = $this->getSiteConfiguration();
46
+		$currentUser = User::getCurrent($database);
47
+
48
+		// Test we should be able to look at this request
49
+		if ($config->getEmailConfirmationEnabled()) {
50
+			if ($request->getEmailConfirm() !== 'Confirmed') {
51
+				// Not allowed to look at this yet.
52
+				throw new ApplicationLogicException('The email address has not yet been confirmed for this request.');
53
+			}
54
+		}
55
+
56
+		$this->setupBasicData($request, $config);
57
+
58
+		$this->setupUsernameData($request);
59
+
60
+		$this->setupTitle($request);
61
+
62
+		$this->setupReservationDetails($request->getReserved(), $database, $currentUser);
63
+		$this->setupGeneralData($database);
64
+
65
+		$this->assign('requestDataCleared', false);
66
+		if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
67
+			$this->assign('requestDataCleared', true);
68
+		}
69
+
70
+		$allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
71
+
72
+		$this->setupCreationTypes($currentUser);
73
+
74
+		$this->setupLogData($request, $database);
75
+
76
+		$this->addJs("/api.php?action=templates&targetVariable=templateconfirms");
77
+
78
+		$this->assign('showRevealLink', false);
79
+		if ($request->getReserved() === $currentUser->getId() ||
80
+			$this->barrierTest('alwaysSeeHash', $currentUser, 'RequestData')
81
+		) {
82
+			$this->assign('showRevealLink', true);
83
+			$this->assign('revealHash', $request->getRevealHash());
84
+		}
85
+
86
+		if ($allowedPrivateData) {
87
+			$this->setTemplate('view-request/main-with-data.tpl');
88
+			$this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
89
+
90
+			$this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
91
+			$this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
92
+
93
+			if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
94
+				$this->setTemplate('view-request/main-with-checkuser-data.tpl');
95
+				$this->setupCheckUserData($request);
96
+			}
97
+		}
98
+		else {
99
+			$this->setTemplate('view-request/main.tpl');
100
+		}
101
+	}
102
+
103
+	/**
104
+	 * @param Request $request
105
+	 */
106
+	protected function setupTitle(Request $request)
107
+	{
108
+		$statusSymbol = self::STATUS_SYMBOL_OPEN;
109
+		if ($request->getStatus() === 'Closed') {
110
+			if ($request->getWasCreated()) {
111
+				$statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
112
+			}
113
+			else {
114
+				$statusSymbol = self::STATUS_SYMBOL_REJECTED;
115
+			}
116
+		}
117
+
118
+		$this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
119
+	}
120
+
121
+	/**
122
+	 * Sets up data unrelated to the request, such as the email template information
123
+	 *
124
+	 * @param PdoDatabase $database
125
+	 */
126
+	protected function setupGeneralData(PdoDatabase $database)
127
+	{
128
+		$config = $this->getSiteConfiguration();
129
+
130
+		$this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
131
+
132
+		$this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
133
+
134
+		$this->assign('requestStates', $config->getRequestStates());
135
+
136
+		/** @var EmailTemplate $createdTemplate */
137
+		$createdTemplate = EmailTemplate::getById($config->getDefaultCreatedTemplateId(), $database);
138
+
139
+		$this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
140
+		$this->assign('createdId', $createdTemplate->getId());
141
+		$this->assign('createdName', $createdTemplate->getName());
142
+
143
+		$createReasons = EmailTemplate::getActiveTemplates(EmailTemplate::CREATED, $database);
144
+		$this->assign("createReasons", $createReasons);
145
+		$declineReasons = EmailTemplate::getActiveTemplates(EmailTemplate::NOT_CREATED, $database);
146
+		$this->assign("declineReasons", $declineReasons);
147
+
148
+		$allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::CREATED, $database);
149
+		$this->assign("allCreateReasons", $allCreateReasons);
150
+		$allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::NOT_CREATED, $database);
151
+		$this->assign("allDeclineReasons", $allDeclineReasons);
152
+		$allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
153
+		$this->assign("allOtherReasons", $allOtherReasons);
154
+	}
155
+
156
+	private function setupLogData(Request $request, PdoDatabase $database)
157
+	{
158
+		$currentUser = User::getCurrent($database);
159
+
160
+		$logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
161
+		$requestLogs = array();
162
+
163
+		if (trim($request->getComment()) !== "") {
164
+			$requestLogs[] = array(
165
+				'type'     => 'comment',
166
+				'security' => 'user',
167
+				'userid'   => null,
168
+				'user'     => $request->getName(),
169
+				'entry'    => null,
170
+				'time'     => $request->getDate(),
171
+				'canedit'  => false,
172
+				'id'       => $request->getId(),
173
+				'comment'  => $request->getComment(),
174
+			);
175
+		}
176
+
177
+		/** @var User[] $nameCache */
178
+		$nameCache = array();
179
+
180
+		$editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
181
+
182
+		/** @var Log|Comment $entry */
183
+		foreach ($logs as $entry) {
184
+			// both log and comment have a 'user' field
185
+			if (!array_key_exists($entry->getUser(), $nameCache)) {
186
+				$entryUser = User::getById($entry->getUser(), $database);
187
+				$nameCache[$entry->getUser()] = $entryUser;
188
+			}
189
+
190
+			if ($entry instanceof Comment) {
191
+				$requestLogs[] = array(
192
+					'type'     => 'comment',
193
+					'security' => $entry->getVisibility(),
194
+					'user'     => $nameCache[$entry->getUser()]->getUsername(),
195
+					'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
196
+					'entry'    => null,
197
+					'time'     => $entry->getTime(),
198
+					'canedit'  => ($editableComments || $entry->getUser() == $currentUser->getId()),
199
+					'id'       => $entry->getId(),
200
+					'comment'  => $entry->getComment(),
201
+				);
202
+			}
203
+
204
+			if ($entry instanceof Log) {
205
+				$invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
206
+				$entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
207
+
208
+				$entryComment = $entry->getComment();
209
+
210
+				if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
211
+					$data = unserialize($entry->getComment());
212
+					/** @var JobQueue $job */
213
+					$job = JobQueue::getById($data['job'], $database);
214
+					$requestLogs[] = array(
215
+						'type'     => 'joblog',
216
+						'security' => 'user',
217
+						'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
218
+						'user'     => $entryUser->getUsername(),
219
+						'entry'    => LogHelper::getLogDescription($entry),
220
+						'time'     => $entry->getTimestamp(),
221
+						'canedit'  => false,
222
+						'id'       => $entry->getId(),
223
+						'jobId'    => $job->getId(),
224
+						'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
225
+					);
226
+				} else {
227
+					$requestLogs[] = array(
228
+						'type'     => 'log',
229
+						'security' => 'user',
230
+						'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
231
+						'user'     => $entryUser->getUsername(),
232
+						'entry'    => LogHelper::getLogDescription($entry),
233
+						'time'     => $entry->getTimestamp(),
234
+						'canedit'  => false,
235
+						'id'       => $entry->getId(),
236
+						'comment'  => $entryComment,
237
+					);
238
+				}
239
+			}
240
+		}
241
+
242
+		$this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
243
+
244
+		$this->assign("requestLogs", $requestLogs);
245
+	}
246
+
247
+	/**
248
+	 * @param Request $request
249
+	 */
250
+	protected function setupUsernameData(Request $request)
251
+	{
252
+		$blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
253
+
254
+		$this->assign('requestIsBlacklisted', $blacklistData !== false);
255
+		$this->assign('requestBlacklist', $blacklistData);
256
+
257
+		try {
258
+			$spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
259
+		}
260
+		catch (Exception $ex) {
261
+			$spoofs = $ex->getMessage();
262
+		}
263
+
264
+		$this->assign("spoofs", $spoofs);
265
+	}
266
+
267
+	private function setupCreationTypes(User $user)
268
+	{
269
+		$this->assign('allowWelcomeSkip', false);
270
+		$this->assign('forceWelcomeSkip', false);
271
+
272
+		$oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
273
+
274
+		if ($user->getWelcomeTemplate() != 0) {
275
+			$this->assign('allowWelcomeSkip', true);
276
+
277
+			if (!$oauth->canWelcome()) {
278
+				$this->assign('forceWelcomeSkip', true);
279
+			}
280
+		}
281
+
282
+		// test credentials
283
+		$canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
284
+		$canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
285
+		$canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
286
+
287
+		$this->assign('canManualCreate', $canManualCreate);
288
+		$this->assign('canOauthCreate', $canOauthCreate);
289
+		$this->assign('canBotCreate', $canBotCreate);
290
+
291
+		// show/hide the type radio buttons
292
+		$creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
293
+
294
+		if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
295
+			// user is not allowed to use their default. Force a choice.
296
+			$creationHasChoice = true;
297
+		}
298
+
299
+		$this->assign('creationHasChoice', $creationHasChoice);
300
+
301
+		// determine problems in creation types
302
+		$this->assign('botProblem', false);
303
+		if ($canBotCreate && $this->getSiteConfiguration()->getCreationBotPassword() === null) {
304
+			$this->assign('botProblem', true);
305
+		}
306
+
307
+		$this->assign('oauthProblem', false);
308
+		if ($canOauthCreate && !$oauth->canCreateAccount()) {
309
+			$this->assign('oauthProblem', true);
310
+		}
311
+	}
312 312
 }
Please login to merge, or discard this patch.
includes/Pages/UserAuth/PageForgotPassword.php 1 patch
Indentation   +204 added lines, -204 removed lines patch added patch discarded remove patch
@@ -22,208 +22,208 @@
 block discarded – undo
22 22
 
23 23
 class PageForgotPassword extends InternalPageBase
24 24
 {
25
-    /**
26
-     * Main function for this page, when no specific actions are called.
27
-     *
28
-     * This is the forgotten password reset form
29
-     * @category Security-Critical
30
-     */
31
-    protected function main()
32
-    {
33
-        if (WebRequest::wasPosted()) {
34
-            $this->validateCSRFToken();
35
-            $username = WebRequest::postString('username');
36
-            $email = WebRequest::postEmail('email');
37
-            $database = $this->getDatabase();
38
-
39
-            if ($username === null || trim($username) === "" || $email === null || trim($email) === "") {
40
-                throw new ApplicationLogicException("Both username and email address must be specified!");
41
-            }
42
-
43
-            $user = User::getByUsername($username, $database);
44
-            $this->sendResetMail($user, $email);
45
-
46
-            SessionAlert::success('<strong>Your password reset request has been completed.</strong> If the details you have provided match our records, you should receive an email shortly.');
47
-
48
-            $this->redirect('login');
49
-        }
50
-        else {
51
-            $this->assignCSRFToken();
52
-            $this->setTemplate('forgot-password/forgotpw.tpl');
53
-        }
54
-    }
55
-
56
-    /**
57
-     * Sends a reset email if the user is authenticated
58
-     *
59
-     * @param User|boolean $user  The user located from the database, or false. Doesn't really matter, since we do the
60
-     *                            check anyway within this method and silently skip if we don't have a user.
61
-     * @param string       $email The provided email address
62
-     */
63
-    private function sendResetMail($user, $email)
64
-    {
65
-        // If the user isn't found, or the email address is wrong, skip sending the details silently.
66
-        if (!$user instanceof User) {
67
-            return;
68
-        }
69
-
70
-        if (strtolower($user->getEmail()) === strtolower($email)) {
71
-            $clientIp = $this->getXffTrustProvider()
72
-                ->getTrustedClientIp(WebRequest::remoteAddress(), WebRequest::forwardedAddress());
73
-
74
-            $this->cleanExistingTokens($user);
75
-
76
-            $hash = Base32::encodeUpper(openssl_random_pseudo_bytes(30));
77
-
78
-            $encryptionHelper = new EncryptionHelper($this->getSiteConfiguration());
79
-
80
-            $cred = new Credential();
81
-            $cred->setDatabase($this->getDatabase());
82
-            $cred->setFactor(-1);
83
-            $cred->setUserId($user->getId());
84
-            $cred->setType('reset');
85
-            $cred->setData($encryptionHelper->encryptData($hash));
86
-            $cred->setVersion(0);
87
-            $cred->setDisabled(0);
88
-            $cred->setTimeout(new DateTimeImmutable('+ 1 hour'));
89
-            $cred->setPriority(9);
90
-            $cred->save();
91
-
92
-            $this->assign("user", $user);
93
-            $this->assign("hash", $hash);
94
-            $this->assign("remoteAddress", $clientIp);
95
-
96
-            $emailContent = $this->fetchTemplate('forgot-password/reset-mail.tpl');
97
-
98
-            $this->getEmailHelper()->sendMail($user->getEmail(), "WP:ACC password reset", $emailContent);
99
-        }
100
-    }
101
-
102
-    /**
103
-     * Entry point for the reset action
104
-     *
105
-     * This is the reset password part of the form.
106
-     * @category Security-Critical
107
-     */
108
-    protected function reset()
109
-    {
110
-        $si = WebRequest::getString('si');
111
-        $id = WebRequest::getString('id');
112
-
113
-        if ($si === null || trim($si) === "" || $id === null || trim($id) === "") {
114
-            throw new ApplicationLogicException("Link not valid, please ensure it has copied correctly");
115
-        }
116
-
117
-        $database = $this->getDatabase();
118
-        $user = $this->getResettingUser($id, $database, $si);
119
-
120
-        // Dual mode
121
-        if (WebRequest::wasPosted()) {
122
-            $this->validateCSRFToken();
123
-            try {
124
-                $this->doReset($user);
125
-                $this->cleanExistingTokens($user);
126
-            }
127
-            catch (ApplicationLogicException $ex) {
128
-                SessionAlert::error($ex->getMessage());
129
-                $this->redirect('forgotPassword', 'reset', array('si' => $si, 'id' => $id));
130
-
131
-                return;
132
-            }
133
-        }
134
-        else {
135
-            $this->assignCSRFToken();
136
-            $this->assign('user', $user);
137
-            $this->setTemplate('forgot-password/forgotpwreset.tpl');
138
-        }
139
-    }
140
-
141
-    /**
142
-     * Gets the user resetting their password from the database, or throwing an exception if that is not possible.
143
-     *
144
-     * @param integer     $id       The ID of the user to retrieve
145
-     * @param PdoDatabase $database The database object to use
146
-     * @param string      $si       The reset hash provided
147
-     *
148
-     * @return User
149
-     * @throws ApplicationLogicException
150
-     */
151
-    private function getResettingUser($id, $database, $si)
152
-    {
153
-        $user = User::getById($id, $database);
154
-
155
-        if ($user === false ||  $user->isCommunityUser()) {
156
-            throw new ApplicationLogicException("Password reset failed. Please try again.");
157
-        }
158
-
159
-        $statement = $database->prepare("SELECT * FROM credential WHERE type = 'reset' AND user = :user;");
160
-        $statement->execute([':user' => $user->getId()]);
161
-
162
-        /** @var Credential $credential */
163
-        $credential = $statement->fetchObject(Credential::class);
164
-
165
-        $statement->closeCursor();
166
-
167
-        if ($credential === false) {
168
-            throw new ApplicationLogicException("Password reset failed. Please try again.");
169
-        }
170
-
171
-        $credential->setDatabase($database);
172
-
173
-        $encryptionHelper = new EncryptionHelper($this->getSiteConfiguration());
174
-        if ($encryptionHelper->decryptData($credential->getData()) != $si) {
175
-            throw new ApplicationLogicException("Password reset failed. Please try again.");
176
-        }
177
-
178
-        if ($credential->getTimeout() < new DateTimeImmutable()) {
179
-            $credential->delete();
180
-            throw new ApplicationLogicException("Password reset token expired. Please try again.");
181
-        }
182
-
183
-        return $user;
184
-    }
185
-
186
-    /**
187
-     * Performs the setting of the new password
188
-     *
189
-     * @param User $user The user to set the password for
190
-     *
191
-     * @throws ApplicationLogicException
192
-     */
193
-    private function doReset(User $user)
194
-    {
195
-        $pw = WebRequest::postString('pw');
196
-        $pw2 = WebRequest::postString('pw2');
197
-
198
-        if ($pw !== $pw2) {
199
-            throw new ApplicationLogicException('Passwords do not match!');
200
-        }
201
-
202
-        $passwordCredentialProvider = new PasswordCredentialProvider($user->getDatabase(), $this->getSiteConfiguration());
203
-        $passwordCredentialProvider->setCredential($user, 1, $pw);
204
-
205
-        SessionAlert::success('You may now log in!');
206
-        $this->redirect('login');
207
-    }
208
-
209
-    protected function isProtectedPage()
210
-    {
211
-        return false;
212
-    }
213
-
214
-    /**
215
-     * @param $user
216
-     */
217
-    private function cleanExistingTokens($user): void
218
-    {
219
-        // clean out existing reset tokens
220
-        $statement = $this->getDatabase()->prepare("SELECT * FROM credential WHERE type = 'reset' AND user = :user;");
221
-        $statement->execute([':user' => $user->getId()]);
222
-        $existing = $statement->fetchAll(PdoDatabase::FETCH_CLASS, Credential::class);
223
-
224
-        foreach ($existing as $c) {
225
-            $c->setDatabase($this->getDatabase());
226
-            $c->delete();
227
-        }
228
-    }
25
+	/**
26
+	 * Main function for this page, when no specific actions are called.
27
+	 *
28
+	 * This is the forgotten password reset form
29
+	 * @category Security-Critical
30
+	 */
31
+	protected function main()
32
+	{
33
+		if (WebRequest::wasPosted()) {
34
+			$this->validateCSRFToken();
35
+			$username = WebRequest::postString('username');
36
+			$email = WebRequest::postEmail('email');
37
+			$database = $this->getDatabase();
38
+
39
+			if ($username === null || trim($username) === "" || $email === null || trim($email) === "") {
40
+				throw new ApplicationLogicException("Both username and email address must be specified!");
41
+			}
42
+
43
+			$user = User::getByUsername($username, $database);
44
+			$this->sendResetMail($user, $email);
45
+
46
+			SessionAlert::success('<strong>Your password reset request has been completed.</strong> If the details you have provided match our records, you should receive an email shortly.');
47
+
48
+			$this->redirect('login');
49
+		}
50
+		else {
51
+			$this->assignCSRFToken();
52
+			$this->setTemplate('forgot-password/forgotpw.tpl');
53
+		}
54
+	}
55
+
56
+	/**
57
+	 * Sends a reset email if the user is authenticated
58
+	 *
59
+	 * @param User|boolean $user  The user located from the database, or false. Doesn't really matter, since we do the
60
+	 *                            check anyway within this method and silently skip if we don't have a user.
61
+	 * @param string       $email The provided email address
62
+	 */
63
+	private function sendResetMail($user, $email)
64
+	{
65
+		// If the user isn't found, or the email address is wrong, skip sending the details silently.
66
+		if (!$user instanceof User) {
67
+			return;
68
+		}
69
+
70
+		if (strtolower($user->getEmail()) === strtolower($email)) {
71
+			$clientIp = $this->getXffTrustProvider()
72
+				->getTrustedClientIp(WebRequest::remoteAddress(), WebRequest::forwardedAddress());
73
+
74
+			$this->cleanExistingTokens($user);
75
+
76
+			$hash = Base32::encodeUpper(openssl_random_pseudo_bytes(30));
77
+
78
+			$encryptionHelper = new EncryptionHelper($this->getSiteConfiguration());
79
+
80
+			$cred = new Credential();
81
+			$cred->setDatabase($this->getDatabase());
82
+			$cred->setFactor(-1);
83
+			$cred->setUserId($user->getId());
84
+			$cred->setType('reset');
85
+			$cred->setData($encryptionHelper->encryptData($hash));
86
+			$cred->setVersion(0);
87
+			$cred->setDisabled(0);
88
+			$cred->setTimeout(new DateTimeImmutable('+ 1 hour'));
89
+			$cred->setPriority(9);
90
+			$cred->save();
91
+
92
+			$this->assign("user", $user);
93
+			$this->assign("hash", $hash);
94
+			$this->assign("remoteAddress", $clientIp);
95
+
96
+			$emailContent = $this->fetchTemplate('forgot-password/reset-mail.tpl');
97
+
98
+			$this->getEmailHelper()->sendMail($user->getEmail(), "WP:ACC password reset", $emailContent);
99
+		}
100
+	}
101
+
102
+	/**
103
+	 * Entry point for the reset action
104
+	 *
105
+	 * This is the reset password part of the form.
106
+	 * @category Security-Critical
107
+	 */
108
+	protected function reset()
109
+	{
110
+		$si = WebRequest::getString('si');
111
+		$id = WebRequest::getString('id');
112
+
113
+		if ($si === null || trim($si) === "" || $id === null || trim($id) === "") {
114
+			throw new ApplicationLogicException("Link not valid, please ensure it has copied correctly");
115
+		}
116
+
117
+		$database = $this->getDatabase();
118
+		$user = $this->getResettingUser($id, $database, $si);
119
+
120
+		// Dual mode
121
+		if (WebRequest::wasPosted()) {
122
+			$this->validateCSRFToken();
123
+			try {
124
+				$this->doReset($user);
125
+				$this->cleanExistingTokens($user);
126
+			}
127
+			catch (ApplicationLogicException $ex) {
128
+				SessionAlert::error($ex->getMessage());
129
+				$this->redirect('forgotPassword', 'reset', array('si' => $si, 'id' => $id));
130
+
131
+				return;
132
+			}
133
+		}
134
+		else {
135
+			$this->assignCSRFToken();
136
+			$this->assign('user', $user);
137
+			$this->setTemplate('forgot-password/forgotpwreset.tpl');
138
+		}
139
+	}
140
+
141
+	/**
142
+	 * Gets the user resetting their password from the database, or throwing an exception if that is not possible.
143
+	 *
144
+	 * @param integer     $id       The ID of the user to retrieve
145
+	 * @param PdoDatabase $database The database object to use
146
+	 * @param string      $si       The reset hash provided
147
+	 *
148
+	 * @return User
149
+	 * @throws ApplicationLogicException
150
+	 */
151
+	private function getResettingUser($id, $database, $si)
152
+	{
153
+		$user = User::getById($id, $database);
154
+
155
+		if ($user === false ||  $user->isCommunityUser()) {
156
+			throw new ApplicationLogicException("Password reset failed. Please try again.");
157
+		}
158
+
159
+		$statement = $database->prepare("SELECT * FROM credential WHERE type = 'reset' AND user = :user;");
160
+		$statement->execute([':user' => $user->getId()]);
161
+
162
+		/** @var Credential $credential */
163
+		$credential = $statement->fetchObject(Credential::class);
164
+
165
+		$statement->closeCursor();
166
+
167
+		if ($credential === false) {
168
+			throw new ApplicationLogicException("Password reset failed. Please try again.");
169
+		}
170
+
171
+		$credential->setDatabase($database);
172
+
173
+		$encryptionHelper = new EncryptionHelper($this->getSiteConfiguration());
174
+		if ($encryptionHelper->decryptData($credential->getData()) != $si) {
175
+			throw new ApplicationLogicException("Password reset failed. Please try again.");
176
+		}
177
+
178
+		if ($credential->getTimeout() < new DateTimeImmutable()) {
179
+			$credential->delete();
180
+			throw new ApplicationLogicException("Password reset token expired. Please try again.");
181
+		}
182
+
183
+		return $user;
184
+	}
185
+
186
+	/**
187
+	 * Performs the setting of the new password
188
+	 *
189
+	 * @param User $user The user to set the password for
190
+	 *
191
+	 * @throws ApplicationLogicException
192
+	 */
193
+	private function doReset(User $user)
194
+	{
195
+		$pw = WebRequest::postString('pw');
196
+		$pw2 = WebRequest::postString('pw2');
197
+
198
+		if ($pw !== $pw2) {
199
+			throw new ApplicationLogicException('Passwords do not match!');
200
+		}
201
+
202
+		$passwordCredentialProvider = new PasswordCredentialProvider($user->getDatabase(), $this->getSiteConfiguration());
203
+		$passwordCredentialProvider->setCredential($user, 1, $pw);
204
+
205
+		SessionAlert::success('You may now log in!');
206
+		$this->redirect('login');
207
+	}
208
+
209
+	protected function isProtectedPage()
210
+	{
211
+		return false;
212
+	}
213
+
214
+	/**
215
+	 * @param $user
216
+	 */
217
+	private function cleanExistingTokens($user): void
218
+	{
219
+		// clean out existing reset tokens
220
+		$statement = $this->getDatabase()->prepare("SELECT * FROM credential WHERE type = 'reset' AND user = :user;");
221
+		$statement->execute([':user' => $user->getId()]);
222
+		$existing = $statement->fetchAll(PdoDatabase::FETCH_CLASS, Credential::class);
223
+
224
+		foreach ($existing as $c) {
225
+			$c->setDatabase($this->getDatabase());
226
+			$c->delete();
227
+		}
228
+	}
229 229
 }
Please login to merge, or discard this patch.
includes/Security/CredentialProviders/TotpCredentialProvider.php 2 patches
Indentation   +130 added lines, -130 removed lines patch added patch discarded remove patch
@@ -19,137 +19,137 @@
 block discarded – undo
19 19
 
20 20
 class TotpCredentialProvider extends CredentialProviderBase
21 21
 {
22
-    /** @var EncryptionHelper */
23
-    private $encryptionHelper;
24
-
25
-    /**
26
-     * TotpCredentialProvider constructor.
27
-     *
28
-     * @param PdoDatabase       $database
29
-     * @param SiteConfiguration $configuration
30
-     */
31
-    public function __construct(PdoDatabase $database, SiteConfiguration $configuration)
32
-    {
33
-        parent::__construct($database, $configuration, 'totp');
34
-        $this->encryptionHelper = new EncryptionHelper($configuration);
35
-    }
36
-
37
-    /**
38
-     * Validates a user-provided credential
39
-     *
40
-     * @param User   $user The user to test the authentication against
41
-     * @param string $data The raw credential data to be validated
42
-     *
43
-     * @return bool
44
-     * @throws ApplicationLogicException
45
-     */
46
-    public function authenticate(User $user, $data)
47
-    {
48
-        if (is_array($data)) {
49
-            return false;
50
-        }
51
-
52
-        $storedData = $this->getCredentialData($user->getId());
53
-
54
-        if ($storedData === null) {
55
-            throw new ApplicationLogicException('Credential data not found');
56
-        }
57
-
58
-        $provisioningUrl = $this->encryptionHelper->decryptData($storedData->getData());
59
-        $totp = Factory::loadFromProvisioningUri($provisioningUrl);
60
-
61
-        return $totp->verify($data, null, 2);
62
-    }
63
-
64
-    public function verifyEnable(User $user, $data)
65
-    {
66
-        $storedData = $this->getCredentialData($user->getId(), true);
67
-
68
-        if ($storedData === null) {
69
-            throw new ApplicationLogicException('Credential data not found');
70
-        }
71
-
72
-        $provisioningUrl = $this->encryptionHelper->decryptData($storedData->getData());
73
-        $totp = Factory::loadFromProvisioningUri($provisioningUrl);
74
-
75
-        $result = $totp->verify($data, null, 2);
76
-
77
-        if ($result && $storedData->getTimeout() > new DateTimeImmutable()) {
78
-            $storedData->setDisabled(0);
79
-            $storedData->setPriority(5);
80
-            $storedData->setTimeout(null);
81
-            $storedData->save();
82
-        }
83
-
84
-        return $result;
85
-    }
86
-
87
-    /**
88
-     * @param User   $user   The user the credential belongs to
89
-     * @param int    $factor The factor this credential provides
90
-     * @param string $data   Unused here, due to there being no user-provided data. We provide the user with the secret.
91
-     */
92
-    public function setCredential(User $user, $factor, $data)
93
-    {
94
-        $issuer = 'ACC - ' . $this->getConfiguration()->getIrcNotificationsInstance();
95
-        $totp = TOTP::create();
96
-        $totp->setLabel($user->getUsername());
97
-        $totp->setIssuer($issuer);
98
-
99
-        $storedData = $this->getCredentialData($user->getId(), null);
100
-
101
-        if ($storedData !== null) {
102
-            $storedData->delete();
103
-        }
104
-
105
-        $storedData = $this->createNewCredential($user);
106
-
107
-        $storedData->setData($this->encryptionHelper->encryptData($totp->getProvisioningUri()));
108
-        $storedData->setFactor($factor);
109
-        $storedData->setTimeout(new DateTimeImmutable('+ 1 hour'));
110
-        $storedData->setDisabled(1);
111
-        $storedData->setVersion(1);
112
-
113
-        $storedData->save();
114
-    }
115
-
116
-    public function getProvisioningUrl(User $user)
117
-    {
118
-        $storedData = $this->getCredentialData($user->getId(), true);
119
-
120
-        if ($storedData->getTimeout() < new DateTimeImmutable()) {
121
-            $storedData->delete();
122
-            $storedData = null;
123
-        }
124
-
125
-        if ($storedData === null) {
126
-            throw new ApplicationLogicException('Credential data not found');
127
-        }
128
-
129
-        return $this->encryptionHelper->decryptData($storedData->getData());
130
-    }
131
-
132
-    public function isPartiallyEnrolled(User $user)
133
-    {
134
-        $storedData = $this->getCredentialData($user->getId(), true);
135
-
136
-        if ($storedData->getTimeout() < new DateTimeImmutable()) {
137
-            $storedData->delete();
138
-
139
-            return false;
140
-        }
141
-
142
-        if ($storedData === null) {
143
-            return false;
144
-        }
22
+	/** @var EncryptionHelper */
23
+	private $encryptionHelper;
24
+
25
+	/**
26
+	 * TotpCredentialProvider constructor.
27
+	 *
28
+	 * @param PdoDatabase       $database
29
+	 * @param SiteConfiguration $configuration
30
+	 */
31
+	public function __construct(PdoDatabase $database, SiteConfiguration $configuration)
32
+	{
33
+		parent::__construct($database, $configuration, 'totp');
34
+		$this->encryptionHelper = new EncryptionHelper($configuration);
35
+	}
36
+
37
+	/**
38
+	 * Validates a user-provided credential
39
+	 *
40
+	 * @param User   $user The user to test the authentication against
41
+	 * @param string $data The raw credential data to be validated
42
+	 *
43
+	 * @return bool
44
+	 * @throws ApplicationLogicException
45
+	 */
46
+	public function authenticate(User $user, $data)
47
+	{
48
+		if (is_array($data)) {
49
+			return false;
50
+		}
51
+
52
+		$storedData = $this->getCredentialData($user->getId());
53
+
54
+		if ($storedData === null) {
55
+			throw new ApplicationLogicException('Credential data not found');
56
+		}
57
+
58
+		$provisioningUrl = $this->encryptionHelper->decryptData($storedData->getData());
59
+		$totp = Factory::loadFromProvisioningUri($provisioningUrl);
60
+
61
+		return $totp->verify($data, null, 2);
62
+	}
63
+
64
+	public function verifyEnable(User $user, $data)
65
+	{
66
+		$storedData = $this->getCredentialData($user->getId(), true);
67
+
68
+		if ($storedData === null) {
69
+			throw new ApplicationLogicException('Credential data not found');
70
+		}
71
+
72
+		$provisioningUrl = $this->encryptionHelper->decryptData($storedData->getData());
73
+		$totp = Factory::loadFromProvisioningUri($provisioningUrl);
74
+
75
+		$result = $totp->verify($data, null, 2);
76
+
77
+		if ($result && $storedData->getTimeout() > new DateTimeImmutable()) {
78
+			$storedData->setDisabled(0);
79
+			$storedData->setPriority(5);
80
+			$storedData->setTimeout(null);
81
+			$storedData->save();
82
+		}
83
+
84
+		return $result;
85
+	}
86
+
87
+	/**
88
+	 * @param User   $user   The user the credential belongs to
89
+	 * @param int    $factor The factor this credential provides
90
+	 * @param string $data   Unused here, due to there being no user-provided data. We provide the user with the secret.
91
+	 */
92
+	public function setCredential(User $user, $factor, $data)
93
+	{
94
+		$issuer = 'ACC - ' . $this->getConfiguration()->getIrcNotificationsInstance();
95
+		$totp = TOTP::create();
96
+		$totp->setLabel($user->getUsername());
97
+		$totp->setIssuer($issuer);
98
+
99
+		$storedData = $this->getCredentialData($user->getId(), null);
100
+
101
+		if ($storedData !== null) {
102
+			$storedData->delete();
103
+		}
104
+
105
+		$storedData = $this->createNewCredential($user);
106
+
107
+		$storedData->setData($this->encryptionHelper->encryptData($totp->getProvisioningUri()));
108
+		$storedData->setFactor($factor);
109
+		$storedData->setTimeout(new DateTimeImmutable('+ 1 hour'));
110
+		$storedData->setDisabled(1);
111
+		$storedData->setVersion(1);
112
+
113
+		$storedData->save();
114
+	}
115
+
116
+	public function getProvisioningUrl(User $user)
117
+	{
118
+		$storedData = $this->getCredentialData($user->getId(), true);
119
+
120
+		if ($storedData->getTimeout() < new DateTimeImmutable()) {
121
+			$storedData->delete();
122
+			$storedData = null;
123
+		}
124
+
125
+		if ($storedData === null) {
126
+			throw new ApplicationLogicException('Credential data not found');
127
+		}
128
+
129
+		return $this->encryptionHelper->decryptData($storedData->getData());
130
+	}
131
+
132
+	public function isPartiallyEnrolled(User $user)
133
+	{
134
+		$storedData = $this->getCredentialData($user->getId(), true);
135
+
136
+		if ($storedData->getTimeout() < new DateTimeImmutable()) {
137
+			$storedData->delete();
138
+
139
+			return false;
140
+		}
141
+
142
+		if ($storedData === null) {
143
+			return false;
144
+		}
145 145
 
146
-        return true;
147
-    }
146
+		return true;
147
+	}
148 148
 
149
-    public function getSecret(User $user)
150
-    {
151
-        $totp = Factory::loadFromProvisioningUri($this->getProvisioningUrl($user));
149
+	public function getSecret(User $user)
150
+	{
151
+		$totp = Factory::loadFromProvisioningUri($this->getProvisioningUrl($user));
152 152
 
153
-        return $totp->getSecret();
154
-    }
153
+		return $totp->getSecret();
154
+	}
155 155
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -91,7 +91,7 @@
 block discarded – undo
91 91
      */
92 92
     public function setCredential(User $user, $factor, $data)
93 93
     {
94
-        $issuer = 'ACC - ' . $this->getConfiguration()->getIrcNotificationsInstance();
94
+        $issuer = 'ACC - '.$this->getConfiguration()->getIrcNotificationsInstance();
95 95
         $totp = TOTP::create();
96 96
         $totp->setLabel($user->getUsername());
97 97
         $totp->setIssuer($issuer);
Please login to merge, or discard this patch.
includes/Security/CredentialProviders/ScratchTokenCredentialProvider.php 1 patch
Indentation   +132 added lines, -132 removed lines patch added patch discarded remove patch
@@ -20,136 +20,136 @@
 block discarded – undo
20 20
 
21 21
 class ScratchTokenCredentialProvider extends CredentialProviderBase
22 22
 {
23
-    /** @var EncryptionHelper */
24
-    private $encryptionHelper;
25
-    /** @var array the tokens generated in the last generation round. */
26
-    private $generatedTokens;
27
-
28
-    /**
29
-     * ScratchTokenCredentialProvider constructor.
30
-     *
31
-     * @param PdoDatabase       $database
32
-     * @param SiteConfiguration $configuration
33
-     */
34
-    public function __construct(PdoDatabase $database, SiteConfiguration $configuration)
35
-    {
36
-        parent::__construct($database, $configuration, 'scratch');
37
-        $this->encryptionHelper = new EncryptionHelper($configuration);
38
-    }
39
-
40
-    /**
41
-     * Validates a user-provided credential
42
-     *
43
-     * @param User   $user The user to test the authentication against
44
-     * @param string $data The raw credential data to be validated
45
-     *
46
-     * @return bool
47
-     * @throws ApplicationLogicException|OptimisticLockFailedException
48
-     */
49
-    public function authenticate(User $user, $data)
50
-    {
51
-        if (is_array($data)) {
52
-            return false;
53
-        }
54
-
55
-        $storedData = $this->getCredentialData($user->getId());
56
-
57
-        if ($storedData === null) {
58
-            throw new ApplicationLogicException('Credential data not found');
59
-        }
60
-
61
-        $scratchTokens = unserialize($this->encryptionHelper->decryptData($storedData->getData()));
62
-
63
-        $usedToken = null;
64
-        foreach ($scratchTokens as $scratchToken) {
65
-            if (password_verify($data, $scratchToken)){
66
-                $usedToken = $scratchToken;
67
-                SessionAlert::quick("Hey, it looks like you used a scratch token to log in. Would you like to change your multi-factor authentication configuration?", 'alert-warning');
68
-                WebRequest::setPostLoginRedirect($this->getConfiguration()->getBaseUrl() . "/internal.php/multiFactor");
69
-                break;
70
-            }
71
-        }
72
-
73
-        if($usedToken === null) {
74
-            return false;
75
-        }
76
-
77
-        $scratchTokens = array_diff($scratchTokens, [$usedToken]);
78
-
79
-        $storedData->setData($this->encryptionHelper->encryptData(serialize($scratchTokens)));
80
-        $storedData->save();
81
-
82
-        return true;
83
-    }
84
-
85
-    /**
86
-     * @param User   $user   The user the credential belongs to
87
-     * @param int    $factor The factor this credential provides
88
-     * @param string $data   Unused.
89
-     *
90
-     * @throws OptimisticLockFailedException
91
-     */
92
-    public function setCredential(User $user, $factor, $data)
93
-    {
94
-        $plaintextScratch = array();
95
-        $storedScratch = array();
96
-        for ($i = 0; $i < 5; $i++) {
97
-            $token = Base32::encodeUpper(openssl_random_pseudo_bytes(10));
98
-            $plaintextScratch[] = $token;
99
-
100
-            $storedScratch[] = password_hash(
101
-                $token,
102
-                PasswordCredentialProvider::PASSWORD_ALGO,
103
-                array('cost' => PasswordCredentialProvider::PASSWORD_COST)
104
-            );
105
-        }
106
-
107
-        $storedData = $this->getCredentialData($user->getId(), null);
108
-
109
-        if ($storedData !== null) {
110
-            $storedData->delete();
111
-        }
112
-
113
-        $storedData = $this->createNewCredential($user);
114
-
115
-        $storedData->setData($this->encryptionHelper->encryptData(serialize($storedScratch)));
116
-        $storedData->setFactor($factor);
117
-        $storedData->setVersion(1);
118
-        $storedData->setPriority(9);
119
-
120
-        $storedData->save();
121
-        $this->generatedTokens = $plaintextScratch;
122
-    }
123
-
124
-    /**
125
-     * Gets the count of remaining valid tokens
126
-     *
127
-     * @param int $userId
128
-     *
129
-     * @return int
130
-     */
131
-    public function getRemaining($userId)
132
-    {
133
-        $storedData = $this->getCredentialData($userId);
134
-
135
-        if ($storedData === null) {
136
-            return 0;
137
-        }
138
-
139
-        $scratchTokens = unserialize($this->encryptionHelper->decryptData($storedData->getData()));
140
-
141
-        return count($scratchTokens);
142
-    }
143
-
144
-    /**
145
-     * @return array
146
-     */
147
-    public function getTokens()
148
-    {
149
-        if ($this->generatedTokens != null) {
150
-            return $this->generatedTokens;
151
-        }
152
-
153
-        return array();
154
-    }
23
+	/** @var EncryptionHelper */
24
+	private $encryptionHelper;
25
+	/** @var array the tokens generated in the last generation round. */
26
+	private $generatedTokens;
27
+
28
+	/**
29
+	 * ScratchTokenCredentialProvider constructor.
30
+	 *
31
+	 * @param PdoDatabase       $database
32
+	 * @param SiteConfiguration $configuration
33
+	 */
34
+	public function __construct(PdoDatabase $database, SiteConfiguration $configuration)
35
+	{
36
+		parent::__construct($database, $configuration, 'scratch');
37
+		$this->encryptionHelper = new EncryptionHelper($configuration);
38
+	}
39
+
40
+	/**
41
+	 * Validates a user-provided credential
42
+	 *
43
+	 * @param User   $user The user to test the authentication against
44
+	 * @param string $data The raw credential data to be validated
45
+	 *
46
+	 * @return bool
47
+	 * @throws ApplicationLogicException|OptimisticLockFailedException
48
+	 */
49
+	public function authenticate(User $user, $data)
50
+	{
51
+		if (is_array($data)) {
52
+			return false;
53
+		}
54
+
55
+		$storedData = $this->getCredentialData($user->getId());
56
+
57
+		if ($storedData === null) {
58
+			throw new ApplicationLogicException('Credential data not found');
59
+		}
60
+
61
+		$scratchTokens = unserialize($this->encryptionHelper->decryptData($storedData->getData()));
62
+
63
+		$usedToken = null;
64
+		foreach ($scratchTokens as $scratchToken) {
65
+			if (password_verify($data, $scratchToken)){
66
+				$usedToken = $scratchToken;
67
+				SessionAlert::quick("Hey, it looks like you used a scratch token to log in. Would you like to change your multi-factor authentication configuration?", 'alert-warning');
68
+				WebRequest::setPostLoginRedirect($this->getConfiguration()->getBaseUrl() . "/internal.php/multiFactor");
69
+				break;
70
+			}
71
+		}
72
+
73
+		if($usedToken === null) {
74
+			return false;
75
+		}
76
+
77
+		$scratchTokens = array_diff($scratchTokens, [$usedToken]);
78
+
79
+		$storedData->setData($this->encryptionHelper->encryptData(serialize($scratchTokens)));
80
+		$storedData->save();
81
+
82
+		return true;
83
+	}
84
+
85
+	/**
86
+	 * @param User   $user   The user the credential belongs to
87
+	 * @param int    $factor The factor this credential provides
88
+	 * @param string $data   Unused.
89
+	 *
90
+	 * @throws OptimisticLockFailedException
91
+	 */
92
+	public function setCredential(User $user, $factor, $data)
93
+	{
94
+		$plaintextScratch = array();
95
+		$storedScratch = array();
96
+		for ($i = 0; $i < 5; $i++) {
97
+			$token = Base32::encodeUpper(openssl_random_pseudo_bytes(10));
98
+			$plaintextScratch[] = $token;
99
+
100
+			$storedScratch[] = password_hash(
101
+				$token,
102
+				PasswordCredentialProvider::PASSWORD_ALGO,
103
+				array('cost' => PasswordCredentialProvider::PASSWORD_COST)
104
+			);
105
+		}
106
+
107
+		$storedData = $this->getCredentialData($user->getId(), null);
108
+
109
+		if ($storedData !== null) {
110
+			$storedData->delete();
111
+		}
112
+
113
+		$storedData = $this->createNewCredential($user);
114
+
115
+		$storedData->setData($this->encryptionHelper->encryptData(serialize($storedScratch)));
116
+		$storedData->setFactor($factor);
117
+		$storedData->setVersion(1);
118
+		$storedData->setPriority(9);
119
+
120
+		$storedData->save();
121
+		$this->generatedTokens = $plaintextScratch;
122
+	}
123
+
124
+	/**
125
+	 * Gets the count of remaining valid tokens
126
+	 *
127
+	 * @param int $userId
128
+	 *
129
+	 * @return int
130
+	 */
131
+	public function getRemaining($userId)
132
+	{
133
+		$storedData = $this->getCredentialData($userId);
134
+
135
+		if ($storedData === null) {
136
+			return 0;
137
+		}
138
+
139
+		$scratchTokens = unserialize($this->encryptionHelper->decryptData($storedData->getData()));
140
+
141
+		return count($scratchTokens);
142
+	}
143
+
144
+	/**
145
+	 * @return array
146
+	 */
147
+	public function getTokens()
148
+	{
149
+		if ($this->generatedTokens != null) {
150
+			return $this->generatedTokens;
151
+		}
152
+
153
+		return array();
154
+	}
155 155
 }
Please login to merge, or discard this patch.
includes/Helpers/SearchHelpers/JobQueueSearchHelper.php 1 patch
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -13,67 +13,67 @@
 block discarded – undo
13 13
 
14 14
 class JobQueueSearchHelper extends SearchHelperBase
15 15
 {
16
-    protected function __construct(PdoDatabase $database)
17
-    {
18
-        parent::__construct($database, 'jobqueue', JobQueue::class, null);
19
-    }
20
-
21
-    /**
22
-     * @param PdoDatabase $database
23
-     *
24
-     * @return JobQueueSearchHelper
25
-     */
26
-    public static function get(PdoDatabase $database) {
27
-        $helper = new JobQueueSearchHelper($database);
28
-        return $helper;
29
-    }
30
-
31
-    /**
32
-     * @param string[] $statuses
33
-     *
34
-     * @return $this
35
-     */
36
-    public function statusIn($statuses) {
37
-        $this->inClause('status', $statuses);
38
-
39
-        return $this;
40
-    }
41
-
42
-    /**
43
-     * @return $this
44
-     */
45
-    public function notAcknowledged() {
46
-        $this->whereClause .= ' AND (acknowledged IS NULL OR acknowledged = 0)';
47
-
48
-        return $this;
49
-    }
50
-
51
-    public function byTask($task) {
52
-        $this->whereClause .= ' AND task = ?';
53
-        $this->parameterList[] = $task;
54
-
55
-        return $this;
56
-    }
57
-
58
-    public function byUser($userId) {
59
-        $this->whereClause .= ' AND user = ?';
60
-        $this->parameterList[] = $userId;
61
-
62
-        return $this;
63
-    }
64
-
65
-    public function byStatus($status) {
66
-        $this->whereClause .= ' AND status = ?';
67
-        $this->parameterList[] = $status;
68
-
69
-        return $this;
70
-    }
71
-
72
-    public function byRequest(int $request) : JobQueueSearchHelper
73
-    {
74
-        $this->whereClause .= ' AND request = ?';
75
-        $this->parameterList[] = $request;
76
-
77
-        return $this;
78
-    }
16
+	protected function __construct(PdoDatabase $database)
17
+	{
18
+		parent::__construct($database, 'jobqueue', JobQueue::class, null);
19
+	}
20
+
21
+	/**
22
+	 * @param PdoDatabase $database
23
+	 *
24
+	 * @return JobQueueSearchHelper
25
+	 */
26
+	public static function get(PdoDatabase $database) {
27
+		$helper = new JobQueueSearchHelper($database);
28
+		return $helper;
29
+	}
30
+
31
+	/**
32
+	 * @param string[] $statuses
33
+	 *
34
+	 * @return $this
35
+	 */
36
+	public function statusIn($statuses) {
37
+		$this->inClause('status', $statuses);
38
+
39
+		return $this;
40
+	}
41
+
42
+	/**
43
+	 * @return $this
44
+	 */
45
+	public function notAcknowledged() {
46
+		$this->whereClause .= ' AND (acknowledged IS NULL OR acknowledged = 0)';
47
+
48
+		return $this;
49
+	}
50
+
51
+	public function byTask($task) {
52
+		$this->whereClause .= ' AND task = ?';
53
+		$this->parameterList[] = $task;
54
+
55
+		return $this;
56
+	}
57
+
58
+	public function byUser($userId) {
59
+		$this->whereClause .= ' AND user = ?';
60
+		$this->parameterList[] = $userId;
61
+
62
+		return $this;
63
+	}
64
+
65
+	public function byStatus($status) {
66
+		$this->whereClause .= ' AND status = ?';
67
+		$this->parameterList[] = $status;
68
+
69
+		return $this;
70
+	}
71
+
72
+	public function byRequest(int $request) : JobQueueSearchHelper
73
+	{
74
+		$this->whereClause .= ' AND request = ?';
75
+		$this->parameterList[] = $request;
76
+
77
+		return $this;
78
+	}
79 79
 }
Please login to merge, or discard this patch.
includes/Helpers/IrcNotificationHelper.php 2 patches
Indentation   +428 added lines, -428 removed lines patch added patch discarded remove patch
@@ -26,434 +26,434 @@
 block discarded – undo
26 26
  */
27 27
 class IrcNotificationHelper
28 28
 {
29
-    /** @var PdoDatabase $notificationsDatabase */
30
-    private $notificationsDatabase;
31
-    /** @var PdoDatabase $primaryDatabase */
32
-    private $primaryDatabase;
33
-    /** @var bool $notificationsEnabled */
34
-    private $notificationsEnabled;
35
-    /** @var int $notificationType */
36
-    private $notificationType;
37
-    /** @var User $currentUser */
38
-    private $currentUser;
39
-    /** @var string $instanceName */
40
-    private $instanceName;
41
-    /** @var string */
42
-    private $baseUrl;
43
-    /** @var array */
44
-    private $requestStates;
45
-
46
-    /**
47
-     * IrcNotificationHelper constructor.
48
-     *
49
-     * @param SiteConfiguration $siteConfiguration
50
-     * @param PdoDatabase       $primaryDatabase
51
-     * @param PdoDatabase       $notificationsDatabase
52
-     */
53
-    public function __construct(
54
-        SiteConfiguration $siteConfiguration,
55
-        PdoDatabase $primaryDatabase,
56
-        PdoDatabase $notificationsDatabase = null
57
-    ) {
58
-        $this->primaryDatabase = $primaryDatabase;
59
-
60
-        if ($notificationsDatabase !== null) {
61
-            $this->notificationsDatabase = $notificationsDatabase;
62
-            $this->notificationsEnabled = $siteConfiguration->getIrcNotificationsEnabled();
63
-        }
64
-        else {
65
-            $this->notificationsEnabled = false;
66
-        }
67
-
68
-        $this->notificationType = $siteConfiguration->getIrcNotificationType();
69
-        $this->instanceName = $siteConfiguration->getIrcNotificationsInstance();
70
-        $this->baseUrl = $siteConfiguration->getBaseUrl();
71
-        $this->requestStates = $siteConfiguration->getRequestStates();
72
-
73
-        $this->currentUser = User::getCurrent($primaryDatabase);
74
-    }
75
-
76
-    /**
77
-     * Send a notification
78
-     *
79
-     * @param string $message The text to send
80
-     */
81
-    protected function send($message)
82
-    {
83
-        $instanceName = $this->instanceName;
84
-
85
-        if (!$this->notificationsEnabled) {
86
-            return;
87
-        }
88
-
89
-        $blacklist = array("DCC", "CCTP", "PRIVMSG");
90
-        $message = str_replace($blacklist, "(IRC Blacklist)", $message); // Lets stop DCC etc
91
-
92
-        $msg = IrcColourCode::RESET . IrcColourCode::BOLD . "[$instanceName]" . IrcColourCode::RESET . ": $message";
93
-
94
-        try {
95
-            $notification = new Notification();
96
-            $notification->setDatabase($this->notificationsDatabase);
97
-            $notification->setType($this->notificationType);
98
-            $notification->setText($msg);
99
-
100
-            $notification->save();
101
-        }
102
-        catch (Exception $ex) {
103
-            // OK, so we failed to send the notification - that db might be down?
104
-            // This is non-critical, so silently fail.
105
-
106
-            // Disable notifications for remainder of request.
107
-            $this->notificationsEnabled = false;
108
-        }
109
-    }
110
-
111
-    #region user management
112
-
113
-    /**
114
-     * send a new user notification
115
-     *
116
-     * @param User $user
117
-     */
118
-    public function userNew(User $user)
119
-    {
120
-        $this->send("New user: {$user->getUsername()}");
121
-    }
122
-
123
-    /**
124
-     * send an approved notification
125
-     *
126
-     * @param User $user
127
-     */
128
-    public function userApproved(User $user)
129
-    {
130
-        $this->send("{$user->getUsername()} approved by " . $this->currentUser->getUsername());
131
-    }
132
-
133
-    /**
134
-     * send a declined notification
135
-     *
136
-     * @param User   $user
137
-     * @param string $reason the reason the user was declined
138
-     */
139
-    public function userDeclined(User $user, $reason)
140
-    {
141
-        $this->send("{$user->getUsername()} declined by " . $this->currentUser->getUsername() . " ($reason)");
142
-    }
143
-
144
-    /**
145
-     * send a suspended notification
146
-     *
147
-     * @param User   $user
148
-     * @param string $reason The reason the user has been suspended
149
-     */
150
-    public function userSuspended(User $user, $reason)
151
-    {
152
-        $this->send("{$user->getUsername()} suspended by " . $this->currentUser->getUsername() . " ($reason)");
153
-    }
154
-
155
-    /**
156
-     * Send a preference change notification
157
-     *
158
-     * @param User $user
159
-     */
160
-    public function userPrefChange(User $user)
161
-    {
162
-        $this->send("{$user->getUsername()}'s preferences were changed by " . $this->currentUser->getUsername());
163
-    }
164
-
165
-    /**
166
-     * Send a user renamed notification
167
-     *
168
-     * @param User   $user
169
-     * @param string $old
170
-     */
171
-    public function userRenamed(User $user, $old)
172
-    {
173
-        $this->send($this->currentUser->getUsername() . " renamed $old to {$user->getUsername()}");
174
-    }
175
-
176
-    /**
177
-     * @param User   $user
178
-     * @param string $reason
179
-     */
180
-    public function userRolesEdited(User $user, $reason)
181
-    {
182
-        $currentUser = $this->currentUser->getUsername();
183
-        $this->send("Active roles for {$user->getUsername()} changed by " . $currentUser . " ($reason)");
184
-    }
185
-
186
-    #endregion
187
-
188
-    #region Site Notice
189
-
190
-    /**
191
-     * Summary of siteNoticeEdited
192
-     */
193
-    public function siteNoticeEdited()
194
-    {
195
-        $this->send("Site notice edited by " . $this->currentUser->getUsername());
196
-    }
197
-    #endregion
198
-
199
-    #region Welcome Templates
200
-    /**
201
-     * Summary of welcomeTemplateCreated
202
-     *
203
-     * @param WelcomeTemplate $template
204
-     */
205
-    public function welcomeTemplateCreated(WelcomeTemplate $template)
206
-    {
207
-        $this->send("Welcome template {$template->getId()} created by " . $this->currentUser->getUsername());
208
-    }
209
-
210
-    /**
211
-     * Summary of welcomeTemplateDeleted
212
-     *
213
-     * @param int $templateid
214
-     */
215
-    public function welcomeTemplateDeleted($templateid)
216
-    {
217
-        $this->send("Welcome template {$templateid} deleted by " . $this->currentUser->getUsername());
218
-    }
219
-
220
-    /**
221
-     * Summary of welcomeTemplateEdited
222
-     *
223
-     * @param WelcomeTemplate $template
224
-     */
225
-    public function welcomeTemplateEdited(WelcomeTemplate $template)
226
-    {
227
-        $this->send("Welcome template {$template->getId()} edited by " . $this->currentUser->getUsername());
228
-    }
229
-
230
-    #endregion
231
-
232
-    #region bans
233
-    /**
234
-     * Summary of banned
235
-     *
236
-     * @param Ban $ban
237
-     */
238
-    public function banned(Ban $ban)
239
-    {
240
-        if ($ban->getDuration() == -1) {
241
-            $duration = "indefinitely";
242
-        }
243
-        else {
244
-            $duration = "until " . date("F j, Y, g:i a", $ban->getDuration());
245
-        }
246
-
247
-        $username = $this->currentUser->getUsername();
248
-
249
-        $this->send("{$ban->getTarget()} banned by {$username} for '{$ban->getReason()}' {$duration}");
250
-    }
251
-
252
-    /**
253
-     * Summary of unbanned
254
-     *
255
-     * @param Ban    $ban
256
-     * @param string $unbanreason
257
-     */
258
-    public function unbanned(Ban $ban, $unbanreason)
259
-    {
260
-        $this->send($ban->getTarget() . " unbanned by " . $this->currentUser
261
-                ->getUsername() . " (" . $unbanreason . ")");
262
-    }
263
-
264
-    #endregion
265
-
266
-    #region request management
267
-
268
-    /**
269
-     * Summary of requestReceived
270
-     *
271
-     * @param Request $request
272
-     */
273
-    public function requestReceived(Request $request)
274
-    {
275
-        $this->send(
276
-            IrcColourCode::DARK_GREY . "[["
277
-            . IrcColourCode::DARK_GREEN . "acc:"
278
-            . IrcColourCode::ORANGE . $request->getId()
279
-            . IrcColourCode::DARK_GREY . "]]"
280
-            . IrcColourCode::RED . " N "
281
-            . IrcColourCode::DARK_BLUE . $this->baseUrl . "/internal.php/viewRequest?id={$request->getId()} "
282
-            . IrcColourCode::DARK_RED . "* "
283
-            . IrcColourCode::DARK_GREEN . $request->getName()
284
-            . IrcColourCode::DARK_RED . " * "
285
-            . IrcColourCode::RESET
286
-        );
287
-    }
288
-
289
-    /**
290
-     * Summary of requestDeferred
291
-     *
292
-     * @param Request $request
293
-     */
294
-    public function requestDeferred(Request $request)
295
-    {
296
-        $availableRequestStates = $this->requestStates;
297
-
298
-        $deferTo = $availableRequestStates[$request->getStatus()]['deferto'];
299
-        $username = $this->currentUser->getUsername();
300
-
301
-        $this->send("Request {$request->getId()} ({$request->getName()}) deferred to {$deferTo} by {$username}");
302
-    }
303
-
304
-    /**
305
-     *
306
-     * Summary of requestDeferredWithMail
307
-     *
308
-     * @param Request $request
309
-     */
310
-    public function requestDeferredWithMail(Request $request)
311
-    {
312
-        $availableRequestStates = $this->requestStates;
313
-
314
-        $deferTo = $availableRequestStates[$request->getStatus()]['deferto'];
315
-        $username = $this->currentUser->getUsername();
316
-        $id = $request->getId();
317
-        $name = $request->getName();
318
-
319
-        $this->send("Request {$id} ({$name}) deferred to {$deferTo} with an email by {$username}");
320
-    }
321
-
322
-    /**
323
-     * Summary of requestClosed
324
-     *
325
-     * @param Request $request
326
-     * @param string  $closetype
327
-     */
328
-    public function requestClosed(Request $request, $closetype)
329
-    {
330
-        $username = $this->currentUser->getUsername();
331
-
332
-        $this->send("Request {$request->getId()} ({$request->getName()}) closed ($closetype) by {$username}");
333
-    }
334
-
335
-    /**
336
-     * Summary of sentMail
337
-     *
338
-     * @param Request $request
339
-     */
340
-    public function sentMail(Request $request)
341
-    {
342
-        $this->send($this->currentUser->getUsername()
343
-            . " sent an email related to Request {$request->getId()} ({$request->getName()})");
344
-    }
345
-
346
-    #endregion
347
-
348
-    #region reservations
349
-
350
-    /**
351
-     * Summary of requestReserved
352
-     *
353
-     * @param Request $request
354
-     */
355
-    public function requestReserved(Request $request)
356
-    {
357
-        $username = $this->currentUser->getUsername();
358
-
359
-        $this->send("Request {$request->getId()} ({$request->getName()}) reserved by {$username}");
360
-    }
361
-
362
-    /**
363
-     * Summary of requestReserveBroken
364
-     *
365
-     * @param Request $request
366
-     */
367
-    public function requestReserveBroken(Request $request)
368
-    {
369
-        $username = $this->currentUser->getUsername();
370
-
371
-        $this->send("Reservation on request {$request->getId()} ({$request->getName()}) broken by {$username}");
372
-    }
373
-
374
-    /**
375
-     * Summary of requestUnreserved
376
-     *
377
-     * @param Request $request
378
-     */
379
-    public function requestUnreserved(Request $request)
380
-    {
381
-        $this->send("Request {$request->getId()} ({$request->getName()}) is no longer being handled.");
382
-    }
383
-
384
-    /**
385
-     * Summary of requestReservationSent
386
-     *
387
-     * @param Request $request
388
-     * @param User    $target
389
-     */
390
-    public function requestReservationSent(Request $request, User $target)
391
-    {
392
-        $username = $this->currentUser->getUsername();
393
-
394
-        $this->send(
395
-            "Reservation of request {$request->getId()} ({$request->getName()}) sent to {$target->getUsername()} by "
396
-            . $username);
397
-    }
398
-
399
-    #endregion
400
-
401
-    #region comments
402
-
403
-    /**
404
-     * Summary of commentCreated
405
-     *
406
-     * @param Comment $comment
407
-     * @param Request $request
408
-     */
409
-    public function commentCreated(Comment $comment, Request $request)
410
-    {
411
-        $username = $this->currentUser->getUsername();
412
-        $visibility = ($comment->getVisibility() == "admin" ? "private " : "");
413
-
414
-        $this->send("{$username} posted a {$visibility}comment on request {$request->getId()} ({$request->getName()})");
415
-    }
416
-
417
-    /**
418
-     * Summary of commentEdited
419
-     *
420
-     * @param Comment $comment
421
-     * @param Request $request
422
-     */
423
-    public function commentEdited(Comment $comment, Request $request)
424
-    {
425
-        $username = $this->currentUser->getUsername();
426
-
427
-        $this->send(<<<TAG
29
+	/** @var PdoDatabase $notificationsDatabase */
30
+	private $notificationsDatabase;
31
+	/** @var PdoDatabase $primaryDatabase */
32
+	private $primaryDatabase;
33
+	/** @var bool $notificationsEnabled */
34
+	private $notificationsEnabled;
35
+	/** @var int $notificationType */
36
+	private $notificationType;
37
+	/** @var User $currentUser */
38
+	private $currentUser;
39
+	/** @var string $instanceName */
40
+	private $instanceName;
41
+	/** @var string */
42
+	private $baseUrl;
43
+	/** @var array */
44
+	private $requestStates;
45
+
46
+	/**
47
+	 * IrcNotificationHelper constructor.
48
+	 *
49
+	 * @param SiteConfiguration $siteConfiguration
50
+	 * @param PdoDatabase       $primaryDatabase
51
+	 * @param PdoDatabase       $notificationsDatabase
52
+	 */
53
+	public function __construct(
54
+		SiteConfiguration $siteConfiguration,
55
+		PdoDatabase $primaryDatabase,
56
+		PdoDatabase $notificationsDatabase = null
57
+	) {
58
+		$this->primaryDatabase = $primaryDatabase;
59
+
60
+		if ($notificationsDatabase !== null) {
61
+			$this->notificationsDatabase = $notificationsDatabase;
62
+			$this->notificationsEnabled = $siteConfiguration->getIrcNotificationsEnabled();
63
+		}
64
+		else {
65
+			$this->notificationsEnabled = false;
66
+		}
67
+
68
+		$this->notificationType = $siteConfiguration->getIrcNotificationType();
69
+		$this->instanceName = $siteConfiguration->getIrcNotificationsInstance();
70
+		$this->baseUrl = $siteConfiguration->getBaseUrl();
71
+		$this->requestStates = $siteConfiguration->getRequestStates();
72
+
73
+		$this->currentUser = User::getCurrent($primaryDatabase);
74
+	}
75
+
76
+	/**
77
+	 * Send a notification
78
+	 *
79
+	 * @param string $message The text to send
80
+	 */
81
+	protected function send($message)
82
+	{
83
+		$instanceName = $this->instanceName;
84
+
85
+		if (!$this->notificationsEnabled) {
86
+			return;
87
+		}
88
+
89
+		$blacklist = array("DCC", "CCTP", "PRIVMSG");
90
+		$message = str_replace($blacklist, "(IRC Blacklist)", $message); // Lets stop DCC etc
91
+
92
+		$msg = IrcColourCode::RESET . IrcColourCode::BOLD . "[$instanceName]" . IrcColourCode::RESET . ": $message";
93
+
94
+		try {
95
+			$notification = new Notification();
96
+			$notification->setDatabase($this->notificationsDatabase);
97
+			$notification->setType($this->notificationType);
98
+			$notification->setText($msg);
99
+
100
+			$notification->save();
101
+		}
102
+		catch (Exception $ex) {
103
+			// OK, so we failed to send the notification - that db might be down?
104
+			// This is non-critical, so silently fail.
105
+
106
+			// Disable notifications for remainder of request.
107
+			$this->notificationsEnabled = false;
108
+		}
109
+	}
110
+
111
+	#region user management
112
+
113
+	/**
114
+	 * send a new user notification
115
+	 *
116
+	 * @param User $user
117
+	 */
118
+	public function userNew(User $user)
119
+	{
120
+		$this->send("New user: {$user->getUsername()}");
121
+	}
122
+
123
+	/**
124
+	 * send an approved notification
125
+	 *
126
+	 * @param User $user
127
+	 */
128
+	public function userApproved(User $user)
129
+	{
130
+		$this->send("{$user->getUsername()} approved by " . $this->currentUser->getUsername());
131
+	}
132
+
133
+	/**
134
+	 * send a declined notification
135
+	 *
136
+	 * @param User   $user
137
+	 * @param string $reason the reason the user was declined
138
+	 */
139
+	public function userDeclined(User $user, $reason)
140
+	{
141
+		$this->send("{$user->getUsername()} declined by " . $this->currentUser->getUsername() . " ($reason)");
142
+	}
143
+
144
+	/**
145
+	 * send a suspended notification
146
+	 *
147
+	 * @param User   $user
148
+	 * @param string $reason The reason the user has been suspended
149
+	 */
150
+	public function userSuspended(User $user, $reason)
151
+	{
152
+		$this->send("{$user->getUsername()} suspended by " . $this->currentUser->getUsername() . " ($reason)");
153
+	}
154
+
155
+	/**
156
+	 * Send a preference change notification
157
+	 *
158
+	 * @param User $user
159
+	 */
160
+	public function userPrefChange(User $user)
161
+	{
162
+		$this->send("{$user->getUsername()}'s preferences were changed by " . $this->currentUser->getUsername());
163
+	}
164
+
165
+	/**
166
+	 * Send a user renamed notification
167
+	 *
168
+	 * @param User   $user
169
+	 * @param string $old
170
+	 */
171
+	public function userRenamed(User $user, $old)
172
+	{
173
+		$this->send($this->currentUser->getUsername() . " renamed $old to {$user->getUsername()}");
174
+	}
175
+
176
+	/**
177
+	 * @param User   $user
178
+	 * @param string $reason
179
+	 */
180
+	public function userRolesEdited(User $user, $reason)
181
+	{
182
+		$currentUser = $this->currentUser->getUsername();
183
+		$this->send("Active roles for {$user->getUsername()} changed by " . $currentUser . " ($reason)");
184
+	}
185
+
186
+	#endregion
187
+
188
+	#region Site Notice
189
+
190
+	/**
191
+	 * Summary of siteNoticeEdited
192
+	 */
193
+	public function siteNoticeEdited()
194
+	{
195
+		$this->send("Site notice edited by " . $this->currentUser->getUsername());
196
+	}
197
+	#endregion
198
+
199
+	#region Welcome Templates
200
+	/**
201
+	 * Summary of welcomeTemplateCreated
202
+	 *
203
+	 * @param WelcomeTemplate $template
204
+	 */
205
+	public function welcomeTemplateCreated(WelcomeTemplate $template)
206
+	{
207
+		$this->send("Welcome template {$template->getId()} created by " . $this->currentUser->getUsername());
208
+	}
209
+
210
+	/**
211
+	 * Summary of welcomeTemplateDeleted
212
+	 *
213
+	 * @param int $templateid
214
+	 */
215
+	public function welcomeTemplateDeleted($templateid)
216
+	{
217
+		$this->send("Welcome template {$templateid} deleted by " . $this->currentUser->getUsername());
218
+	}
219
+
220
+	/**
221
+	 * Summary of welcomeTemplateEdited
222
+	 *
223
+	 * @param WelcomeTemplate $template
224
+	 */
225
+	public function welcomeTemplateEdited(WelcomeTemplate $template)
226
+	{
227
+		$this->send("Welcome template {$template->getId()} edited by " . $this->currentUser->getUsername());
228
+	}
229
+
230
+	#endregion
231
+
232
+	#region bans
233
+	/**
234
+	 * Summary of banned
235
+	 *
236
+	 * @param Ban $ban
237
+	 */
238
+	public function banned(Ban $ban)
239
+	{
240
+		if ($ban->getDuration() == -1) {
241
+			$duration = "indefinitely";
242
+		}
243
+		else {
244
+			$duration = "until " . date("F j, Y, g:i a", $ban->getDuration());
245
+		}
246
+
247
+		$username = $this->currentUser->getUsername();
248
+
249
+		$this->send("{$ban->getTarget()} banned by {$username} for '{$ban->getReason()}' {$duration}");
250
+	}
251
+
252
+	/**
253
+	 * Summary of unbanned
254
+	 *
255
+	 * @param Ban    $ban
256
+	 * @param string $unbanreason
257
+	 */
258
+	public function unbanned(Ban $ban, $unbanreason)
259
+	{
260
+		$this->send($ban->getTarget() . " unbanned by " . $this->currentUser
261
+				->getUsername() . " (" . $unbanreason . ")");
262
+	}
263
+
264
+	#endregion
265
+
266
+	#region request management
267
+
268
+	/**
269
+	 * Summary of requestReceived
270
+	 *
271
+	 * @param Request $request
272
+	 */
273
+	public function requestReceived(Request $request)
274
+	{
275
+		$this->send(
276
+			IrcColourCode::DARK_GREY . "[["
277
+			. IrcColourCode::DARK_GREEN . "acc:"
278
+			. IrcColourCode::ORANGE . $request->getId()
279
+			. IrcColourCode::DARK_GREY . "]]"
280
+			. IrcColourCode::RED . " N "
281
+			. IrcColourCode::DARK_BLUE . $this->baseUrl . "/internal.php/viewRequest?id={$request->getId()} "
282
+			. IrcColourCode::DARK_RED . "* "
283
+			. IrcColourCode::DARK_GREEN . $request->getName()
284
+			. IrcColourCode::DARK_RED . " * "
285
+			. IrcColourCode::RESET
286
+		);
287
+	}
288
+
289
+	/**
290
+	 * Summary of requestDeferred
291
+	 *
292
+	 * @param Request $request
293
+	 */
294
+	public function requestDeferred(Request $request)
295
+	{
296
+		$availableRequestStates = $this->requestStates;
297
+
298
+		$deferTo = $availableRequestStates[$request->getStatus()]['deferto'];
299
+		$username = $this->currentUser->getUsername();
300
+
301
+		$this->send("Request {$request->getId()} ({$request->getName()}) deferred to {$deferTo} by {$username}");
302
+	}
303
+
304
+	/**
305
+	 *
306
+	 * Summary of requestDeferredWithMail
307
+	 *
308
+	 * @param Request $request
309
+	 */
310
+	public function requestDeferredWithMail(Request $request)
311
+	{
312
+		$availableRequestStates = $this->requestStates;
313
+
314
+		$deferTo = $availableRequestStates[$request->getStatus()]['deferto'];
315
+		$username = $this->currentUser->getUsername();
316
+		$id = $request->getId();
317
+		$name = $request->getName();
318
+
319
+		$this->send("Request {$id} ({$name}) deferred to {$deferTo} with an email by {$username}");
320
+	}
321
+
322
+	/**
323
+	 * Summary of requestClosed
324
+	 *
325
+	 * @param Request $request
326
+	 * @param string  $closetype
327
+	 */
328
+	public function requestClosed(Request $request, $closetype)
329
+	{
330
+		$username = $this->currentUser->getUsername();
331
+
332
+		$this->send("Request {$request->getId()} ({$request->getName()}) closed ($closetype) by {$username}");
333
+	}
334
+
335
+	/**
336
+	 * Summary of sentMail
337
+	 *
338
+	 * @param Request $request
339
+	 */
340
+	public function sentMail(Request $request)
341
+	{
342
+		$this->send($this->currentUser->getUsername()
343
+			. " sent an email related to Request {$request->getId()} ({$request->getName()})");
344
+	}
345
+
346
+	#endregion
347
+
348
+	#region reservations
349
+
350
+	/**
351
+	 * Summary of requestReserved
352
+	 *
353
+	 * @param Request $request
354
+	 */
355
+	public function requestReserved(Request $request)
356
+	{
357
+		$username = $this->currentUser->getUsername();
358
+
359
+		$this->send("Request {$request->getId()} ({$request->getName()}) reserved by {$username}");
360
+	}
361
+
362
+	/**
363
+	 * Summary of requestReserveBroken
364
+	 *
365
+	 * @param Request $request
366
+	 */
367
+	public function requestReserveBroken(Request $request)
368
+	{
369
+		$username = $this->currentUser->getUsername();
370
+
371
+		$this->send("Reservation on request {$request->getId()} ({$request->getName()}) broken by {$username}");
372
+	}
373
+
374
+	/**
375
+	 * Summary of requestUnreserved
376
+	 *
377
+	 * @param Request $request
378
+	 */
379
+	public function requestUnreserved(Request $request)
380
+	{
381
+		$this->send("Request {$request->getId()} ({$request->getName()}) is no longer being handled.");
382
+	}
383
+
384
+	/**
385
+	 * Summary of requestReservationSent
386
+	 *
387
+	 * @param Request $request
388
+	 * @param User    $target
389
+	 */
390
+	public function requestReservationSent(Request $request, User $target)
391
+	{
392
+		$username = $this->currentUser->getUsername();
393
+
394
+		$this->send(
395
+			"Reservation of request {$request->getId()} ({$request->getName()}) sent to {$target->getUsername()} by "
396
+			. $username);
397
+	}
398
+
399
+	#endregion
400
+
401
+	#region comments
402
+
403
+	/**
404
+	 * Summary of commentCreated
405
+	 *
406
+	 * @param Comment $comment
407
+	 * @param Request $request
408
+	 */
409
+	public function commentCreated(Comment $comment, Request $request)
410
+	{
411
+		$username = $this->currentUser->getUsername();
412
+		$visibility = ($comment->getVisibility() == "admin" ? "private " : "");
413
+
414
+		$this->send("{$username} posted a {$visibility}comment on request {$request->getId()} ({$request->getName()})");
415
+	}
416
+
417
+	/**
418
+	 * Summary of commentEdited
419
+	 *
420
+	 * @param Comment $comment
421
+	 * @param Request $request
422
+	 */
423
+	public function commentEdited(Comment $comment, Request $request)
424
+	{
425
+		$username = $this->currentUser->getUsername();
426
+
427
+		$this->send(<<<TAG
428 428
 Comment {$comment->getId()} on request {$request->getId()} ({$request->getName()}) edited by {$username}
429 429
 TAG
430
-        );
431
-    }
432
-
433
-    #endregion
434
-
435
-    #region email management (close reasons)
436
-
437
-    /**
438
-     * Summary of emailCreated
439
-     *
440
-     * @param EmailTemplate $template
441
-     */
442
-    public function emailCreated(EmailTemplate $template)
443
-    {
444
-        $username = $this->currentUser->getUsername();
445
-        $this->send("Email {$template->getId()} ({$template->getName()}) created by " . $username);
446
-    }
447
-
448
-    /**
449
-     * Summary of emailEdited
450
-     *
451
-     * @param EmailTemplate $template
452
-     */
453
-    public function emailEdited(EmailTemplate $template)
454
-    {
455
-        $username = $this->currentUser->getUsername();
456
-        $this->send("Email {$template->getId()} ({$template->getName()}) edited by " . $username);
457
-    }
458
-    #endregion
430
+		);
431
+	}
432
+
433
+	#endregion
434
+
435
+	#region email management (close reasons)
436
+
437
+	/**
438
+	 * Summary of emailCreated
439
+	 *
440
+	 * @param EmailTemplate $template
441
+	 */
442
+	public function emailCreated(EmailTemplate $template)
443
+	{
444
+		$username = $this->currentUser->getUsername();
445
+		$this->send("Email {$template->getId()} ({$template->getName()}) created by " . $username);
446
+	}
447
+
448
+	/**
449
+	 * Summary of emailEdited
450
+	 *
451
+	 * @param EmailTemplate $template
452
+	 */
453
+	public function emailEdited(EmailTemplate $template)
454
+	{
455
+		$username = $this->currentUser->getUsername();
456
+		$this->send("Email {$template->getId()} ({$template->getName()}) edited by " . $username);
457
+	}
458
+	#endregion
459 459
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -89,7 +89,7 @@  discard block
 block discarded – undo
89 89
         $blacklist = array("DCC", "CCTP", "PRIVMSG");
90 90
         $message = str_replace($blacklist, "(IRC Blacklist)", $message); // Lets stop DCC etc
91 91
 
92
-        $msg = IrcColourCode::RESET . IrcColourCode::BOLD . "[$instanceName]" . IrcColourCode::RESET . ": $message";
92
+        $msg = IrcColourCode::RESET.IrcColourCode::BOLD."[$instanceName]".IrcColourCode::RESET.": $message";
93 93
 
94 94
         try {
95 95
             $notification = new Notification();
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
      */
128 128
     public function userApproved(User $user)
129 129
     {
130
-        $this->send("{$user->getUsername()} approved by " . $this->currentUser->getUsername());
130
+        $this->send("{$user->getUsername()} approved by ".$this->currentUser->getUsername());
131 131
     }
132 132
 
133 133
     /**
@@ -138,7 +138,7 @@  discard block
 block discarded – undo
138 138
      */
139 139
     public function userDeclined(User $user, $reason)
140 140
     {
141
-        $this->send("{$user->getUsername()} declined by " . $this->currentUser->getUsername() . " ($reason)");
141
+        $this->send("{$user->getUsername()} declined by ".$this->currentUser->getUsername()." ($reason)");
142 142
     }
143 143
 
144 144
     /**
@@ -149,7 +149,7 @@  discard block
 block discarded – undo
149 149
      */
150 150
     public function userSuspended(User $user, $reason)
151 151
     {
152
-        $this->send("{$user->getUsername()} suspended by " . $this->currentUser->getUsername() . " ($reason)");
152
+        $this->send("{$user->getUsername()} suspended by ".$this->currentUser->getUsername()." ($reason)");
153 153
     }
154 154
 
155 155
     /**
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
      */
160 160
     public function userPrefChange(User $user)
161 161
     {
162
-        $this->send("{$user->getUsername()}'s preferences were changed by " . $this->currentUser->getUsername());
162
+        $this->send("{$user->getUsername()}'s preferences were changed by ".$this->currentUser->getUsername());
163 163
     }
164 164
 
165 165
     /**
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
      */
171 171
     public function userRenamed(User $user, $old)
172 172
     {
173
-        $this->send($this->currentUser->getUsername() . " renamed $old to {$user->getUsername()}");
173
+        $this->send($this->currentUser->getUsername()." renamed $old to {$user->getUsername()}");
174 174
     }
175 175
 
176 176
     /**
@@ -180,7 +180,7 @@  discard block
 block discarded – undo
180 180
     public function userRolesEdited(User $user, $reason)
181 181
     {
182 182
         $currentUser = $this->currentUser->getUsername();
183
-        $this->send("Active roles for {$user->getUsername()} changed by " . $currentUser . " ($reason)");
183
+        $this->send("Active roles for {$user->getUsername()} changed by ".$currentUser." ($reason)");
184 184
     }
185 185
 
186 186
     #endregion
@@ -192,7 +192,7 @@  discard block
 block discarded – undo
192 192
      */
193 193
     public function siteNoticeEdited()
194 194
     {
195
-        $this->send("Site notice edited by " . $this->currentUser->getUsername());
195
+        $this->send("Site notice edited by ".$this->currentUser->getUsername());
196 196
     }
197 197
     #endregion
198 198
 
@@ -204,7 +204,7 @@  discard block
 block discarded – undo
204 204
      */
205 205
     public function welcomeTemplateCreated(WelcomeTemplate $template)
206 206
     {
207
-        $this->send("Welcome template {$template->getId()} created by " . $this->currentUser->getUsername());
207
+        $this->send("Welcome template {$template->getId()} created by ".$this->currentUser->getUsername());
208 208
     }
209 209
 
210 210
     /**
@@ -214,7 +214,7 @@  discard block
 block discarded – undo
214 214
      */
215 215
     public function welcomeTemplateDeleted($templateid)
216 216
     {
217
-        $this->send("Welcome template {$templateid} deleted by " . $this->currentUser->getUsername());
217
+        $this->send("Welcome template {$templateid} deleted by ".$this->currentUser->getUsername());
218 218
     }
219 219
 
220 220
     /**
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
      */
225 225
     public function welcomeTemplateEdited(WelcomeTemplate $template)
226 226
     {
227
-        $this->send("Welcome template {$template->getId()} edited by " . $this->currentUser->getUsername());
227
+        $this->send("Welcome template {$template->getId()} edited by ".$this->currentUser->getUsername());
228 228
     }
229 229
 
230 230
     #endregion
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
             $duration = "indefinitely";
242 242
         }
243 243
         else {
244
-            $duration = "until " . date("F j, Y, g:i a", $ban->getDuration());
244
+            $duration = "until ".date("F j, Y, g:i a", $ban->getDuration());
245 245
         }
246 246
 
247 247
         $username = $this->currentUser->getUsername();
@@ -257,8 +257,8 @@  discard block
 block discarded – undo
257 257
      */
258 258
     public function unbanned(Ban $ban, $unbanreason)
259 259
     {
260
-        $this->send($ban->getTarget() . " unbanned by " . $this->currentUser
261
-                ->getUsername() . " (" . $unbanreason . ")");
260
+        $this->send($ban->getTarget()." unbanned by ".$this->currentUser
261
+                ->getUsername()." (".$unbanreason.")");
262 262
     }
263 263
 
264 264
     #endregion
@@ -273,15 +273,15 @@  discard block
 block discarded – undo
273 273
     public function requestReceived(Request $request)
274 274
     {
275 275
         $this->send(
276
-            IrcColourCode::DARK_GREY . "[["
277
-            . IrcColourCode::DARK_GREEN . "acc:"
278
-            . IrcColourCode::ORANGE . $request->getId()
279
-            . IrcColourCode::DARK_GREY . "]]"
280
-            . IrcColourCode::RED . " N "
281
-            . IrcColourCode::DARK_BLUE . $this->baseUrl . "/internal.php/viewRequest?id={$request->getId()} "
282
-            . IrcColourCode::DARK_RED . "* "
283
-            . IrcColourCode::DARK_GREEN . $request->getName()
284
-            . IrcColourCode::DARK_RED . " * "
276
+            IrcColourCode::DARK_GREY."[["
277
+            . IrcColourCode::DARK_GREEN."acc:"
278
+            . IrcColourCode::ORANGE.$request->getId()
279
+            . IrcColourCode::DARK_GREY."]]"
280
+            . IrcColourCode::RED." N "
281
+            . IrcColourCode::DARK_BLUE.$this->baseUrl."/internal.php/viewRequest?id={$request->getId()} "
282
+            . IrcColourCode::DARK_RED."* "
283
+            . IrcColourCode::DARK_GREEN.$request->getName()
284
+            . IrcColourCode::DARK_RED." * "
285 285
             . IrcColourCode::RESET
286 286
         );
287 287
     }
@@ -442,7 +442,7 @@  discard block
 block discarded – undo
442 442
     public function emailCreated(EmailTemplate $template)
443 443
     {
444 444
         $username = $this->currentUser->getUsername();
445
-        $this->send("Email {$template->getId()} ({$template->getName()}) created by " . $username);
445
+        $this->send("Email {$template->getId()} ({$template->getName()}) created by ".$username);
446 446
     }
447 447
 
448 448
     /**
@@ -453,7 +453,7 @@  discard block
 block discarded – undo
453 453
     public function emailEdited(EmailTemplate $template)
454 454
     {
455 455
         $username = $this->currentUser->getUsername();
456
-        $this->send("Email {$template->getId()} ({$template->getName()}) edited by " . $username);
456
+        $this->send("Email {$template->getId()} ({$template->getName()}) edited by ".$username);
457 457
     }
458 458
     #endregion
459 459
 }
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageDeferRequest.php 1 patch
Indentation   +67 added lines, -67 removed lines patch added patch discarded remove patch
@@ -20,71 +20,71 @@
 block discarded – undo
20 20
 
21 21
 class PageDeferRequest extends RequestActionBase
22 22
 {
23
-    /**
24
-     * Main function for this page, when no specific actions are called.
25
-     * @throws ApplicationLogicException
26
-     */
27
-    protected function main()
28
-    {
29
-        $this->checkPosted();
30
-        $database = $this->getDatabase();
31
-        $request = $this->getRequest($database);
32
-        $currentUser = User::getCurrent($database);
33
-
34
-        $target = WebRequest::postString('target');
35
-        $requestStates = $this->getSiteConfiguration()->getRequestStates();
36
-
37
-        if (!array_key_exists($target, $requestStates)) {
38
-            throw new ApplicationLogicException('Defer target not valid');
39
-        }
40
-
41
-        if ($request->getStatus() == $target) {
42
-            SessionAlert::warning('This request is already in the specified queue.');
43
-            $this->redirect('viewRequest', null, array('id' => $request->getId()));
44
-
45
-            return;
46
-        }
47
-
48
-        $closureDate = $request->getClosureDate();
49
-        $date = new DateTime();
50
-        $date->modify("-7 days");
51
-        $oneweek = $date->format("Y-m-d H:i:s");
52
-
53
-
54
-        if ($request->getStatus() == "Closed" && $closureDate < $oneweek) {
55
-            if (!$this->barrierTest('reopenOldRequest', $currentUser, 'RequestData')) {
56
-                throw new ApplicationLogicException(
57
-                    "You are not allowed to re-open a request that has been closed for over a week.");
58
-            }
59
-        }
60
-
61
-        if ($request->getStatus() === RequestStatus::JOBQUEUE) {
62
-            /** @var JobQueue[] $pendingJobs */
63
-            $pendingJobs = JobQueueSearchHelper::get($database)->byRequest($request->getId())->statusIn([
64
-                JobQueue::STATUS_READY,
65
-                JobQueue::STATUS_WAITING,
66
-            ])->fetch();
67
-
68
-            foreach ($pendingJobs as $job) {
69
-                $job->setStatus(JobQueue::STATUS_CANCELLED);
70
-                $job->setError('Cancelled by request deferral');
71
-                $job->save();
72
-            }
73
-        }
74
-
75
-        $request->setReserved(null);
76
-        $request->setStatus($target);
77
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
78
-        $request->save();
79
-
80
-        $deto = $requestStates[$target]['deferto'];
81
-        $detolog = $requestStates[$target]['defertolog'];
82
-
83
-        Logger::deferRequest($database, $request, $detolog);
84
-
85
-        $this->getNotificationHelper()->requestDeferred($request);
86
-        SessionAlert::success("Request {$request->getId()} deferred to {$deto}");
87
-
88
-        $this->redirect();
89
-    }
23
+	/**
24
+	 * Main function for this page, when no specific actions are called.
25
+	 * @throws ApplicationLogicException
26
+	 */
27
+	protected function main()
28
+	{
29
+		$this->checkPosted();
30
+		$database = $this->getDatabase();
31
+		$request = $this->getRequest($database);
32
+		$currentUser = User::getCurrent($database);
33
+
34
+		$target = WebRequest::postString('target');
35
+		$requestStates = $this->getSiteConfiguration()->getRequestStates();
36
+
37
+		if (!array_key_exists($target, $requestStates)) {
38
+			throw new ApplicationLogicException('Defer target not valid');
39
+		}
40
+
41
+		if ($request->getStatus() == $target) {
42
+			SessionAlert::warning('This request is already in the specified queue.');
43
+			$this->redirect('viewRequest', null, array('id' => $request->getId()));
44
+
45
+			return;
46
+		}
47
+
48
+		$closureDate = $request->getClosureDate();
49
+		$date = new DateTime();
50
+		$date->modify("-7 days");
51
+		$oneweek = $date->format("Y-m-d H:i:s");
52
+
53
+
54
+		if ($request->getStatus() == "Closed" && $closureDate < $oneweek) {
55
+			if (!$this->barrierTest('reopenOldRequest', $currentUser, 'RequestData')) {
56
+				throw new ApplicationLogicException(
57
+					"You are not allowed to re-open a request that has been closed for over a week.");
58
+			}
59
+		}
60
+
61
+		if ($request->getStatus() === RequestStatus::JOBQUEUE) {
62
+			/** @var JobQueue[] $pendingJobs */
63
+			$pendingJobs = JobQueueSearchHelper::get($database)->byRequest($request->getId())->statusIn([
64
+				JobQueue::STATUS_READY,
65
+				JobQueue::STATUS_WAITING,
66
+			])->fetch();
67
+
68
+			foreach ($pendingJobs as $job) {
69
+				$job->setStatus(JobQueue::STATUS_CANCELLED);
70
+				$job->setError('Cancelled by request deferral');
71
+				$job->save();
72
+			}
73
+		}
74
+
75
+		$request->setReserved(null);
76
+		$request->setStatus($target);
77
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
78
+		$request->save();
79
+
80
+		$deto = $requestStates[$target]['deferto'];
81
+		$detolog = $requestStates[$target]['defertolog'];
82
+
83
+		Logger::deferRequest($database, $request, $detolog);
84
+
85
+		$this->getNotificationHelper()->requestDeferred($request);
86
+		SessionAlert::success("Request {$request->getId()} deferred to {$deto}");
87
+
88
+		$this->redirect();
89
+	}
90 90
 }
Please login to merge, or discard this patch.
includes/Pages/PageExpandedRequestList.php 1 patch
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -16,65 +16,65 @@
 block discarded – undo
16 16
 
17 17
 class PageExpandedRequestList extends InternalPageBase
18 18
 {
19
-    use RequestListData;
19
+	use RequestListData;
20 20
 
21
-    /**
22
-     * Main function for this page, when no specific actions are called.
23
-     * @return void
24
-     * @todo This is very similar to the PageMain code, we could probably generalise this somehow
25
-     */
26
-    protected function main()
27
-    {
28
-        $config = $this->getSiteConfiguration();
21
+	/**
22
+	 * Main function for this page, when no specific actions are called.
23
+	 * @return void
24
+	 * @todo This is very similar to the PageMain code, we could probably generalise this somehow
25
+	 */
26
+	protected function main()
27
+	{
28
+		$config = $this->getSiteConfiguration();
29 29
 
30
-        $requestedStatus = WebRequest::getString('status');
31
-        $requestStates = $config->getRequestStates();
30
+		$requestedStatus = WebRequest::getString('status');
31
+		$requestStates = $config->getRequestStates();
32 32
 
33
-        if ($requestedStatus !== null && isset($requestStates[$requestedStatus])) {
33
+		if ($requestedStatus !== null && isset($requestStates[$requestedStatus])) {
34 34
 
35
-            $this->assignCSRFToken();
35
+			$this->assignCSRFToken();
36 36
 
37
-            $database = $this->getDatabase();
37
+			$database = $this->getDatabase();
38 38
 
39
-            $help = $requestStates[$requestedStatus]['queuehelp'];
40
-            $this->assign('queuehelp', $help);
39
+			$help = $requestStates[$requestedStatus]['queuehelp'];
40
+			$this->assign('queuehelp', $help);
41 41
 
42
-            if ($config->getEmailConfirmationEnabled()) {
43
-                $query = "SELECT * FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
44
-                $totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
45
-            }
46
-            else {
47
-                $query = "SELECT * FROM request WHERE status = :type;";
48
-                $totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type;";
49
-            }
42
+			if ($config->getEmailConfirmationEnabled()) {
43
+				$query = "SELECT * FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
44
+				$totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
45
+			}
46
+			else {
47
+				$query = "SELECT * FROM request WHERE status = :type;";
48
+				$totalQuery = "SELECT COUNT(id) FROM request WHERE status = :type;";
49
+			}
50 50
 
51
-            $statement = $database->prepare($query);
52
-            $totalRequestsStatement = $database->prepare($totalQuery);
51
+			$statement = $database->prepare($query);
52
+			$totalRequestsStatement = $database->prepare($totalQuery);
53 53
 
54
-            $statement->bindValue(":type", $requestedStatus);
55
-            $statement->execute();
54
+			$statement->bindValue(":type", $requestedStatus);
55
+			$statement->execute();
56 56
 
57
-            $requests = $statement->fetchAll(PDO::FETCH_CLASS, Request::class);
57
+			$requests = $statement->fetchAll(PDO::FETCH_CLASS, Request::class);
58 58
 
59
-            /** @var Request $req */
60
-            foreach ($requests as $req) {
61
-                $req->setDatabase($database);
62
-            }
59
+			/** @var Request $req */
60
+			foreach ($requests as $req) {
61
+				$req->setDatabase($database);
62
+			}
63 63
 
64
-            $this->assign('requests', $this->prepareRequestData($requests));
65
-            $this->assign('header', $requestedStatus);
66
-            $this->assign('requestLimitShowOnly', $config->getMiserModeLimit());
67
-            $this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
64
+			$this->assign('requests', $this->prepareRequestData($requests));
65
+			$this->assign('header', $requestedStatus);
66
+			$this->assign('requestLimitShowOnly', $config->getMiserModeLimit());
67
+			$this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
68 68
 
69
-            $totalRequestsStatement->bindValue(':type', $requestedStatus);
70
-            $totalRequestsStatement->execute();
71
-            $totalRequests = $totalRequestsStatement->fetchColumn();
72
-            $totalRequestsStatement->closeCursor();
73
-            $this->assign('totalRequests', $totalRequests);
69
+			$totalRequestsStatement->bindValue(':type', $requestedStatus);
70
+			$totalRequestsStatement->execute();
71
+			$totalRequests = $totalRequestsStatement->fetchColumn();
72
+			$totalRequestsStatement->closeCursor();
73
+			$this->assign('totalRequests', $totalRequests);
74 74
 
75 75
 
76
-            $this->setHtmlTitle('{$header|escape}{if $totalRequests > 0} [{$totalRequests|escape}]{/if}');
77
-            $this->setTemplate('mainpage/expandedrequestlist.tpl');
78
-        }
79
-    }
76
+			$this->setHtmlTitle('{$header|escape}{if $totalRequests > 0} [{$totalRequests|escape}]{/if}');
77
+			$this->setTemplate('mainpage/expandedrequestlist.tpl');
78
+		}
79
+	}
80 80
 }
Please login to merge, or discard this patch.