@@ -12,100 +12,100 @@ |
||
12 | 12 | |
13 | 13 | class ContentSecurityPolicyManager |
14 | 14 | { |
15 | - private $policy = [ |
|
16 | - 'default-src' => [], |
|
17 | - 'script-src' => ['self', 'nonce'], |
|
18 | - 'script-src-elem' => ['self', 'nonce'], |
|
19 | - 'script-src-attr' => [], |
|
20 | - 'connect-src' => ['self'], |
|
21 | - 'style-src' => ['self'], |
|
22 | - 'style-src-elem' => ['self'], |
|
23 | - 'style-src-attr' => [], |
|
24 | - 'img-src' => ['self', 'data:', 'https://upload.wikimedia.org', 'https://accounts-dev.wmflabs.org/'], |
|
25 | - 'font-src' => ['self'], |
|
26 | - 'form-action' => ['self', 'oauth'], |
|
27 | - 'frame-ancestors' => [], |
|
28 | - ]; |
|
29 | - private $nonce = null; |
|
30 | - private $reportOnly = false; |
|
31 | - /** |
|
32 | - * @var SiteConfiguration |
|
33 | - */ |
|
34 | - private $configuration; |
|
15 | + private $policy = [ |
|
16 | + 'default-src' => [], |
|
17 | + 'script-src' => ['self', 'nonce'], |
|
18 | + 'script-src-elem' => ['self', 'nonce'], |
|
19 | + 'script-src-attr' => [], |
|
20 | + 'connect-src' => ['self'], |
|
21 | + 'style-src' => ['self'], |
|
22 | + 'style-src-elem' => ['self'], |
|
23 | + 'style-src-attr' => [], |
|
24 | + 'img-src' => ['self', 'data:', 'https://upload.wikimedia.org', 'https://accounts-dev.wmflabs.org/'], |
|
25 | + 'font-src' => ['self'], |
|
26 | + 'form-action' => ['self', 'oauth'], |
|
27 | + 'frame-ancestors' => [], |
|
28 | + ]; |
|
29 | + private $nonce = null; |
|
30 | + private $reportOnly = false; |
|
31 | + /** |
|
32 | + * @var SiteConfiguration |
|
33 | + */ |
|
34 | + private $configuration; |
|
35 | 35 | |
36 | - /** |
|
37 | - * ContentSecurityPolicyManager constructor. |
|
38 | - * |
|
39 | - * @param SiteConfiguration $configuration |
|
40 | - */ |
|
41 | - public function __construct(SiteConfiguration $configuration) |
|
42 | - { |
|
43 | - $this->configuration = $configuration; |
|
44 | - } |
|
36 | + /** |
|
37 | + * ContentSecurityPolicyManager constructor. |
|
38 | + * |
|
39 | + * @param SiteConfiguration $configuration |
|
40 | + */ |
|
41 | + public function __construct(SiteConfiguration $configuration) |
|
42 | + { |
|
43 | + $this->configuration = $configuration; |
|
44 | + } |
|
45 | 45 | |
46 | - public function getNonce() |
|
47 | - { |
|
48 | - if ($this->nonce === null) { |
|
49 | - $this->nonce = base64_encode(openssl_random_pseudo_bytes(32)); |
|
50 | - } |
|
46 | + public function getNonce() |
|
47 | + { |
|
48 | + if ($this->nonce === null) { |
|
49 | + $this->nonce = base64_encode(openssl_random_pseudo_bytes(32)); |
|
50 | + } |
|
51 | 51 | |
52 | - return $this->nonce; |
|
53 | - } |
|
52 | + return $this->nonce; |
|
53 | + } |
|
54 | 54 | |
55 | - public function getHeader(): string |
|
56 | - { |
|
57 | - $reportOnly = ''; |
|
58 | - if ($this->reportOnly) { |
|
59 | - $reportOnly = '-Report-Only'; |
|
60 | - } |
|
55 | + public function getHeader(): string |
|
56 | + { |
|
57 | + $reportOnly = ''; |
|
58 | + if ($this->reportOnly) { |
|
59 | + $reportOnly = '-Report-Only'; |
|
60 | + } |
|
61 | 61 | |
62 | - $constructedPolicy = "Content-Security-Policy{$reportOnly}: "; |
|
62 | + $constructedPolicy = "Content-Security-Policy{$reportOnly}: "; |
|
63 | 63 | |
64 | - foreach ($this->policy as $item => $values) { |
|
65 | - $constructedPolicy .= $item . ' '; |
|
66 | - $policyIsSet = false; |
|
64 | + foreach ($this->policy as $item => $values) { |
|
65 | + $constructedPolicy .= $item . ' '; |
|
66 | + $policyIsSet = false; |
|
67 | 67 | |
68 | - if (count($values) > 0) { |
|
69 | - foreach ($values as $value) { |
|
70 | - switch ($value) { |
|
71 | - case 'none': |
|
72 | - case 'self': |
|
73 | - case 'strict-dynamic': |
|
74 | - $policyIsSet = true; |
|
75 | - $constructedPolicy .= "'{$value}' "; |
|
76 | - break; |
|
77 | - case 'nonce': |
|
78 | - if ($this->nonce !== null) { |
|
79 | - $policyIsSet = true; |
|
80 | - $constructedPolicy .= "'nonce-{$this->nonce}' "; |
|
81 | - } |
|
82 | - break; |
|
83 | - case 'oauth': |
|
84 | - $policyIsSet = true; |
|
85 | - $constructedPolicy .= "{$this->configuration->getOauthMediaWikiCanonicalServer()} "; |
|
86 | - break; |
|
87 | - default: |
|
88 | - $policyIsSet = true; |
|
89 | - $constructedPolicy .= $value . ' '; |
|
90 | - break; |
|
91 | - } |
|
92 | - } |
|
68 | + if (count($values) > 0) { |
|
69 | + foreach ($values as $value) { |
|
70 | + switch ($value) { |
|
71 | + case 'none': |
|
72 | + case 'self': |
|
73 | + case 'strict-dynamic': |
|
74 | + $policyIsSet = true; |
|
75 | + $constructedPolicy .= "'{$value}' "; |
|
76 | + break; |
|
77 | + case 'nonce': |
|
78 | + if ($this->nonce !== null) { |
|
79 | + $policyIsSet = true; |
|
80 | + $constructedPolicy .= "'nonce-{$this->nonce}' "; |
|
81 | + } |
|
82 | + break; |
|
83 | + case 'oauth': |
|
84 | + $policyIsSet = true; |
|
85 | + $constructedPolicy .= "{$this->configuration->getOauthMediaWikiCanonicalServer()} "; |
|
86 | + break; |
|
87 | + default: |
|
88 | + $policyIsSet = true; |
|
89 | + $constructedPolicy .= $value . ' '; |
|
90 | + break; |
|
91 | + } |
|
92 | + } |
|
93 | 93 | |
94 | - if (!$policyIsSet) { |
|
95 | - $constructedPolicy .= "'none' "; |
|
96 | - } |
|
97 | - } |
|
98 | - else { |
|
99 | - $constructedPolicy .= "'none' "; |
|
100 | - } |
|
94 | + if (!$policyIsSet) { |
|
95 | + $constructedPolicy .= "'none' "; |
|
96 | + } |
|
97 | + } |
|
98 | + else { |
|
99 | + $constructedPolicy .= "'none' "; |
|
100 | + } |
|
101 | 101 | |
102 | - $constructedPolicy .= '; '; |
|
103 | - } |
|
102 | + $constructedPolicy .= '; '; |
|
103 | + } |
|
104 | 104 | |
105 | - if ($this->configuration->getCspReportUri() !== null) { |
|
106 | - $constructedPolicy .= 'report-uri ' . $this->configuration->getCspReportUri(); |
|
107 | - } |
|
105 | + if ($this->configuration->getCspReportUri() !== null) { |
|
106 | + $constructedPolicy .= 'report-uri ' . $this->configuration->getCspReportUri(); |
|
107 | + } |
|
108 | 108 | |
109 | - return $constructedPolicy; |
|
110 | - } |
|
109 | + return $constructedPolicy; |
|
110 | + } |
|
111 | 111 | } |
@@ -62,7 +62,7 @@ discard block |
||
62 | 62 | $constructedPolicy = "Content-Security-Policy{$reportOnly}: "; |
63 | 63 | |
64 | 64 | foreach ($this->policy as $item => $values) { |
65 | - $constructedPolicy .= $item . ' '; |
|
65 | + $constructedPolicy .= $item.' '; |
|
66 | 66 | $policyIsSet = false; |
67 | 67 | |
68 | 68 | if (count($values) > 0) { |
@@ -86,7 +86,7 @@ discard block |
||
86 | 86 | break; |
87 | 87 | default: |
88 | 88 | $policyIsSet = true; |
89 | - $constructedPolicy .= $value . ' '; |
|
89 | + $constructedPolicy .= $value.' '; |
|
90 | 90 | break; |
91 | 91 | } |
92 | 92 | } |
@@ -103,7 +103,7 @@ discard block |
||
103 | 103 | } |
104 | 104 | |
105 | 105 | if ($this->configuration->getCspReportUri() !== null) { |
106 | - $constructedPolicy .= 'report-uri ' . $this->configuration->getCspReportUri(); |
|
106 | + $constructedPolicy .= 'report-uri '.$this->configuration->getCspReportUri(); |
|
107 | 107 | } |
108 | 108 | |
109 | 109 | return $constructedPolicy; |
@@ -24,316 +24,316 @@ |
||
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 | } |
@@ -19,137 +19,137 @@ |
||
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 | } |
@@ -91,7 +91,7 @@ |
||
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); |
@@ -8,17 +8,17 @@ |
||
8 | 8 | |
9 | 9 | function smarty_modifier_iphex($input) |
10 | 10 | { |
11 | - $output = $input; |
|
11 | + $output = $input; |
|
12 | 12 | |
13 | - if(filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false){ |
|
14 | - $octets = explode('.', $input); |
|
15 | - $output = ''; |
|
16 | - foreach ($octets as $octet){ |
|
17 | - $output .= str_pad(dechex($octet), 2, '0', STR_PAD_LEFT); |
|
18 | - } |
|
13 | + if(filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false){ |
|
14 | + $octets = explode('.', $input); |
|
15 | + $output = ''; |
|
16 | + foreach ($octets as $octet){ |
|
17 | + $output .= str_pad(dechex($octet), 2, '0', STR_PAD_LEFT); |
|
18 | + } |
|
19 | 19 | |
20 | - $output = str_pad($output, 32, '0', STR_PAD_LEFT); |
|
21 | - } |
|
20 | + $output = str_pad($output, 32, '0', STR_PAD_LEFT); |
|
21 | + } |
|
22 | 22 | |
23 | - return $output; |
|
23 | + return $output; |
|
24 | 24 | } |
@@ -10,10 +10,10 @@ |
||
10 | 10 | { |
11 | 11 | $output = $input; |
12 | 12 | |
13 | - if(filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false){ |
|
13 | + if (filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) { |
|
14 | 14 | $octets = explode('.', $input); |
15 | 15 | $output = ''; |
16 | - foreach ($octets as $octet){ |
|
16 | + foreach ($octets as $octet) { |
|
17 | 17 | $output .= str_pad(dechex($octet), 2, '0', STR_PAD_LEFT); |
18 | 18 | } |
19 | 19 |
@@ -10,10 +10,10 @@ |
||
10 | 10 | { |
11 | 11 | $output = $input; |
12 | 12 | |
13 | - if(filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false){ |
|
13 | + if(filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) { |
|
14 | 14 | $octets = explode('.', $input); |
15 | 15 | $output = ''; |
16 | - foreach ($octets as $octet){ |
|
16 | + foreach ($octets as $octet) { |
|
17 | 17 | $output .= str_pad(dechex($octet), 2, '0', STR_PAD_LEFT); |
18 | 18 | } |
19 | 19 |
@@ -26,434 +26,434 @@ |
||
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 | } |
@@ -89,7 +89,7 @@ discard block |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 |
||
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 | } |
@@ -20,71 +20,71 @@ |
||
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 | } |
@@ -16,65 +16,65 @@ |
||
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 | } |
@@ -19,54 +19,54 @@ discard block |
||
19 | 19 | |
20 | 20 | class PageMain extends InternalPageBase |
21 | 21 | { |
22 | - use RequestListData; |
|
23 | - |
|
24 | - /** |
|
25 | - * Main function for this page, when no actions are called. |
|
26 | - */ |
|
27 | - protected function main() |
|
28 | - { |
|
29 | - $this->assignCSRFToken(); |
|
30 | - |
|
31 | - $config = $this->getSiteConfiguration(); |
|
32 | - $database = $this->getDatabase(); |
|
33 | - $currentUser = User::getCurrent($database); |
|
34 | - |
|
35 | - // general template configuration |
|
36 | - $this->assign('defaultRequestState', $config->getDefaultRequestStateKey()); |
|
37 | - $this->assign('requestLimitShowOnly', $config->getMiserModeLimit()); |
|
38 | - |
|
39 | - $seeAllRequests = $this->barrierTest('seeAllRequests', $currentUser, PageViewRequest::class); |
|
40 | - |
|
41 | - // Fetch request data |
|
42 | - $requestSectionData = array(); |
|
43 | - if ($seeAllRequests) { |
|
44 | - $this->setupStatusSections($database, $config, $requestSectionData); |
|
45 | - $this->setupHospitalQueue($database, $config, $requestSectionData); |
|
46 | - $this->setupJobQueue($database, $config, $requestSectionData); |
|
47 | - } |
|
48 | - $this->setupLastFiveClosedData($database, $seeAllRequests); |
|
49 | - |
|
50 | - // Assign data to template |
|
51 | - $this->assign('requestSectionData', $requestSectionData); |
|
52 | - |
|
53 | - $this->setTemplate('mainpage/mainpage.tpl'); |
|
54 | - } |
|
55 | - |
|
56 | - /** |
|
57 | - * @param PdoDatabase $database |
|
58 | - * @param bool $seeAllRequests |
|
59 | - * |
|
60 | - * @internal param User $currentUser |
|
61 | - */ |
|
62 | - private function setupLastFiveClosedData(PdoDatabase $database, $seeAllRequests) |
|
63 | - { |
|
64 | - $this->assign('showLastFive', $seeAllRequests); |
|
65 | - if (!$seeAllRequests) { |
|
66 | - return; |
|
67 | - } |
|
68 | - |
|
69 | - $query = <<<SQL |
|
22 | + use RequestListData; |
|
23 | + |
|
24 | + /** |
|
25 | + * Main function for this page, when no actions are called. |
|
26 | + */ |
|
27 | + protected function main() |
|
28 | + { |
|
29 | + $this->assignCSRFToken(); |
|
30 | + |
|
31 | + $config = $this->getSiteConfiguration(); |
|
32 | + $database = $this->getDatabase(); |
|
33 | + $currentUser = User::getCurrent($database); |
|
34 | + |
|
35 | + // general template configuration |
|
36 | + $this->assign('defaultRequestState', $config->getDefaultRequestStateKey()); |
|
37 | + $this->assign('requestLimitShowOnly', $config->getMiserModeLimit()); |
|
38 | + |
|
39 | + $seeAllRequests = $this->barrierTest('seeAllRequests', $currentUser, PageViewRequest::class); |
|
40 | + |
|
41 | + // Fetch request data |
|
42 | + $requestSectionData = array(); |
|
43 | + if ($seeAllRequests) { |
|
44 | + $this->setupStatusSections($database, $config, $requestSectionData); |
|
45 | + $this->setupHospitalQueue($database, $config, $requestSectionData); |
|
46 | + $this->setupJobQueue($database, $config, $requestSectionData); |
|
47 | + } |
|
48 | + $this->setupLastFiveClosedData($database, $seeAllRequests); |
|
49 | + |
|
50 | + // Assign data to template |
|
51 | + $this->assign('requestSectionData', $requestSectionData); |
|
52 | + |
|
53 | + $this->setTemplate('mainpage/mainpage.tpl'); |
|
54 | + } |
|
55 | + |
|
56 | + /** |
|
57 | + * @param PdoDatabase $database |
|
58 | + * @param bool $seeAllRequests |
|
59 | + * |
|
60 | + * @internal param User $currentUser |
|
61 | + */ |
|
62 | + private function setupLastFiveClosedData(PdoDatabase $database, $seeAllRequests) |
|
63 | + { |
|
64 | + $this->assign('showLastFive', $seeAllRequests); |
|
65 | + if (!$seeAllRequests) { |
|
66 | + return; |
|
67 | + } |
|
68 | + |
|
69 | + $query = <<<SQL |
|
70 | 70 | SELECT request.id, request.name, request.updateversion |
71 | 71 | FROM request /* PageMain::main() */ |
72 | 72 | JOIN log ON log.objectid = request.id AND log.objecttype = 'Request' |
@@ -75,111 +75,111 @@ discard block |
||
75 | 75 | LIMIT 5; |
76 | 76 | SQL; |
77 | 77 | |
78 | - $statement = $database->prepare($query); |
|
79 | - $statement->execute(); |
|
80 | - |
|
81 | - $last5result = $statement->fetchAll(PDO::FETCH_ASSOC); |
|
82 | - |
|
83 | - $this->assign('lastFive', $last5result); |
|
84 | - } |
|
85 | - |
|
86 | - /** |
|
87 | - * @param PdoDatabase $database |
|
88 | - * @param SiteConfiguration $config |
|
89 | - * @param $requestSectionData |
|
90 | - */ |
|
91 | - private function setupHospitalQueue( |
|
92 | - PdoDatabase $database, |
|
93 | - SiteConfiguration $config, |
|
94 | - &$requestSectionData |
|
95 | - ) { |
|
96 | - $search = RequestSearchHelper::get($database) |
|
97 | - ->limit($config->getMiserModeLimit()) |
|
98 | - ->excludingStatus('Closed') |
|
99 | - ->isHospitalised(); |
|
100 | - |
|
101 | - if ($config->getEmailConfirmationEnabled()) { |
|
102 | - $search->withConfirmedEmail(); |
|
103 | - } |
|
104 | - |
|
105 | - $results = $search->getRecordCount($requestCount)->fetch(); |
|
106 | - |
|
107 | - if($requestCount > 0) { |
|
108 | - $requestSectionData['Hospital - Requests failed auto-creation'] = array( |
|
109 | - 'requests' => $this->prepareRequestData($results), |
|
110 | - 'total' => $requestCount, |
|
111 | - 'api' => 'hospital', |
|
112 | - 'type' => 'hospital', |
|
113 | - 'special' => 'Job Queue', |
|
114 | - 'help' => 'This queue lists all the requests which have been attempted to be created in the background, but for which this has failed for one reason or another. Check the job queue to find the error. Requests here may need to be created manually, or it may be possible to re-queue the request for auto-creation by the tool, or it may have been created already. Use your own technical discretion here.', |
|
115 | - 'showAll' => false |
|
116 | - ); |
|
117 | - } |
|
118 | - } |
|
119 | - |
|
120 | - /** |
|
121 | - * @param PdoDatabase $database |
|
122 | - * @param SiteConfiguration $config |
|
123 | - * @param $requestSectionData |
|
124 | - */ |
|
125 | - private function setupJobQueue( |
|
126 | - PdoDatabase $database, |
|
127 | - SiteConfiguration $config, |
|
128 | - &$requestSectionData |
|
129 | - ) { |
|
130 | - $search = RequestSearchHelper::get($database) |
|
131 | - ->limit($config->getMiserModeLimit()) |
|
132 | - ->byStatus(RequestStatus::JOBQUEUE); |
|
133 | - |
|
134 | - if ($config->getEmailConfirmationEnabled()) { |
|
135 | - $search->withConfirmedEmail(); |
|
136 | - } |
|
137 | - |
|
138 | - $results = $search->getRecordCount($requestCount)->fetch(); |
|
139 | - |
|
140 | - if($requestCount > 0) { |
|
141 | - $requestSectionData['Requests queued in the Job Queue'] = array( |
|
142 | - 'requests' => $this->prepareRequestData($results), |
|
143 | - 'total' => $requestCount, |
|
144 | - 'api' => 'JobQueue', |
|
145 | - 'type' => 'JobQueue', |
|
146 | - 'special' => 'Job Queue', |
|
147 | - 'help' => 'This section lists all the requests which are currently waiting to be created by the tool. Requests should automatically disappear from here within a few minutes.', |
|
148 | - 'showAll' => false |
|
149 | - ); |
|
150 | - } |
|
151 | - } |
|
152 | - |
|
153 | - /** |
|
154 | - * @param PdoDatabase $database |
|
155 | - * @param SiteConfiguration $config |
|
156 | - * @param $requestSectionData |
|
157 | - */ |
|
158 | - private function setupStatusSections( |
|
159 | - PdoDatabase $database, |
|
160 | - SiteConfiguration $config, |
|
161 | - &$requestSectionData |
|
162 | - ) { |
|
163 | - $search = RequestSearchHelper::get($database)->limit($config->getMiserModeLimit())->notHospitalised(); |
|
164 | - |
|
165 | - if ($config->getEmailConfirmationEnabled()) { |
|
166 | - $search->withConfirmedEmail(); |
|
167 | - } |
|
168 | - |
|
169 | - $allRequestStates = $config->getRequestStates(); |
|
170 | - $requestsByStatus = $search->fetchByStatus(array_keys($allRequestStates)); |
|
171 | - |
|
172 | - foreach ($allRequestStates as $requestState => $requestStateConfig) { |
|
173 | - |
|
174 | - $requestSectionData[$requestStateConfig['header']] = array( |
|
175 | - 'requests' => $this->prepareRequestData($requestsByStatus[$requestState]['data']), |
|
176 | - 'total' => $requestsByStatus[$requestState]['count'], |
|
177 | - 'api' => $requestStateConfig['api'], |
|
178 | - 'type' => $requestState, |
|
179 | - 'special' => null, |
|
180 | - 'help' => $requestStateConfig['queuehelp'], |
|
181 | - 'showAll' => true |
|
182 | - ); |
|
183 | - } |
|
184 | - } |
|
78 | + $statement = $database->prepare($query); |
|
79 | + $statement->execute(); |
|
80 | + |
|
81 | + $last5result = $statement->fetchAll(PDO::FETCH_ASSOC); |
|
82 | + |
|
83 | + $this->assign('lastFive', $last5result); |
|
84 | + } |
|
85 | + |
|
86 | + /** |
|
87 | + * @param PdoDatabase $database |
|
88 | + * @param SiteConfiguration $config |
|
89 | + * @param $requestSectionData |
|
90 | + */ |
|
91 | + private function setupHospitalQueue( |
|
92 | + PdoDatabase $database, |
|
93 | + SiteConfiguration $config, |
|
94 | + &$requestSectionData |
|
95 | + ) { |
|
96 | + $search = RequestSearchHelper::get($database) |
|
97 | + ->limit($config->getMiserModeLimit()) |
|
98 | + ->excludingStatus('Closed') |
|
99 | + ->isHospitalised(); |
|
100 | + |
|
101 | + if ($config->getEmailConfirmationEnabled()) { |
|
102 | + $search->withConfirmedEmail(); |
|
103 | + } |
|
104 | + |
|
105 | + $results = $search->getRecordCount($requestCount)->fetch(); |
|
106 | + |
|
107 | + if($requestCount > 0) { |
|
108 | + $requestSectionData['Hospital - Requests failed auto-creation'] = array( |
|
109 | + 'requests' => $this->prepareRequestData($results), |
|
110 | + 'total' => $requestCount, |
|
111 | + 'api' => 'hospital', |
|
112 | + 'type' => 'hospital', |
|
113 | + 'special' => 'Job Queue', |
|
114 | + 'help' => 'This queue lists all the requests which have been attempted to be created in the background, but for which this has failed for one reason or another. Check the job queue to find the error. Requests here may need to be created manually, or it may be possible to re-queue the request for auto-creation by the tool, or it may have been created already. Use your own technical discretion here.', |
|
115 | + 'showAll' => false |
|
116 | + ); |
|
117 | + } |
|
118 | + } |
|
119 | + |
|
120 | + /** |
|
121 | + * @param PdoDatabase $database |
|
122 | + * @param SiteConfiguration $config |
|
123 | + * @param $requestSectionData |
|
124 | + */ |
|
125 | + private function setupJobQueue( |
|
126 | + PdoDatabase $database, |
|
127 | + SiteConfiguration $config, |
|
128 | + &$requestSectionData |
|
129 | + ) { |
|
130 | + $search = RequestSearchHelper::get($database) |
|
131 | + ->limit($config->getMiserModeLimit()) |
|
132 | + ->byStatus(RequestStatus::JOBQUEUE); |
|
133 | + |
|
134 | + if ($config->getEmailConfirmationEnabled()) { |
|
135 | + $search->withConfirmedEmail(); |
|
136 | + } |
|
137 | + |
|
138 | + $results = $search->getRecordCount($requestCount)->fetch(); |
|
139 | + |
|
140 | + if($requestCount > 0) { |
|
141 | + $requestSectionData['Requests queued in the Job Queue'] = array( |
|
142 | + 'requests' => $this->prepareRequestData($results), |
|
143 | + 'total' => $requestCount, |
|
144 | + 'api' => 'JobQueue', |
|
145 | + 'type' => 'JobQueue', |
|
146 | + 'special' => 'Job Queue', |
|
147 | + 'help' => 'This section lists all the requests which are currently waiting to be created by the tool. Requests should automatically disappear from here within a few minutes.', |
|
148 | + 'showAll' => false |
|
149 | + ); |
|
150 | + } |
|
151 | + } |
|
152 | + |
|
153 | + /** |
|
154 | + * @param PdoDatabase $database |
|
155 | + * @param SiteConfiguration $config |
|
156 | + * @param $requestSectionData |
|
157 | + */ |
|
158 | + private function setupStatusSections( |
|
159 | + PdoDatabase $database, |
|
160 | + SiteConfiguration $config, |
|
161 | + &$requestSectionData |
|
162 | + ) { |
|
163 | + $search = RequestSearchHelper::get($database)->limit($config->getMiserModeLimit())->notHospitalised(); |
|
164 | + |
|
165 | + if ($config->getEmailConfirmationEnabled()) { |
|
166 | + $search->withConfirmedEmail(); |
|
167 | + } |
|
168 | + |
|
169 | + $allRequestStates = $config->getRequestStates(); |
|
170 | + $requestsByStatus = $search->fetchByStatus(array_keys($allRequestStates)); |
|
171 | + |
|
172 | + foreach ($allRequestStates as $requestState => $requestStateConfig) { |
|
173 | + |
|
174 | + $requestSectionData[$requestStateConfig['header']] = array( |
|
175 | + 'requests' => $this->prepareRequestData($requestsByStatus[$requestState]['data']), |
|
176 | + 'total' => $requestsByStatus[$requestState]['count'], |
|
177 | + 'api' => $requestStateConfig['api'], |
|
178 | + 'type' => $requestState, |
|
179 | + 'special' => null, |
|
180 | + 'help' => $requestStateConfig['queuehelp'], |
|
181 | + 'showAll' => true |
|
182 | + ); |
|
183 | + } |
|
184 | + } |
|
185 | 185 | } |
@@ -104,7 +104,7 @@ discard block |
||
104 | 104 | |
105 | 105 | $results = $search->getRecordCount($requestCount)->fetch(); |
106 | 106 | |
107 | - if($requestCount > 0) { |
|
107 | + if ($requestCount > 0) { |
|
108 | 108 | $requestSectionData['Hospital - Requests failed auto-creation'] = array( |
109 | 109 | 'requests' => $this->prepareRequestData($results), |
110 | 110 | 'total' => $requestCount, |
@@ -137,7 +137,7 @@ discard block |
||
137 | 137 | |
138 | 138 | $results = $search->getRecordCount($requestCount)->fetch(); |
139 | 139 | |
140 | - if($requestCount > 0) { |
|
140 | + if ($requestCount > 0) { |
|
141 | 141 | $requestSectionData['Requests queued in the Job Queue'] = array( |
142 | 142 | 'requests' => $this->prepareRequestData($results), |
143 | 143 | 'total' => $requestCount, |
@@ -16,14 +16,14 @@ |
||
16 | 16 | */ |
17 | 17 | class RequestList |
18 | 18 | { |
19 | - public $requests; |
|
20 | - public $showPrivateData; |
|
21 | - public $dataClearEmail; |
|
22 | - public $dataClearIp; |
|
23 | - public $relatedEmailRequests; |
|
24 | - public $relatedIpRequests; |
|
25 | - public $requestTrustedIp; |
|
26 | - public $canBan; |
|
27 | - public $canBreakReservation; |
|
28 | - public $userList; |
|
19 | + public $requests; |
|
20 | + public $showPrivateData; |
|
21 | + public $dataClearEmail; |
|
22 | + public $dataClearIp; |
|
23 | + public $relatedEmailRequests; |
|
24 | + public $relatedIpRequests; |
|
25 | + public $requestTrustedIp; |
|
26 | + public $canBan; |
|
27 | + public $canBreakReservation; |
|
28 | + public $userList; |
|
29 | 29 | } |