Failed Conditions
Pull Request — oauthcreation (#531)
by Simon
18:38 queued 08:37
created
smarty-plugins/modifier.relativedate.php 2 patches
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -16,68 +16,68 @@
 block discarded – undo
16 16
  */
17 17
 function smarty_modifier_relativedate($input)
18 18
 {
19
-    $now = new DateTime();
19
+	$now = new DateTime();
20 20
 
21
-    if (gettype($input) === 'object'
22
-        && (get_class($input) === DateTime::class || get_class($input) === DateTimeImmutable::class)
23
-    ) {
24
-        $then = $input;
25
-    }
26
-    else {
27
-        $then = new DateTime($input);
28
-    }
21
+	if (gettype($input) === 'object'
22
+		&& (get_class($input) === DateTime::class || get_class($input) === DateTimeImmutable::class)
23
+	) {
24
+		$then = $input;
25
+	}
26
+	else {
27
+		$then = new DateTime($input);
28
+	}
29 29
 
30
-    $secs = $now->getTimestamp() - $then->getTimestamp();
30
+	$secs = $now->getTimestamp() - $then->getTimestamp();
31 31
 
32
-    $second = 1;
33
-    $minute = 60 * $second;
34
-    $minuteCut = 60 * $second;
35
-    $hour = 60 * $minute;
36
-    $hourCut = 90 * $minute;
37
-    $day = 24 * $hour;
38
-    $dayCut = 48 * $hour;
39
-    $week = 7 * $day;
40
-    $weekCut = 14 * $day;
41
-    $month = 30 * $day;
42
-    $monthCut = 60 * $day;
43
-    $year = 365 * $day;
44
-    $yearCut = $year * 2;
32
+	$second = 1;
33
+	$minute = 60 * $second;
34
+	$minuteCut = 60 * $second;
35
+	$hour = 60 * $minute;
36
+	$hourCut = 90 * $minute;
37
+	$day = 24 * $hour;
38
+	$dayCut = 48 * $hour;
39
+	$week = 7 * $day;
40
+	$weekCut = 14 * $day;
41
+	$month = 30 * $day;
42
+	$monthCut = 60 * $day;
43
+	$year = 365 * $day;
44
+	$yearCut = $year * 2;
45 45
 
46
-    $pluralise = true;
46
+	$pluralise = true;
47 47
 
48
-    if ($secs <= 10) {
49
-        $output = "just now";
50
-        $pluralise = false;
51
-    }
52
-    elseif ($secs > 10 && $secs < $minuteCut) {
53
-        $output = round($secs / $second) . " second";
54
-    }
55
-    elseif ($secs >= $minuteCut && $secs < $hourCut) {
56
-        $output = round($secs / $minute) . " minute";
57
-    }
58
-    elseif ($secs >= $hourCut && $secs < $dayCut) {
59
-        $output = round($secs / $hour) . " hour";
60
-    }
61
-    elseif ($secs >= $dayCut && $secs < $weekCut) {
62
-        $output = round($secs / $day) . " day";
63
-    }
64
-    elseif ($secs >= $weekCut && $secs < $monthCut) {
65
-        $output = round($secs / $week) . " week";
66
-    }
67
-    elseif ($secs >= $monthCut && $secs < $yearCut) {
68
-        $output = round($secs / $month) . " month";
69
-    }
70
-    elseif ($secs >= $yearCut && $secs < $year * 10) {
71
-        $output = round($secs / $year) . " year";
72
-    }
73
-    else {
74
-        $output = "a long time ago";
75
-        $pluralise = false;
76
-    }
48
+	if ($secs <= 10) {
49
+		$output = "just now";
50
+		$pluralise = false;
51
+	}
52
+	elseif ($secs > 10 && $secs < $minuteCut) {
53
+		$output = round($secs / $second) . " second";
54
+	}
55
+	elseif ($secs >= $minuteCut && $secs < $hourCut) {
56
+		$output = round($secs / $minute) . " minute";
57
+	}
58
+	elseif ($secs >= $hourCut && $secs < $dayCut) {
59
+		$output = round($secs / $hour) . " hour";
60
+	}
61
+	elseif ($secs >= $dayCut && $secs < $weekCut) {
62
+		$output = round($secs / $day) . " day";
63
+	}
64
+	elseif ($secs >= $weekCut && $secs < $monthCut) {
65
+		$output = round($secs / $week) . " week";
66
+	}
67
+	elseif ($secs >= $monthCut && $secs < $yearCut) {
68
+		$output = round($secs / $month) . " month";
69
+	}
70
+	elseif ($secs >= $yearCut && $secs < $year * 10) {
71
+		$output = round($secs / $year) . " year";
72
+	}
73
+	else {
74
+		$output = "a long time ago";
75
+		$pluralise = false;
76
+	}
77 77
 
78
-    if ($pluralise) {
79
-        $output = (substr($output, 0, 2) <> "1 ") ? $output . "s ago" : $output . " ago";
80
-    }
78
+	if ($pluralise) {
79
+		$output = (substr($output, 0, 2) <> "1 ") ? $output . "s ago" : $output . " ago";
80
+	}
81 81
 
82
-    return $output;
82
+	return $output;
83 83
 }
84 84
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -50,25 +50,25 @@  discard block
 block discarded – undo
50 50
         $pluralise = false;
51 51
     }
52 52
     elseif ($secs > 10 && $secs < $minuteCut) {
53
-        $output = round($secs / $second) . " second";
53
+        $output = round($secs / $second)." second";
54 54
     }
55 55
     elseif ($secs >= $minuteCut && $secs < $hourCut) {
56
-        $output = round($secs / $minute) . " minute";
56
+        $output = round($secs / $minute)." minute";
57 57
     }
58 58
     elseif ($secs >= $hourCut && $secs < $dayCut) {
59
-        $output = round($secs / $hour) . " hour";
59
+        $output = round($secs / $hour)." hour";
60 60
     }
61 61
     elseif ($secs >= $dayCut && $secs < $weekCut) {
62
-        $output = round($secs / $day) . " day";
62
+        $output = round($secs / $day)." day";
63 63
     }
64 64
     elseif ($secs >= $weekCut && $secs < $monthCut) {
65
-        $output = round($secs / $week) . " week";
65
+        $output = round($secs / $week)." week";
66 66
     }
67 67
     elseif ($secs >= $monthCut && $secs < $yearCut) {
68
-        $output = round($secs / $month) . " month";
68
+        $output = round($secs / $month)." month";
69 69
     }
70 70
     elseif ($secs >= $yearCut && $secs < $year * 10) {
71
-        $output = round($secs / $year) . " year";
71
+        $output = round($secs / $year)." year";
72 72
     }
73 73
     else {
74 74
         $output = "a long time ago";
@@ -76,7 +76,7 @@  discard block
 block discarded – undo
76 76
     }
77 77
 
78 78
     if ($pluralise) {
79
-        $output = (substr($output, 0, 2) <> "1 ") ? $output . "s ago" : $output . " ago";
79
+        $output = (substr($output, 0, 2) <> "1 ") ? $output."s ago" : $output." ago";
80 80
     }
81 81
 
82 82
     return $output;
Please login to merge, or discard this patch.
smarty-plugins/modifier.date.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -16,16 +16,16 @@
 block discarded – undo
16 16
  */
17 17
 function smarty_modifier_date($input)
18 18
 {
19
-    if (gettype($input) === 'object'
20
-        && (get_class($input) === DateTime::class || get_class($input) === DateTimeImmutable::class)
21
-    ) {
22
-        /** @var $date DateTime|DateTimeImmutable */
23
-        $date = $input;
24
-        $dateString = $date->format('Y-m-d H:i:s');
19
+	if (gettype($input) === 'object'
20
+		&& (get_class($input) === DateTime::class || get_class($input) === DateTimeImmutable::class)
21
+	) {
22
+		/** @var $date DateTime|DateTimeImmutable */
23
+		$date = $input;
24
+		$dateString = $date->format('Y-m-d H:i:s');
25 25
 
26
-        return $dateString;
27
-    }
28
-    else {
29
-        return $input;
30
-    }
26
+		return $dateString;
27
+	}
28
+	else {
29
+		return $input;
30
+	}
31 31
 }
32 32
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Helpers/SearchHelpers/LogSearchHelper.php 1 patch
Indentation   +73 added lines, -73 removed lines patch added patch discarded remove patch
@@ -13,87 +13,87 @@
 block discarded – undo
13 13
 
14 14
 class LogSearchHelper extends SearchHelperBase
15 15
 {
16
-    /**
17
-     * LogSearchHelper constructor.
18
-     *
19
-     * @param PdoDatabase $database
20
-     */
21
-    protected function __construct(PdoDatabase $database)
22
-    {
23
-        parent::__construct($database, 'log', Log::class, 'timestamp DESC');
24
-    }
16
+	/**
17
+	 * LogSearchHelper constructor.
18
+	 *
19
+	 * @param PdoDatabase $database
20
+	 */
21
+	protected function __construct(PdoDatabase $database)
22
+	{
23
+		parent::__construct($database, 'log', Log::class, 'timestamp DESC');
24
+	}
25 25
 
26
-    /**
27
-     * Initiates a search for requests
28
-     *
29
-     * @param PdoDatabase $database
30
-     *
31
-     * @return LogSearchHelper
32
-     */
33
-    public static function get(PdoDatabase $database)
34
-    {
35
-        $helper = new LogSearchHelper($database);
26
+	/**
27
+	 * Initiates a search for requests
28
+	 *
29
+	 * @param PdoDatabase $database
30
+	 *
31
+	 * @return LogSearchHelper
32
+	 */
33
+	public static function get(PdoDatabase $database)
34
+	{
35
+		$helper = new LogSearchHelper($database);
36 36
 
37
-        return $helper;
38
-    }
37
+		return $helper;
38
+	}
39 39
 
40
-    /**
41
-     * Filters the results by user
42
-     *
43
-     * @param int $userId
44
-     *
45
-     * @return $this
46
-     */
47
-    public function byUser($userId)
48
-    {
49
-        $this->whereClause .= ' AND user = ?';
50
-        $this->parameterList[] = $userId;
40
+	/**
41
+	 * Filters the results by user
42
+	 *
43
+	 * @param int $userId
44
+	 *
45
+	 * @return $this
46
+	 */
47
+	public function byUser($userId)
48
+	{
49
+		$this->whereClause .= ' AND user = ?';
50
+		$this->parameterList[] = $userId;
51 51
 
52
-        return $this;
53
-    }
52
+		return $this;
53
+	}
54 54
 
55
-    /**
56
-     * Filters the results by log action
57
-     *
58
-     * @param string $action
59
-     *
60
-     * @return $this
61
-     */
62
-    public function byAction($action)
63
-    {
64
-        $this->whereClause .= ' AND action = ?';
65
-        $this->parameterList[] = $action;
55
+	/**
56
+	 * Filters the results by log action
57
+	 *
58
+	 * @param string $action
59
+	 *
60
+	 * @return $this
61
+	 */
62
+	public function byAction($action)
63
+	{
64
+		$this->whereClause .= ' AND action = ?';
65
+		$this->parameterList[] = $action;
66 66
 
67
-        return $this;
68
-    }
67
+		return $this;
68
+	}
69 69
 
70
-    /**
71
-     * Filters the results by object type
72
-     *
73
-     * @param string $objectType
74
-     *
75
-     * @return $this
76
-     */
77
-    public function byObjectType($objectType)
78
-    {
79
-        $this->whereClause .= ' AND objecttype = ?';
80
-        $this->parameterList[] = $objectType;
70
+	/**
71
+	 * Filters the results by object type
72
+	 *
73
+	 * @param string $objectType
74
+	 *
75
+	 * @return $this
76
+	 */
77
+	public function byObjectType($objectType)
78
+	{
79
+		$this->whereClause .= ' AND objecttype = ?';
80
+		$this->parameterList[] = $objectType;
81 81
 
82
-        return $this;
83
-    }
82
+		return $this;
83
+	}
84 84
 
85
-    /**
86
-     * Filters the results by object type
87
-     *
88
-     * @param integer $objectId
89
-     *
90
-     * @return $this
91
-     */
92
-    public function byObjectId($objectId)
93
-    {
94
-        $this->whereClause .= ' AND objectid = ?';
95
-        $this->parameterList[] = $objectId;
85
+	/**
86
+	 * Filters the results by object type
87
+	 *
88
+	 * @param integer $objectId
89
+	 *
90
+	 * @return $this
91
+	 */
92
+	public function byObjectId($objectId)
93
+	{
94
+		$this->whereClause .= ' AND objectid = ?';
95
+		$this->parameterList[] = $objectId;
96 96
 
97
-        return $this;
98
-    }
97
+		return $this;
98
+	}
99 99
 }
100 100
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Tasks/PageBase.php 3 patches
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
             $targetScriptName = $currentScriptName;
220 220
         }
221 221
         else {
222
-            $targetScriptName = $this->getSiteConfiguration()->getBaseUrl() . '/' . $script;
222
+            $targetScriptName = $this->getSiteConfiguration()->getBaseUrl().'/'.$script;
223 223
         }
224 224
 
225 225
         $pathInfo = array($targetScriptName);
@@ -233,7 +233,7 @@  discard block
 block discarded – undo
233 233
         $url = implode('/', $pathInfo);
234 234
 
235 235
         if (is_array($parameters) && count($parameters) > 0) {
236
-            $url .= '?' . http_build_query($parameters);
236
+            $url .= '?'.http_build_query($parameters);
237 237
         }
238 238
 
239 239
         $this->redirectUrl($url);
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
      * @param string $path The path (relative to the application root) of the file
279 279
      */
280 280
     final protected function addCss($path) {
281
-        if(in_array($path, $this->extraCss)){
281
+        if (in_array($path, $this->extraCss)) {
282 282
             // nothing to do
283 283
             return;
284 284
         }
@@ -291,8 +291,8 @@  discard block
 block discarded – undo
291 291
      *
292 292
      * @param string $path The path (relative to the application root) of the file
293 293
      */
294
-    final protected function addJs($path){
295
-        if(in_array($path, $this->extraJs)){
294
+    final protected function addJs($path) {
295
+        if (in_array($path, $this->extraJs)) {
296 296
             // nothing to do
297 297
             return;
298 298
         }
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
     protected function sendResponseHeaders()
346 346
     {
347 347
         if (headers_sent()) {
348
-            throw new ApplicationLogicException          ('Headers have already been sent! This is likely a bug in the application.');
348
+            throw new ApplicationLogicException('Headers have already been sent! This is likely a bug in the application.');
349 349
         }
350 350
 
351 351
         foreach ($this->headerQueue as $item) {
Please login to merge, or discard this patch.
Braces   +6 added lines, -4 removed lines patch added patch discarded remove patch
@@ -277,8 +277,9 @@  discard block
 block discarded – undo
277 277
      *
278 278
      * @param string $path The path (relative to the application root) of the file
279 279
      */
280
-    final protected function addCss($path) {
281
-        if(in_array($path, $this->extraCss)){
280
+    final protected function addCss($path)
281
+    {
282
+        if(in_array($path, $this->extraCss)) {
282 283
             // nothing to do
283 284
             return;
284 285
         }
@@ -291,8 +292,9 @@  discard block
 block discarded – undo
291 292
      *
292 293
      * @param string $path The path (relative to the application root) of the file
293 294
      */
294
-    final protected function addJs($path){
295
-        if(in_array($path, $this->extraJs)){
295
+    final protected function addJs($path)
296
+    {
297
+        if(in_array($path, $this->extraJs)) {
296 298
             // nothing to do
297 299
             return;
298 300
         }
Please login to merge, or discard this patch.
Indentation   +349 added lines, -349 removed lines patch added patch discarded remove patch
@@ -21,353 +21,353 @@
 block discarded – undo
21 21
 
22 22
 abstract class PageBase extends TaskBase implements IRoutedTask
23 23
 {
24
-    use TemplateOutput;
25
-    /** @var string Smarty template to display */
26
-    protected $template = "base.tpl";
27
-    /** @var string HTML title. Currently unused. */
28
-    protected $htmlTitle;
29
-    /** @var bool Determines if the page is a redirect or not */
30
-    protected $isRedirecting = false;
31
-    /** @var array Queue of headers to be sent on successful completion */
32
-    protected $headerQueue = array();
33
-    /** @var string The name of the route to use, as determined by the request router. */
34
-    private $routeName = null;
35
-    /** @var TokenManager */
36
-    protected $tokenManager;
37
-    /** @var string[] Extra CSS files to include */
38
-    private $extraCss = array();
39
-    /** @var string[] Extra JS files to include */
40
-    private $extraJs = array();
41
-
42
-    /**
43
-     * Sets the route the request will take. Only should be called from the request router or barrier test.
44
-     *
45
-     * @param string $routeName        The name of the route
46
-     * @param bool   $skipCallableTest Don't use this unless you know what you're doing, and what the implications are.
47
-     *
48
-     * @throws Exception
49
-     * @category Security-Critical
50
-     */
51
-    final public function setRoute($routeName, $skipCallableTest = false)
52
-    {
53
-        // Test the new route is callable before adopting it.
54
-        if (!$skipCallableTest && !is_callable(array($this, $routeName))) {
55
-            throw new Exception("Proposed route '$routeName' is not callable.");
56
-        }
57
-
58
-        // Adopt the new route
59
-        $this->routeName = $routeName;
60
-    }
61
-
62
-    /**
63
-     * Gets the name of the route that has been passed from the request router.
64
-     * @return string
65
-     */
66
-    final public function getRouteName()
67
-    {
68
-        return $this->routeName;
69
-    }
70
-
71
-    /**
72
-     * Performs generic page setup actions
73
-     */
74
-    final protected function setupPage()
75
-    {
76
-        $this->setUpSmarty();
77
-
78
-        $siteNoticeText = SiteNotice::get($this->getDatabase());
79
-
80
-        $this->assign('siteNoticeText', $siteNoticeText);
81
-
82
-        $currentUser = User::getCurrent($this->getDatabase());
83
-        $this->assign('currentUser', $currentUser);
84
-        $this->assign('loggedIn', (!$currentUser->isCommunityUser()));
85
-    }
86
-
87
-    /**
88
-     * Runs the page logic as routed by the RequestRouter
89
-     *
90
-     * Only should be called after a security barrier! That means only from execute().
91
-     */
92
-    final protected function runPage()
93
-    {
94
-        $database = $this->getDatabase();
95
-
96
-        // initialise a database transaction
97
-        if (!$database->beginTransaction()) {
98
-            throw new Exception('Failed to start transaction on primary database.');
99
-        }
100
-
101
-        try {
102
-            // run the page code
103
-            $this->{$this->getRouteName()}();
104
-
105
-            $database->commit();
106
-        }
107
-        catch (ApplicationLogicException $ex) {
108
-            // it's an application logic exception, so nothing went seriously wrong with the site. We can use the
109
-            // standard templating system for this.
110
-
111
-            // Firstly, let's undo anything that happened to the database.
112
-            $database->rollBack();
113
-
114
-            // Reset smarty
115
-            $this->setUpSmarty();
116
-
117
-            // Set the template
118
-            $this->setTemplate('exception/application-logic.tpl');
119
-            $this->assign('message', $ex->getMessage());
120
-
121
-            // Force this back to false
122
-            $this->isRedirecting = false;
123
-            $this->headerQueue = array();
124
-        }
125
-        catch (OptimisticLockFailedException $ex) {
126
-            // it's an optimistic lock failure exception, so nothing went seriously wrong with the site. We can use the
127
-            // standard templating system for this.
128
-
129
-            // Firstly, let's undo anything that happened to the database.
130
-            $database->rollBack();
131
-
132
-            // Reset smarty
133
-            $this->setUpSmarty();
134
-
135
-            // Set the template
136
-            $this->setTemplate('exception/optimistic-lock-failure.tpl');
137
-            $this->assign('message', $ex->getMessage());
138
-
139
-            $this->assign('debugTrace', false);
140
-
141
-            if ($this->getSiteConfiguration()->getDebuggingTraceEnabled()) {
142
-                ob_start();
143
-                var_dump(ExceptionHandler::getExceptionData($ex));
144
-                $textErrorData = ob_get_contents();
145
-                ob_end_clean();
146
-
147
-                $this->assign('exceptionData', $textErrorData);
148
-                $this->assign('debugTrace', true);
149
-            }
150
-
151
-            // Force this back to false
152
-            $this->isRedirecting = false;
153
-            $this->headerQueue = array();
154
-        }
155
-        finally {
156
-            // Catch any hanging on transactions
157
-            if ($database->hasActiveTransaction()) {
158
-                $database->rollBack();
159
-            }
160
-        }
161
-
162
-        // run any finalisation code needed before we send the output to the browser.
163
-        $this->finalisePage();
164
-
165
-        // Send the headers
166
-        $this->sendResponseHeaders();
167
-
168
-        // Check we have a template to use!
169
-        if ($this->template !== null) {
170
-            $content = $this->fetchTemplate($this->template);
171
-            ob_clean();
172
-            print($content);
173
-            ob_flush();
174
-
175
-            return;
176
-        }
177
-    }
178
-
179
-    /**
180
-     * Performs final tasks needed before rendering the page.
181
-     */
182
-    protected function finalisePage()
183
-    {
184
-        if ($this->isRedirecting) {
185
-            $this->template = null;
186
-
187
-            return;
188
-        }
189
-
190
-        $this->assign('extraCss', $this->extraCss);
191
-        $this->assign('extraJs', $this->extraJs);
192
-
193
-        // If we're actually displaying content, we want to add the session alerts here!
194
-        $this->assign('alerts', SessionAlert::getAlerts());
195
-        SessionAlert::clearAlerts();
196
-
197
-        $this->assign('htmlTitle', $this->htmlTitle);
198
-    }
199
-
200
-    /**
201
-     * @return TokenManager
202
-     */
203
-    public function getTokenManager()
204
-    {
205
-        return $this->tokenManager;
206
-    }
207
-
208
-    /**
209
-     * @param TokenManager $tokenManager
210
-     */
211
-    public function setTokenManager($tokenManager)
212
-    {
213
-        $this->tokenManager = $tokenManager;
214
-    }
215
-
216
-    /**
217
-     * Sends the redirect headers to perform a GET at the destination page.
218
-     *
219
-     * Also nullifies the set template so Smarty does not render it.
220
-     *
221
-     * @param string      $page   The page to redirect requests to (as used in the UR)
222
-     * @param null|string $action The action to use on the page.
223
-     * @param null|array  $parameters
224
-     * @param null|string $script The script (relative to index.php) to redirect to
225
-     */
226
-    final protected function redirect($page = '', $action = null, $parameters = null, $script = null)
227
-    {
228
-        $currentScriptName = WebRequest::scriptName();
229
-
230
-        // Are we changing script?
231
-        if ($script === null || substr($currentScriptName, -1 * count($script)) === $script) {
232
-            $targetScriptName = $currentScriptName;
233
-        }
234
-        else {
235
-            $targetScriptName = $this->getSiteConfiguration()->getBaseUrl() . '/' . $script;
236
-        }
237
-
238
-        $pathInfo = array($targetScriptName);
239
-
240
-        $pathInfo[1] = $page;
241
-
242
-        if ($action !== null) {
243
-            $pathInfo[2] = $action;
244
-        }
245
-
246
-        $url = implode('/', $pathInfo);
247
-
248
-        if (is_array($parameters) && count($parameters) > 0) {
249
-            $url .= '?' . http_build_query($parameters);
250
-        }
251
-
252
-        $this->redirectUrl($url);
253
-    }
254
-
255
-    /**
256
-     * Sends the redirect headers to perform a GET at the new address.
257
-     *
258
-     * Also nullifies the set template so Smarty does not render it.
259
-     *
260
-     * @param string $path URL to redirect to
261
-     */
262
-    final protected function redirectUrl($path)
263
-    {
264
-        // 303 See Other = re-request at new address with a GET.
265
-        $this->headerQueue[] = 'HTTP/1.1 303 See Other';
266
-        $this->headerQueue[] = "Location: $path";
267
-
268
-        $this->setTemplate(null);
269
-        $this->isRedirecting = true;
270
-    }
271
-
272
-    /**
273
-     * Sets the name of the template this page should display.
274
-     *
275
-     * @param string $name
276
-     *
277
-     * @throws Exception
278
-     */
279
-    final protected function setTemplate($name)
280
-    {
281
-        if ($this->isRedirecting) {
282
-            throw new Exception('This page has been set as a redirect, no template can be displayed!');
283
-        }
284
-
285
-        $this->template = $name;
286
-    }
287
-
288
-    /**
289
-     * Adds an extra CSS file to to the page
290
-     *
291
-     * @param string $path The path (relative to the application root) of the file
292
-     */
293
-    final protected function addCss($path) {
294
-        if(in_array($path, $this->extraCss)){
295
-            // nothing to do
296
-            return;
297
-        }
298
-
299
-        $this->extraCss[] = $path;
300
-    }
301
-
302
-    /**
303
-     * Adds an extra JS file to to the page
304
-     *
305
-     * @param string $path The path (relative to the application root) of the file
306
-     */
307
-    final protected function addJs($path){
308
-        if(in_array($path, $this->extraJs)){
309
-            // nothing to do
310
-            return;
311
-        }
312
-
313
-        $this->extraJs[] = $path;
314
-    }
315
-
316
-    /**
317
-     * Main function for this page, when no specific actions are called.
318
-     * @return void
319
-     */
320
-    abstract protected function main();
321
-
322
-    /**
323
-     * @param string $title
324
-     */
325
-    final protected function setHtmlTitle($title)
326
-    {
327
-        $this->htmlTitle = $title;
328
-    }
329
-
330
-    public function execute()
331
-    {
332
-        if ($this->getRouteName() === null) {
333
-            throw new Exception('Request is unrouted.');
334
-        }
335
-
336
-        if ($this->getSiteConfiguration() === null) {
337
-            throw new Exception('Page has no configuration!');
338
-        }
339
-
340
-        $this->setupPage();
341
-
342
-        $this->runPage();
343
-    }
344
-
345
-    public function assignCSRFToken()
346
-    {
347
-        $token = $this->tokenManager->getNewToken();
348
-        $this->assign('csrfTokenData', $token->getTokenData());
349
-    }
350
-
351
-    public function validateCSRFToken()
352
-    {
353
-        if (!$this->tokenManager->validateToken(WebRequest::postString('csrfTokenData'))) {
354
-            throw new ApplicationLogicException('Form token is not valid, please reload and try again');
355
-        }
356
-    }
357
-
358
-    protected function sendResponseHeaders()
359
-    {
360
-        if (headers_sent()) {
361
-            throw new ApplicationLogicException          ('Headers have already been sent! This is likely a bug in the application.');
362
-        }
363
-
364
-        foreach ($this->headerQueue as $item) {
365
-            if (mb_strpos($item, "\r") !== false || mb_strpos($item, "\n") !== false) {
366
-                // Oops. We're not allowed to do this.
367
-                throw new Exception('Unable to split header');
368
-            }
369
-
370
-            header($item);
371
-        }
372
-    }
24
+	use TemplateOutput;
25
+	/** @var string Smarty template to display */
26
+	protected $template = "base.tpl";
27
+	/** @var string HTML title. Currently unused. */
28
+	protected $htmlTitle;
29
+	/** @var bool Determines if the page is a redirect or not */
30
+	protected $isRedirecting = false;
31
+	/** @var array Queue of headers to be sent on successful completion */
32
+	protected $headerQueue = array();
33
+	/** @var string The name of the route to use, as determined by the request router. */
34
+	private $routeName = null;
35
+	/** @var TokenManager */
36
+	protected $tokenManager;
37
+	/** @var string[] Extra CSS files to include */
38
+	private $extraCss = array();
39
+	/** @var string[] Extra JS files to include */
40
+	private $extraJs = array();
41
+
42
+	/**
43
+	 * Sets the route the request will take. Only should be called from the request router or barrier test.
44
+	 *
45
+	 * @param string $routeName        The name of the route
46
+	 * @param bool   $skipCallableTest Don't use this unless you know what you're doing, and what the implications are.
47
+	 *
48
+	 * @throws Exception
49
+	 * @category Security-Critical
50
+	 */
51
+	final public function setRoute($routeName, $skipCallableTest = false)
52
+	{
53
+		// Test the new route is callable before adopting it.
54
+		if (!$skipCallableTest && !is_callable(array($this, $routeName))) {
55
+			throw new Exception("Proposed route '$routeName' is not callable.");
56
+		}
57
+
58
+		// Adopt the new route
59
+		$this->routeName = $routeName;
60
+	}
61
+
62
+	/**
63
+	 * Gets the name of the route that has been passed from the request router.
64
+	 * @return string
65
+	 */
66
+	final public function getRouteName()
67
+	{
68
+		return $this->routeName;
69
+	}
70
+
71
+	/**
72
+	 * Performs generic page setup actions
73
+	 */
74
+	final protected function setupPage()
75
+	{
76
+		$this->setUpSmarty();
77
+
78
+		$siteNoticeText = SiteNotice::get($this->getDatabase());
79
+
80
+		$this->assign('siteNoticeText', $siteNoticeText);
81
+
82
+		$currentUser = User::getCurrent($this->getDatabase());
83
+		$this->assign('currentUser', $currentUser);
84
+		$this->assign('loggedIn', (!$currentUser->isCommunityUser()));
85
+	}
86
+
87
+	/**
88
+	 * Runs the page logic as routed by the RequestRouter
89
+	 *
90
+	 * Only should be called after a security barrier! That means only from execute().
91
+	 */
92
+	final protected function runPage()
93
+	{
94
+		$database = $this->getDatabase();
95
+
96
+		// initialise a database transaction
97
+		if (!$database->beginTransaction()) {
98
+			throw new Exception('Failed to start transaction on primary database.');
99
+		}
100
+
101
+		try {
102
+			// run the page code
103
+			$this->{$this->getRouteName()}();
104
+
105
+			$database->commit();
106
+		}
107
+		catch (ApplicationLogicException $ex) {
108
+			// it's an application logic exception, so nothing went seriously wrong with the site. We can use the
109
+			// standard templating system for this.
110
+
111
+			// Firstly, let's undo anything that happened to the database.
112
+			$database->rollBack();
113
+
114
+			// Reset smarty
115
+			$this->setUpSmarty();
116
+
117
+			// Set the template
118
+			$this->setTemplate('exception/application-logic.tpl');
119
+			$this->assign('message', $ex->getMessage());
120
+
121
+			// Force this back to false
122
+			$this->isRedirecting = false;
123
+			$this->headerQueue = array();
124
+		}
125
+		catch (OptimisticLockFailedException $ex) {
126
+			// it's an optimistic lock failure exception, so nothing went seriously wrong with the site. We can use the
127
+			// standard templating system for this.
128
+
129
+			// Firstly, let's undo anything that happened to the database.
130
+			$database->rollBack();
131
+
132
+			// Reset smarty
133
+			$this->setUpSmarty();
134
+
135
+			// Set the template
136
+			$this->setTemplate('exception/optimistic-lock-failure.tpl');
137
+			$this->assign('message', $ex->getMessage());
138
+
139
+			$this->assign('debugTrace', false);
140
+
141
+			if ($this->getSiteConfiguration()->getDebuggingTraceEnabled()) {
142
+				ob_start();
143
+				var_dump(ExceptionHandler::getExceptionData($ex));
144
+				$textErrorData = ob_get_contents();
145
+				ob_end_clean();
146
+
147
+				$this->assign('exceptionData', $textErrorData);
148
+				$this->assign('debugTrace', true);
149
+			}
150
+
151
+			// Force this back to false
152
+			$this->isRedirecting = false;
153
+			$this->headerQueue = array();
154
+		}
155
+		finally {
156
+			// Catch any hanging on transactions
157
+			if ($database->hasActiveTransaction()) {
158
+				$database->rollBack();
159
+			}
160
+		}
161
+
162
+		// run any finalisation code needed before we send the output to the browser.
163
+		$this->finalisePage();
164
+
165
+		// Send the headers
166
+		$this->sendResponseHeaders();
167
+
168
+		// Check we have a template to use!
169
+		if ($this->template !== null) {
170
+			$content = $this->fetchTemplate($this->template);
171
+			ob_clean();
172
+			print($content);
173
+			ob_flush();
174
+
175
+			return;
176
+		}
177
+	}
178
+
179
+	/**
180
+	 * Performs final tasks needed before rendering the page.
181
+	 */
182
+	protected function finalisePage()
183
+	{
184
+		if ($this->isRedirecting) {
185
+			$this->template = null;
186
+
187
+			return;
188
+		}
189
+
190
+		$this->assign('extraCss', $this->extraCss);
191
+		$this->assign('extraJs', $this->extraJs);
192
+
193
+		// If we're actually displaying content, we want to add the session alerts here!
194
+		$this->assign('alerts', SessionAlert::getAlerts());
195
+		SessionAlert::clearAlerts();
196
+
197
+		$this->assign('htmlTitle', $this->htmlTitle);
198
+	}
199
+
200
+	/**
201
+	 * @return TokenManager
202
+	 */
203
+	public function getTokenManager()
204
+	{
205
+		return $this->tokenManager;
206
+	}
207
+
208
+	/**
209
+	 * @param TokenManager $tokenManager
210
+	 */
211
+	public function setTokenManager($tokenManager)
212
+	{
213
+		$this->tokenManager = $tokenManager;
214
+	}
215
+
216
+	/**
217
+	 * Sends the redirect headers to perform a GET at the destination page.
218
+	 *
219
+	 * Also nullifies the set template so Smarty does not render it.
220
+	 *
221
+	 * @param string      $page   The page to redirect requests to (as used in the UR)
222
+	 * @param null|string $action The action to use on the page.
223
+	 * @param null|array  $parameters
224
+	 * @param null|string $script The script (relative to index.php) to redirect to
225
+	 */
226
+	final protected function redirect($page = '', $action = null, $parameters = null, $script = null)
227
+	{
228
+		$currentScriptName = WebRequest::scriptName();
229
+
230
+		// Are we changing script?
231
+		if ($script === null || substr($currentScriptName, -1 * count($script)) === $script) {
232
+			$targetScriptName = $currentScriptName;
233
+		}
234
+		else {
235
+			$targetScriptName = $this->getSiteConfiguration()->getBaseUrl() . '/' . $script;
236
+		}
237
+
238
+		$pathInfo = array($targetScriptName);
239
+
240
+		$pathInfo[1] = $page;
241
+
242
+		if ($action !== null) {
243
+			$pathInfo[2] = $action;
244
+		}
245
+
246
+		$url = implode('/', $pathInfo);
247
+
248
+		if (is_array($parameters) && count($parameters) > 0) {
249
+			$url .= '?' . http_build_query($parameters);
250
+		}
251
+
252
+		$this->redirectUrl($url);
253
+	}
254
+
255
+	/**
256
+	 * Sends the redirect headers to perform a GET at the new address.
257
+	 *
258
+	 * Also nullifies the set template so Smarty does not render it.
259
+	 *
260
+	 * @param string $path URL to redirect to
261
+	 */
262
+	final protected function redirectUrl($path)
263
+	{
264
+		// 303 See Other = re-request at new address with a GET.
265
+		$this->headerQueue[] = 'HTTP/1.1 303 See Other';
266
+		$this->headerQueue[] = "Location: $path";
267
+
268
+		$this->setTemplate(null);
269
+		$this->isRedirecting = true;
270
+	}
271
+
272
+	/**
273
+	 * Sets the name of the template this page should display.
274
+	 *
275
+	 * @param string $name
276
+	 *
277
+	 * @throws Exception
278
+	 */
279
+	final protected function setTemplate($name)
280
+	{
281
+		if ($this->isRedirecting) {
282
+			throw new Exception('This page has been set as a redirect, no template can be displayed!');
283
+		}
284
+
285
+		$this->template = $name;
286
+	}
287
+
288
+	/**
289
+	 * Adds an extra CSS file to to the page
290
+	 *
291
+	 * @param string $path The path (relative to the application root) of the file
292
+	 */
293
+	final protected function addCss($path) {
294
+		if(in_array($path, $this->extraCss)){
295
+			// nothing to do
296
+			return;
297
+		}
298
+
299
+		$this->extraCss[] = $path;
300
+	}
301
+
302
+	/**
303
+	 * Adds an extra JS file to to the page
304
+	 *
305
+	 * @param string $path The path (relative to the application root) of the file
306
+	 */
307
+	final protected function addJs($path){
308
+		if(in_array($path, $this->extraJs)){
309
+			// nothing to do
310
+			return;
311
+		}
312
+
313
+		$this->extraJs[] = $path;
314
+	}
315
+
316
+	/**
317
+	 * Main function for this page, when no specific actions are called.
318
+	 * @return void
319
+	 */
320
+	abstract protected function main();
321
+
322
+	/**
323
+	 * @param string $title
324
+	 */
325
+	final protected function setHtmlTitle($title)
326
+	{
327
+		$this->htmlTitle = $title;
328
+	}
329
+
330
+	public function execute()
331
+	{
332
+		if ($this->getRouteName() === null) {
333
+			throw new Exception('Request is unrouted.');
334
+		}
335
+
336
+		if ($this->getSiteConfiguration() === null) {
337
+			throw new Exception('Page has no configuration!');
338
+		}
339
+
340
+		$this->setupPage();
341
+
342
+		$this->runPage();
343
+	}
344
+
345
+	public function assignCSRFToken()
346
+	{
347
+		$token = $this->tokenManager->getNewToken();
348
+		$this->assign('csrfTokenData', $token->getTokenData());
349
+	}
350
+
351
+	public function validateCSRFToken()
352
+	{
353
+		if (!$this->tokenManager->validateToken(WebRequest::postString('csrfTokenData'))) {
354
+			throw new ApplicationLogicException('Form token is not valid, please reload and try again');
355
+		}
356
+	}
357
+
358
+	protected function sendResponseHeaders()
359
+	{
360
+		if (headers_sent()) {
361
+			throw new ApplicationLogicException          ('Headers have already been sent! This is likely a bug in the application.');
362
+		}
363
+
364
+		foreach ($this->headerQueue as $item) {
365
+			if (mb_strpos($item, "\r") !== false || mb_strpos($item, "\n") !== false) {
366
+				// Oops. We're not allowed to do this.
367
+				throw new Exception('Unable to split header');
368
+			}
369
+
370
+			header($item);
371
+		}
372
+	}
373 373
 }
Please login to merge, or discard this patch.
includes/IdentificationVerifier.php 3 patches
Indentation   +157 added lines, -157 removed lines patch added patch discarded remove patch
@@ -26,131 +26,131 @@  discard block
 block discarded – undo
26 26
  */
27 27
 class IdentificationVerifier
28 28
 {
29
-    /**
30
-     * This field is an array of parameters, in key => value format, that should be appended to the Meta Wikimedia
31
-     * Web Service Endpoint URL to query if a user is listed on the Identification Noticeboard.  Note that URL encoding
32
-     * of these values is *not* necessary; this is done automatically.
33
-     *
34
-     * @var string[]
35
-     * @category Security-Critical
36
-     */
37
-    private static $apiQueryParameters = array(
38
-        'action'   => 'query',
39
-        'format'   => 'json',
40
-        'prop'     => 'links',
41
-        'titles'   => 'Access to nonpublic information policy/Noticeboard',
42
-        // Username of the user to be checked, with User: prefix, goes here!  Set in isIdentifiedOnWiki()
43
-        'pltitles' => '',
44
-    );
45
-    /** @var HttpHelper */
46
-    private $httpHelper;
47
-    /** @var SiteConfiguration */
48
-    private $siteConfiguration;
49
-    /** @var PdoDatabase */
50
-    private $dbObject;
51
-
52
-    /**
53
-     * IdentificationVerifier constructor.
54
-     *
55
-     * @param HttpHelper        $httpHelper
56
-     * @param SiteConfiguration $siteConfiguration
57
-     * @param PdoDatabase       $dbObject
58
-     */
59
-    public function __construct(HttpHelper $httpHelper, SiteConfiguration $siteConfiguration, PdoDatabase $dbObject)
60
-    {
61
-        $this->httpHelper = $httpHelper;
62
-        $this->siteConfiguration = $siteConfiguration;
63
-        $this->dbObject = $dbObject;
64
-    }
65
-
66
-    /**
67
-     * Checks if the given user is identified to the Wikimedia Foundation.
68
-     *
69
-     * @param string $onWikiName The Wikipedia username of the user
70
-     *
71
-     * @return bool
72
-     * @category Security-Critical
73
-     */
74
-    public function isUserIdentified($onWikiName)
75
-    {
76
-        if ($this->checkIdentificationCache($onWikiName)) {
77
-            return true;
78
-        }
79
-        else {
80
-            if ($this->isIdentifiedOnWiki($onWikiName)) {
81
-                $this->cacheIdentificationStatus($onWikiName);
82
-
83
-                return true;
84
-            }
85
-            else {
86
-                return false;
87
-            }
88
-        }
89
-    }
90
-
91
-    /**
92
-     * Checks if the given user has a valid entry in the idcache table.
93
-     *
94
-     * @param string $onWikiName The Wikipedia username of the user
95
-     *
96
-     * @return bool
97
-     * @category Security-Critical
98
-     */
99
-    private function checkIdentificationCache($onWikiName)
100
-    {
101
-        $interval = $this->siteConfiguration->getIdentificationCacheExpiry();
102
-
103
-        $query = <<<SQL
29
+	/**
30
+	 * This field is an array of parameters, in key => value format, that should be appended to the Meta Wikimedia
31
+	 * Web Service Endpoint URL to query if a user is listed on the Identification Noticeboard.  Note that URL encoding
32
+	 * of these values is *not* necessary; this is done automatically.
33
+	 *
34
+	 * @var string[]
35
+	 * @category Security-Critical
36
+	 */
37
+	private static $apiQueryParameters = array(
38
+		'action'   => 'query',
39
+		'format'   => 'json',
40
+		'prop'     => 'links',
41
+		'titles'   => 'Access to nonpublic information policy/Noticeboard',
42
+		// Username of the user to be checked, with User: prefix, goes here!  Set in isIdentifiedOnWiki()
43
+		'pltitles' => '',
44
+	);
45
+	/** @var HttpHelper */
46
+	private $httpHelper;
47
+	/** @var SiteConfiguration */
48
+	private $siteConfiguration;
49
+	/** @var PdoDatabase */
50
+	private $dbObject;
51
+
52
+	/**
53
+	 * IdentificationVerifier constructor.
54
+	 *
55
+	 * @param HttpHelper        $httpHelper
56
+	 * @param SiteConfiguration $siteConfiguration
57
+	 * @param PdoDatabase       $dbObject
58
+	 */
59
+	public function __construct(HttpHelper $httpHelper, SiteConfiguration $siteConfiguration, PdoDatabase $dbObject)
60
+	{
61
+		$this->httpHelper = $httpHelper;
62
+		$this->siteConfiguration = $siteConfiguration;
63
+		$this->dbObject = $dbObject;
64
+	}
65
+
66
+	/**
67
+	 * Checks if the given user is identified to the Wikimedia Foundation.
68
+	 *
69
+	 * @param string $onWikiName The Wikipedia username of the user
70
+	 *
71
+	 * @return bool
72
+	 * @category Security-Critical
73
+	 */
74
+	public function isUserIdentified($onWikiName)
75
+	{
76
+		if ($this->checkIdentificationCache($onWikiName)) {
77
+			return true;
78
+		}
79
+		else {
80
+			if ($this->isIdentifiedOnWiki($onWikiName)) {
81
+				$this->cacheIdentificationStatus($onWikiName);
82
+
83
+				return true;
84
+			}
85
+			else {
86
+				return false;
87
+			}
88
+		}
89
+	}
90
+
91
+	/**
92
+	 * Checks if the given user has a valid entry in the idcache table.
93
+	 *
94
+	 * @param string $onWikiName The Wikipedia username of the user
95
+	 *
96
+	 * @return bool
97
+	 * @category Security-Critical
98
+	 */
99
+	private function checkIdentificationCache($onWikiName)
100
+	{
101
+		$interval = $this->siteConfiguration->getIdentificationCacheExpiry();
102
+
103
+		$query = <<<SQL
104 104
 			SELECT COUNT(`id`)
105 105
 			FROM `idcache`
106 106
 			WHERE `onwikiusername` = :onwikiname
107 107
 				AND DATE_ADD(`checktime`, INTERVAL {$interval}) >= NOW();
108 108
 SQL;
109
-        $stmt = $this->dbObject->prepare($query);
110
-        $stmt->bindValue(':onwikiname', $onWikiName, PDO::PARAM_STR);
111
-        $stmt->execute();
112
-
113
-        // Guaranteed by the query to only return a single row with a single column
114
-        $results = $stmt->fetch(PDO::FETCH_NUM);
115
-
116
-        // I don't expect this to ever be a value other than 0 or 1 since the `onwikiusername` column is declared as a
117
-        // unique key - but meh.
118
-        return $results[0] != 0;
119
-    }
120
-
121
-    /**
122
-     * Does pretty much exactly what it says on the label - this method will clear all expired idcache entries from the
123
-     * idcache table.  Meant to be called periodically by a maintenance script.
124
-     *
125
-     * @param SiteConfiguration $siteConfiguration
126
-     * @param PdoDatabase       $dbObject
127
-     *
128
-     * @return void
129
-     */
130
-    public static function clearExpiredCacheEntries(SiteConfiguration $siteConfiguration, PdoDatabase $dbObject)
131
-    {
132
-        $interval = $siteConfiguration->getIdentificationCacheExpiry();
133
-
134
-        $query = <<<SQL
109
+		$stmt = $this->dbObject->prepare($query);
110
+		$stmt->bindValue(':onwikiname', $onWikiName, PDO::PARAM_STR);
111
+		$stmt->execute();
112
+
113
+		// Guaranteed by the query to only return a single row with a single column
114
+		$results = $stmt->fetch(PDO::FETCH_NUM);
115
+
116
+		// I don't expect this to ever be a value other than 0 or 1 since the `onwikiusername` column is declared as a
117
+		// unique key - but meh.
118
+		return $results[0] != 0;
119
+	}
120
+
121
+	/**
122
+	 * Does pretty much exactly what it says on the label - this method will clear all expired idcache entries from the
123
+	 * idcache table.  Meant to be called periodically by a maintenance script.
124
+	 *
125
+	 * @param SiteConfiguration $siteConfiguration
126
+	 * @param PdoDatabase       $dbObject
127
+	 *
128
+	 * @return void
129
+	 */
130
+	public static function clearExpiredCacheEntries(SiteConfiguration $siteConfiguration, PdoDatabase $dbObject)
131
+	{
132
+		$interval = $siteConfiguration->getIdentificationCacheExpiry();
133
+
134
+		$query = <<<SQL
135 135
 			DELETE FROM `idcache`
136 136
 			WHERE DATE_ADD(`checktime`, INTERVAL {$interval}) < NOW();
137 137
 SQL;
138
-        $dbObject->prepare($query)->execute();
139
-    }
140
-
141
-    /**
142
-     * This method will add an entry to the idcache that the given Wikipedia user has been verified as identified.  This
143
-     * is so we don't have to hit the API every single time we check.  The cache entry is valid for as long as specified
144
-     * in the ACC configuration (validity enforced by checkIdentificationCache() and clearExpiredCacheEntries()).
145
-     *
146
-     * @param string $onWikiName The Wikipedia username of the user
147
-     *
148
-     * @return void
149
-     * @category Security-Critical
150
-     */
151
-    private function cacheIdentificationStatus($onWikiName)
152
-    {
153
-        $query = <<<SQL
138
+		$dbObject->prepare($query)->execute();
139
+	}
140
+
141
+	/**
142
+	 * This method will add an entry to the idcache that the given Wikipedia user has been verified as identified.  This
143
+	 * is so we don't have to hit the API every single time we check.  The cache entry is valid for as long as specified
144
+	 * in the ACC configuration (validity enforced by checkIdentificationCache() and clearExpiredCacheEntries()).
145
+	 *
146
+	 * @param string $onWikiName The Wikipedia username of the user
147
+	 *
148
+	 * @return void
149
+	 * @category Security-Critical
150
+	 */
151
+	private function cacheIdentificationStatus($onWikiName)
152
+	{
153
+		$query = <<<SQL
154 154
 			INSERT INTO `idcache`
155 155
 				(`onwikiusername`)
156 156
 			VALUES
@@ -159,44 +159,44 @@  discard block
 block discarded – undo
159 159
 				`onwikiusername` = VALUES(`onwikiusername`),
160 160
 				`checktime` = CURRENT_TIMESTAMP;
161 161
 SQL;
162
-        $stmt = $this->dbObject->prepare($query);
163
-        $stmt->bindValue(':onwikiname', $onWikiName, PDO::PARAM_STR);
164
-        $stmt->execute();
165
-    }
166
-
167
-    /**
168
-     * Queries the Wikimedia API to determine if the specified user is listed on the identification noticeboard.
169
-     *
170
-     * @param string $onWikiName The Wikipedia username of the user
171
-     *
172
-     * @return bool
173
-     * @throws EnvironmentException
174
-     * @category Security-Critical
175
-     */
176
-    private function isIdentifiedOnWiki($onWikiName)
177
-    {
178
-        $strings = new StringFunctions();
179
-
180
-        // First character of Wikipedia usernames is always capitalized.
181
-        $onWikiName = $strings->ucfirst($onWikiName);
182
-
183
-        $parameters = self::$apiQueryParameters;
184
-        $parameters['pltitles'] = "User:" . $onWikiName;
185
-
186
-        try {
187
-            $endpoint = $this->siteConfiguration->getMetaWikimediaWebServiceEndpoint();
188
-            $response = $this->httpHelper->get($endpoint, $parameters);
189
-            $response = json_decode($response, true);
190
-        } catch (CurlException $ex) {
191
-            // failed getting identification status, so throw a nicer error.
192
-            $m = 'Could not contact metawiki API to determine user\' identification status. '
193
-                . 'This is probably a transient error, so please try again.';
194
-
195
-            throw new EnvironmentException($m, 0, $ex);
196
-        }
197
-
198
-        $page = @array_pop($response['query']['pages']);
199
-
200
-        return @$page['links'][0]['title'] === "User:" . $onWikiName;
201
-    }
162
+		$stmt = $this->dbObject->prepare($query);
163
+		$stmt->bindValue(':onwikiname', $onWikiName, PDO::PARAM_STR);
164
+		$stmt->execute();
165
+	}
166
+
167
+	/**
168
+	 * Queries the Wikimedia API to determine if the specified user is listed on the identification noticeboard.
169
+	 *
170
+	 * @param string $onWikiName The Wikipedia username of the user
171
+	 *
172
+	 * @return bool
173
+	 * @throws EnvironmentException
174
+	 * @category Security-Critical
175
+	 */
176
+	private function isIdentifiedOnWiki($onWikiName)
177
+	{
178
+		$strings = new StringFunctions();
179
+
180
+		// First character of Wikipedia usernames is always capitalized.
181
+		$onWikiName = $strings->ucfirst($onWikiName);
182
+
183
+		$parameters = self::$apiQueryParameters;
184
+		$parameters['pltitles'] = "User:" . $onWikiName;
185
+
186
+		try {
187
+			$endpoint = $this->siteConfiguration->getMetaWikimediaWebServiceEndpoint();
188
+			$response = $this->httpHelper->get($endpoint, $parameters);
189
+			$response = json_decode($response, true);
190
+		} catch (CurlException $ex) {
191
+			// failed getting identification status, so throw a nicer error.
192
+			$m = 'Could not contact metawiki API to determine user\' identification status. '
193
+				. 'This is probably a transient error, so please try again.';
194
+
195
+			throw new EnvironmentException($m, 0, $ex);
196
+		}
197
+
198
+		$page = @array_pop($response['query']['pages']);
199
+
200
+		return @$page['links'][0]['title'] === "User:" . $onWikiName;
201
+	}
202 202
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -187,7 +187,8 @@
 block discarded – undo
187 187
             $endpoint = $this->siteConfiguration->getMetaWikimediaWebServiceEndpoint();
188 188
             $response = $this->httpHelper->get($endpoint, $parameters);
189 189
             $response = json_decode($response, true);
190
-        } catch (CurlException $ex) {
190
+        }
191
+        catch (CurlException $ex) {
191 192
             // failed getting identification status, so throw a nicer error.
192 193
             $m = 'Could not contact metawiki API to determine user\' identification status. '
193 194
                 . 'This is probably a transient error, so please try again.';
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
         $onWikiName = $strings->ucfirst($onWikiName);
182 182
 
183 183
         $parameters = self::$apiQueryParameters;
184
-        $parameters['pltitles'] = "User:" . $onWikiName;
184
+        $parameters['pltitles'] = "User:".$onWikiName;
185 185
 
186 186
         try {
187 187
             $endpoint = $this->siteConfiguration->getMetaWikimediaWebServiceEndpoint();
@@ -197,6 +197,6 @@  discard block
 block discarded – undo
197 197
 
198 198
         $page = @array_pop($response['query']['pages']);
199 199
 
200
-        return @$page['links'][0]['title'] === "User:" . $onWikiName;
200
+        return @$page['links'][0]['title'] === "User:".$onWikiName;
201 201
     }
202 202
 }
Please login to merge, or discard this patch.
includes/Exceptions/AccessDeniedException.php 3 patches
Unused Use Statements   -2 removed lines patch added patch discarded remove patch
@@ -11,9 +11,7 @@
 block discarded – undo
11 11
 use Waca\DataObjects\Log;
12 12
 use Waca\DataObjects\User;
13 13
 use Waca\Fragments\NavigationMenuAccessControl;
14
-use Waca\Helpers\HttpHelper;
15 14
 use Waca\Helpers\SearchHelpers\LogSearchHelper;
16
-use Waca\IdentificationVerifier;
17 15
 use Waca\PdoDatabase;
18 16
 use Waca\Security\SecurityManager;
19 17
 
Please login to merge, or discard this patch.
Indentation   +85 added lines, -85 removed lines patch added patch discarded remove patch
@@ -26,89 +26,89 @@
 block discarded – undo
26 26
  */
27 27
 class AccessDeniedException extends ReadableException
28 28
 {
29
-    use NavigationMenuAccessControl;
30
-
31
-    /**
32
-     * @var SecurityManager
33
-     */
34
-    private $securityManager;
35
-
36
-    /**
37
-     * AccessDeniedException constructor.
38
-     *
39
-     * @param SecurityManager $securityManager
40
-     */
41
-    public function __construct(SecurityManager $securityManager = null)
42
-    {
43
-        $this->securityManager = $securityManager;
44
-    }
45
-
46
-    public function getReadableError()
47
-    {
48
-        if (!headers_sent()) {
49
-            header("HTTP/1.1 403 Forbidden");
50
-        }
51
-
52
-        $this->setUpSmarty();
53
-
54
-        // uck. We should still be able to access the database in this situation though.
55
-        $database = PdoDatabase::getDatabaseConnection('acc');
56
-        $currentUser = User::getCurrent($database);
57
-        $this->assign('currentUser', $currentUser);
58
-        $this->assign("loggedIn", (!$currentUser->isCommunityUser()));
59
-
60
-        if($this->securityManager !== null) {
61
-            $this->setupNavMenuAccess($currentUser);
62
-        }
63
-
64
-        if ($currentUser->isDeclined()) {
65
-            $this->assign('htmlTitle', 'Account Declined');
66
-            $this->assign('declineReason', $this->getLogEntry('Declined', $currentUser, $database));
67
-
68
-            return $this->fetchTemplate("exception/account-declined.tpl");
69
-        }
70
-
71
-        if ($currentUser->isSuspended()) {
72
-            $this->assign('htmlTitle', 'Account Suspended');
73
-            $this->assign('suspendReason', $this->getLogEntry('Suspended', $currentUser, $database));
74
-
75
-            return $this->fetchTemplate("exception/account-suspended.tpl");
76
-        }
77
-
78
-        if ($currentUser->isNewUser()) {
79
-            $this->assign('htmlTitle', 'Account Pending');
80
-
81
-            return $this->fetchTemplate("exception/account-new.tpl");
82
-        }
83
-
84
-        return $this->fetchTemplate("exception/access-denied.tpl");
85
-    }
86
-
87
-    /**
88
-     * @param string      $action
89
-     * @param User        $user
90
-     * @param PdoDatabase $database
91
-     *
92
-     * @return null|string
93
-     */
94
-    private function getLogEntry($action, User $user, PdoDatabase $database)
95
-    {
96
-        /** @var Log[] $logs */
97
-        $logs = LogSearchHelper::get($database)
98
-            ->byAction($action)
99
-            ->byObjectType('User')
100
-            ->byObjectId($user->getId())
101
-            ->limit(1)
102
-            ->fetch();
103
-
104
-        return $logs[0]->getComment();
105
-    }
106
-
107
-    /**
108
-     * @return SecurityManager
109
-     */
110
-    protected function getSecurityManager()
111
-    {
112
-        return $this->securityManager;
113
-    }
29
+	use NavigationMenuAccessControl;
30
+
31
+	/**
32
+	 * @var SecurityManager
33
+	 */
34
+	private $securityManager;
35
+
36
+	/**
37
+	 * AccessDeniedException constructor.
38
+	 *
39
+	 * @param SecurityManager $securityManager
40
+	 */
41
+	public function __construct(SecurityManager $securityManager = null)
42
+	{
43
+		$this->securityManager = $securityManager;
44
+	}
45
+
46
+	public function getReadableError()
47
+	{
48
+		if (!headers_sent()) {
49
+			header("HTTP/1.1 403 Forbidden");
50
+		}
51
+
52
+		$this->setUpSmarty();
53
+
54
+		// uck. We should still be able to access the database in this situation though.
55
+		$database = PdoDatabase::getDatabaseConnection('acc');
56
+		$currentUser = User::getCurrent($database);
57
+		$this->assign('currentUser', $currentUser);
58
+		$this->assign("loggedIn", (!$currentUser->isCommunityUser()));
59
+
60
+		if($this->securityManager !== null) {
61
+			$this->setupNavMenuAccess($currentUser);
62
+		}
63
+
64
+		if ($currentUser->isDeclined()) {
65
+			$this->assign('htmlTitle', 'Account Declined');
66
+			$this->assign('declineReason', $this->getLogEntry('Declined', $currentUser, $database));
67
+
68
+			return $this->fetchTemplate("exception/account-declined.tpl");
69
+		}
70
+
71
+		if ($currentUser->isSuspended()) {
72
+			$this->assign('htmlTitle', 'Account Suspended');
73
+			$this->assign('suspendReason', $this->getLogEntry('Suspended', $currentUser, $database));
74
+
75
+			return $this->fetchTemplate("exception/account-suspended.tpl");
76
+		}
77
+
78
+		if ($currentUser->isNewUser()) {
79
+			$this->assign('htmlTitle', 'Account Pending');
80
+
81
+			return $this->fetchTemplate("exception/account-new.tpl");
82
+		}
83
+
84
+		return $this->fetchTemplate("exception/access-denied.tpl");
85
+	}
86
+
87
+	/**
88
+	 * @param string      $action
89
+	 * @param User        $user
90
+	 * @param PdoDatabase $database
91
+	 *
92
+	 * @return null|string
93
+	 */
94
+	private function getLogEntry($action, User $user, PdoDatabase $database)
95
+	{
96
+		/** @var Log[] $logs */
97
+		$logs = LogSearchHelper::get($database)
98
+			->byAction($action)
99
+			->byObjectType('User')
100
+			->byObjectId($user->getId())
101
+			->limit(1)
102
+			->fetch();
103
+
104
+		return $logs[0]->getComment();
105
+	}
106
+
107
+	/**
108
+	 * @return SecurityManager
109
+	 */
110
+	protected function getSecurityManager()
111
+	{
112
+		return $this->securityManager;
113
+	}
114 114
 }
115 115
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@
 block discarded – undo
57 57
         $this->assign('currentUser', $currentUser);
58 58
         $this->assign("loggedIn", (!$currentUser->isCommunityUser()));
59 59
 
60
-        if($this->securityManager !== null) {
60
+        if ($this->securityManager !== null) {
61 61
             $this->setupNavMenuAccess($currentUser);
62 62
         }
63 63
 
Please login to merge, or discard this patch.
includes/Fragments/NavigationMenuAccessControl.php 2 patches
Doc Comments   +5 added lines, -1 removed lines patch added patch discarded remove patch
@@ -24,6 +24,10 @@  discard block
 block discarded – undo
24 24
 
25 25
 trait NavigationMenuAccessControl
26 26
 {
27
+    /**
28
+     * @param string $name
29
+     * @param boolean $value
30
+     */
27 31
     protected abstract function assign($name, $value);
28 32
 
29 33
     /**
@@ -32,7 +36,7 @@  discard block
 block discarded – undo
32 36
     protected abstract function getSecurityManager();
33 37
 
34 38
     /**
35
-     * @param $currentUser
39
+     * @param \Waca\DataObjects\User $currentUser
36 40
      */
37 41
     protected function setupNavMenuAccess($currentUser)
38 42
     {
Please login to merge, or discard this patch.
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -25,48 +25,48 @@
 block discarded – undo
25 25
 
26 26
 trait NavigationMenuAccessControl
27 27
 {
28
-    protected abstract function assign($name, $value);
28
+	protected abstract function assign($name, $value);
29 29
 
30
-    /**
31
-     * @return SecurityManager
32
-     */
33
-    protected abstract function getSecurityManager();
30
+	/**
31
+	 * @return SecurityManager
32
+	 */
33
+	protected abstract function getSecurityManager();
34 34
 
35
-    /**
36
-     * @param $currentUser
37
-     */
38
-    protected function setupNavMenuAccess($currentUser)
39
-    {
40
-        $this->assign('nav__canRequests', $this->getSecurityManager()
41
-                ->allows(PageMain::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
35
+	/**
36
+	 * @param $currentUser
37
+	 */
38
+	protected function setupNavMenuAccess($currentUser)
39
+	{
40
+		$this->assign('nav__canRequests', $this->getSecurityManager()
41
+				->allows(PageMain::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
42 42
 
43
-        $this->assign('nav__canLogs', $this->getSecurityManager()
44
-                ->allows(PageLog::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
45
-        $this->assign('nav__canUsers', $this->getSecurityManager()
46
-                ->allows(StatsUsers::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
47
-        $this->assign('nav__canSearch', $this->getSecurityManager()
48
-                ->allows(PageSearch::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
49
-        $this->assign('nav__canStats', $this->getSecurityManager()
50
-                ->allows(StatsMain::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
43
+		$this->assign('nav__canLogs', $this->getSecurityManager()
44
+				->allows(PageLog::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
45
+		$this->assign('nav__canUsers', $this->getSecurityManager()
46
+				->allows(StatsUsers::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
47
+		$this->assign('nav__canSearch', $this->getSecurityManager()
48
+				->allows(PageSearch::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
49
+		$this->assign('nav__canStats', $this->getSecurityManager()
50
+				->allows(StatsMain::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
51 51
 
52
-        $this->assign('nav__canBan', $this->getSecurityManager()
53
-                ->allows(PageBan::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
54
-        $this->assign('nav__canEmailMgmt', $this->getSecurityManager()
55
-                ->allows(PageEmailManagement::class, RoleConfiguration::MAIN,
56
-                    $currentUser) === SecurityManager::ALLOWED);
57
-        $this->assign('nav__canWelcomeMgmt', $this->getSecurityManager()
58
-                ->allows(PageWelcomeTemplateManagement::class, RoleConfiguration::MAIN,
59
-                    $currentUser) === SecurityManager::ALLOWED);
60
-        $this->assign('nav__canSiteNoticeMgmt', $this->getSecurityManager()
61
-                ->allows(PageSiteNotice::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
62
-        $this->assign('nav__canUserMgmt', $this->getSecurityManager()
63
-                ->allows(PageUserManagement::class, RoleConfiguration::MAIN,
64
-                    $currentUser) === SecurityManager::ALLOWED);
65
-        $this->assign('nav__canJobQueue', $this->getSecurityManager()
66
-                ->allows(PageJobQueue::class, RoleConfiguration::MAIN,
67
-                    $currentUser) === SecurityManager::ALLOWED);
52
+		$this->assign('nav__canBan', $this->getSecurityManager()
53
+				->allows(PageBan::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
54
+		$this->assign('nav__canEmailMgmt', $this->getSecurityManager()
55
+				->allows(PageEmailManagement::class, RoleConfiguration::MAIN,
56
+					$currentUser) === SecurityManager::ALLOWED);
57
+		$this->assign('nav__canWelcomeMgmt', $this->getSecurityManager()
58
+				->allows(PageWelcomeTemplateManagement::class, RoleConfiguration::MAIN,
59
+					$currentUser) === SecurityManager::ALLOWED);
60
+		$this->assign('nav__canSiteNoticeMgmt', $this->getSecurityManager()
61
+				->allows(PageSiteNotice::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
62
+		$this->assign('nav__canUserMgmt', $this->getSecurityManager()
63
+				->allows(PageUserManagement::class, RoleConfiguration::MAIN,
64
+					$currentUser) === SecurityManager::ALLOWED);
65
+		$this->assign('nav__canJobQueue', $this->getSecurityManager()
66
+				->allows(PageJobQueue::class, RoleConfiguration::MAIN,
67
+					$currentUser) === SecurityManager::ALLOWED);
68 68
 
69
-        $this->assign('nav__canViewRequest', $this->getSecurityManager()
70
-                ->allows(PageViewRequest::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
71
-    }
69
+		$this->assign('nav__canViewRequest', $this->getSecurityManager()
70
+				->allows(PageViewRequest::class, RoleConfiguration::MAIN, $currentUser) === SecurityManager::ALLOWED);
71
+	}
72 72
 }
73 73
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/Registration/PageRegisterBase.php 2 patches
Doc Comments   +8 added lines, -5 removed lines patch added patch discarded remove patch
@@ -44,6 +44,9 @@  discard block
 block discarded – undo
44 44
         }
45 45
     }
46 46
 
47
+    /**
48
+     * @return string
49
+     */
47 50
     protected abstract function getRegistrationTemplate();
48 51
 
49 52
     protected function isProtectedPage()
@@ -70,12 +73,12 @@  discard block
 block discarded – undo
70 73
     }
71 74
 
72 75
     /**
73
-     * @param $emailAddress
74
-     * @param $password
75
-     * @param $username
76
+     * @param null|string $emailAddress
77
+     * @param null|string $password
78
+     * @param null|string $username
76 79
      * @param $useOAuthSignup
77
-     * @param $confirmationId
78
-     * @param $onwikiUsername
80
+     * @param null|integer $confirmationId
81
+     * @param null|string $onwikiUsername
79 82
      *
80 83
      * @throws ApplicationLogicException
81 84
      */
Please login to merge, or discard this patch.
Indentation   +196 added lines, -196 removed lines patch added patch discarded remove patch
@@ -20,200 +20,200 @@
 block discarded – undo
20 20
 
21 21
 abstract class PageRegisterBase extends InternalPageBase
22 22
 {
23
-    /**
24
-     * Main function for this page, when no specific actions are called.
25
-     */
26
-    protected function main()
27
-    {
28
-        $useOAuthSignup = $this->getSiteConfiguration()->getUseOAuthSignup();
29
-
30
-        // Dual-mode page
31
-        if (WebRequest::wasPosted()) {
32
-            $this->validateCSRFToken();
33
-
34
-            try {
35
-                $this->handlePost($useOAuthSignup);
36
-            }
37
-            catch (ApplicationLogicException $ex) {
38
-                SessionAlert::error($ex->getMessage());
39
-                $this->redirect('register');
40
-            }
41
-        }
42
-        else {
43
-            $this->assignCSRFToken();
44
-            $this->assign("useOAuthSignup", $useOAuthSignup);
45
-            $this->setTemplate($this->getRegistrationTemplate());
46
-        }
47
-    }
48
-
49
-    protected abstract function getRegistrationTemplate();
50
-
51
-    protected function isProtectedPage()
52
-    {
53
-        return false;
54
-    }
55
-
56
-    /**
57
-     * @param string $emailAddress
58
-     *
59
-     * @throws ApplicationLogicException
60
-     */
61
-    protected function validateUniqueEmail($emailAddress)
62
-    {
63
-        $query = 'SELECT COUNT(id) FROM user WHERE email = :email';
64
-        $statement = $this->getDatabase()->prepare($query);
65
-        $statement->execute(array(':email' => $emailAddress));
66
-
67
-        if ($statement->fetchColumn() > 0) {
68
-            throw new ApplicationLogicException('That email address is already in use on this system.');
69
-        }
70
-
71
-        $statement->closeCursor();
72
-    }
73
-
74
-    /**
75
-     * @param $emailAddress
76
-     * @param $password
77
-     * @param $username
78
-     * @param $useOAuthSignup
79
-     * @param $confirmationId
80
-     * @param $onwikiUsername
81
-     *
82
-     * @throws ApplicationLogicException
83
-     */
84
-    protected function validateRequest(
85
-        $emailAddress,
86
-        $password,
87
-        $username,
88
-        $useOAuthSignup,
89
-        $confirmationId,
90
-        $onwikiUsername
91
-    ) {
92
-        if (!WebRequest::postBoolean('guidelines')) {
93
-            throw new ApplicationLogicException('You must read the interface guidelines before your request may be submitted.');
94
-        }
95
-
96
-        $this->validateGeneralInformation($emailAddress, $password, $username);
97
-        $this->validateUniqueEmail($emailAddress);
98
-        $this->validateNonOAuthFields($useOAuthSignup, $confirmationId, $onwikiUsername);
99
-    }
100
-
101
-    /**
102
-     * @param $useOAuthSignup
103
-     * @param $confirmationId
104
-     * @param $onwikiUsername
105
-     *
106
-     * @throws ApplicationLogicException
107
-     */
108
-    protected function validateNonOAuthFields($useOAuthSignup, $confirmationId, $onwikiUsername)
109
-    {
110
-        if (!$useOAuthSignup) {
111
-            if ($confirmationId === null || $confirmationId <= 0) {
112
-                throw new ApplicationLogicException('Please enter the revision id of your confirmation edit.');
113
-            }
114
-
115
-            if ($onwikiUsername === null) {
116
-                throw new ApplicationLogicException('Please specify your on-wiki username.');
117
-            }
118
-        }
119
-    }
120
-
121
-    /**
122
-     * @param $emailAddress
123
-     * @param $password
124
-     * @param $username
125
-     *
126
-     * @throws ApplicationLogicException
127
-     */
128
-    protected function validateGeneralInformation($emailAddress, $password, $username)
129
-    {
130
-        if ($emailAddress === null) {
131
-            throw new ApplicationLogicException('Your email address appears to be invalid!');
132
-        }
133
-
134
-        if ($password !== WebRequest::postString('pass2')) {
135
-            throw new ApplicationLogicException('Your passwords did not match, please try again.');
136
-        }
137
-
138
-        if (User::getByUsername($username, $this->getDatabase()) !== false) {
139
-            throw new ApplicationLogicException('That username is already in use on this system.');
140
-        }
141
-    }
142
-
143
-    /**
144
-     * @param $useOAuthSignup
145
-     *
146
-     * @throws ApplicationLogicException
147
-     * @throws \Exception
148
-     */
149
-    protected function handlePost($useOAuthSignup)
150
-    {
151
-        // Get the data
152
-        $emailAddress = WebRequest::postEmail('email');
153
-        $password = WebRequest::postString('pass');
154
-        $username = WebRequest::postString('name');
155
-
156
-        // Only set if OAuth is disabled
157
-        $confirmationId = WebRequest::postInt('conf_revid');
158
-        $onwikiUsername = WebRequest::postString('wname');
159
-
160
-        // Do some validation
161
-        $this->validateRequest($emailAddress, $password, $username, $useOAuthSignup, $confirmationId,
162
-            $onwikiUsername);
163
-
164
-        $database = $this->getDatabase();
165
-
166
-        $user = new User();
167
-        $user->setDatabase($database);
168
-
169
-        $user->setUsername($username);
170
-        $user->setEmail($emailAddress);
171
-
172
-        if (!$useOAuthSignup) {
173
-            $user->setOnWikiName($onwikiUsername);
174
-            $user->setConfirmationDiff($confirmationId);
175
-        }
176
-
177
-        $user->save();
178
-
179
-        $passwordCredentialProvider = new PasswordCredentialProvider($database, $this->getSiteConfiguration());
180
-        $passwordCredentialProvider->setCredential($user, 1, $password);
181
-
182
-        $defaultRole = $this->getDefaultRole();
183
-
184
-        $role = new UserRole();
185
-        $role->setDatabase($database);
186
-        $role->setUser($user->getId());
187
-        $role->setRole($defaultRole);
188
-        $role->save();
189
-
190
-        // Log now to get the signup date.
191
-        Logger::newUser($database, $user);
192
-        Logger::userRolesEdited($database, $user, 'Registration', array($defaultRole), array());
193
-
194
-        if ($useOAuthSignup) {
195
-            $oauthProtocolHelper = $this->getOAuthProtocolHelper();
196
-            $oauth = new OAuthUserHelper($user, $database, $oauthProtocolHelper, $this->getSiteConfiguration());
197
-
198
-            $authoriseUrl = $oauth->getRequestToken();
199
-            WebRequest::setOAuthPartialLogin($user);
200
-            $this->redirectUrl($authoriseUrl);
201
-        }
202
-        else {
203
-            // only notify if we're not using the oauth signup.
204
-            $this->getNotificationHelper()->userNew($user);
205
-            WebRequest::setLoggedInUser($user);
206
-            $this->redirect('preferences');
207
-        }
208
-    }
209
-
210
-    protected abstract function getDefaultRole();
211
-
212
-    /**
213
-     * Entry point for registration complete
214
-     */
215
-    protected function done()
216
-    {
217
-        $this->setTemplate('registration/alert-registrationcomplete.tpl');
218
-    }
23
+	/**
24
+	 * Main function for this page, when no specific actions are called.
25
+	 */
26
+	protected function main()
27
+	{
28
+		$useOAuthSignup = $this->getSiteConfiguration()->getUseOAuthSignup();
29
+
30
+		// Dual-mode page
31
+		if (WebRequest::wasPosted()) {
32
+			$this->validateCSRFToken();
33
+
34
+			try {
35
+				$this->handlePost($useOAuthSignup);
36
+			}
37
+			catch (ApplicationLogicException $ex) {
38
+				SessionAlert::error($ex->getMessage());
39
+				$this->redirect('register');
40
+			}
41
+		}
42
+		else {
43
+			$this->assignCSRFToken();
44
+			$this->assign("useOAuthSignup", $useOAuthSignup);
45
+			$this->setTemplate($this->getRegistrationTemplate());
46
+		}
47
+	}
48
+
49
+	protected abstract function getRegistrationTemplate();
50
+
51
+	protected function isProtectedPage()
52
+	{
53
+		return false;
54
+	}
55
+
56
+	/**
57
+	 * @param string $emailAddress
58
+	 *
59
+	 * @throws ApplicationLogicException
60
+	 */
61
+	protected function validateUniqueEmail($emailAddress)
62
+	{
63
+		$query = 'SELECT COUNT(id) FROM user WHERE email = :email';
64
+		$statement = $this->getDatabase()->prepare($query);
65
+		$statement->execute(array(':email' => $emailAddress));
66
+
67
+		if ($statement->fetchColumn() > 0) {
68
+			throw new ApplicationLogicException('That email address is already in use on this system.');
69
+		}
70
+
71
+		$statement->closeCursor();
72
+	}
73
+
74
+	/**
75
+	 * @param $emailAddress
76
+	 * @param $password
77
+	 * @param $username
78
+	 * @param $useOAuthSignup
79
+	 * @param $confirmationId
80
+	 * @param $onwikiUsername
81
+	 *
82
+	 * @throws ApplicationLogicException
83
+	 */
84
+	protected function validateRequest(
85
+		$emailAddress,
86
+		$password,
87
+		$username,
88
+		$useOAuthSignup,
89
+		$confirmationId,
90
+		$onwikiUsername
91
+	) {
92
+		if (!WebRequest::postBoolean('guidelines')) {
93
+			throw new ApplicationLogicException('You must read the interface guidelines before your request may be submitted.');
94
+		}
95
+
96
+		$this->validateGeneralInformation($emailAddress, $password, $username);
97
+		$this->validateUniqueEmail($emailAddress);
98
+		$this->validateNonOAuthFields($useOAuthSignup, $confirmationId, $onwikiUsername);
99
+	}
100
+
101
+	/**
102
+	 * @param $useOAuthSignup
103
+	 * @param $confirmationId
104
+	 * @param $onwikiUsername
105
+	 *
106
+	 * @throws ApplicationLogicException
107
+	 */
108
+	protected function validateNonOAuthFields($useOAuthSignup, $confirmationId, $onwikiUsername)
109
+	{
110
+		if (!$useOAuthSignup) {
111
+			if ($confirmationId === null || $confirmationId <= 0) {
112
+				throw new ApplicationLogicException('Please enter the revision id of your confirmation edit.');
113
+			}
114
+
115
+			if ($onwikiUsername === null) {
116
+				throw new ApplicationLogicException('Please specify your on-wiki username.');
117
+			}
118
+		}
119
+	}
120
+
121
+	/**
122
+	 * @param $emailAddress
123
+	 * @param $password
124
+	 * @param $username
125
+	 *
126
+	 * @throws ApplicationLogicException
127
+	 */
128
+	protected function validateGeneralInformation($emailAddress, $password, $username)
129
+	{
130
+		if ($emailAddress === null) {
131
+			throw new ApplicationLogicException('Your email address appears to be invalid!');
132
+		}
133
+
134
+		if ($password !== WebRequest::postString('pass2')) {
135
+			throw new ApplicationLogicException('Your passwords did not match, please try again.');
136
+		}
137
+
138
+		if (User::getByUsername($username, $this->getDatabase()) !== false) {
139
+			throw new ApplicationLogicException('That username is already in use on this system.');
140
+		}
141
+	}
142
+
143
+	/**
144
+	 * @param $useOAuthSignup
145
+	 *
146
+	 * @throws ApplicationLogicException
147
+	 * @throws \Exception
148
+	 */
149
+	protected function handlePost($useOAuthSignup)
150
+	{
151
+		// Get the data
152
+		$emailAddress = WebRequest::postEmail('email');
153
+		$password = WebRequest::postString('pass');
154
+		$username = WebRequest::postString('name');
155
+
156
+		// Only set if OAuth is disabled
157
+		$confirmationId = WebRequest::postInt('conf_revid');
158
+		$onwikiUsername = WebRequest::postString('wname');
159
+
160
+		// Do some validation
161
+		$this->validateRequest($emailAddress, $password, $username, $useOAuthSignup, $confirmationId,
162
+			$onwikiUsername);
163
+
164
+		$database = $this->getDatabase();
165
+
166
+		$user = new User();
167
+		$user->setDatabase($database);
168
+
169
+		$user->setUsername($username);
170
+		$user->setEmail($emailAddress);
171
+
172
+		if (!$useOAuthSignup) {
173
+			$user->setOnWikiName($onwikiUsername);
174
+			$user->setConfirmationDiff($confirmationId);
175
+		}
176
+
177
+		$user->save();
178
+
179
+		$passwordCredentialProvider = new PasswordCredentialProvider($database, $this->getSiteConfiguration());
180
+		$passwordCredentialProvider->setCredential($user, 1, $password);
181
+
182
+		$defaultRole = $this->getDefaultRole();
183
+
184
+		$role = new UserRole();
185
+		$role->setDatabase($database);
186
+		$role->setUser($user->getId());
187
+		$role->setRole($defaultRole);
188
+		$role->save();
189
+
190
+		// Log now to get the signup date.
191
+		Logger::newUser($database, $user);
192
+		Logger::userRolesEdited($database, $user, 'Registration', array($defaultRole), array());
193
+
194
+		if ($useOAuthSignup) {
195
+			$oauthProtocolHelper = $this->getOAuthProtocolHelper();
196
+			$oauth = new OAuthUserHelper($user, $database, $oauthProtocolHelper, $this->getSiteConfiguration());
197
+
198
+			$authoriseUrl = $oauth->getRequestToken();
199
+			WebRequest::setOAuthPartialLogin($user);
200
+			$this->redirectUrl($authoriseUrl);
201
+		}
202
+		else {
203
+			// only notify if we're not using the oauth signup.
204
+			$this->getNotificationHelper()->userNew($user);
205
+			WebRequest::setLoggedInUser($user);
206
+			$this->redirect('preferences');
207
+		}
208
+	}
209
+
210
+	protected abstract function getDefaultRole();
211
+
212
+	/**
213
+	 * Entry point for registration complete
214
+	 */
215
+	protected function done()
216
+	{
217
+		$this->setTemplate('registration/alert-registrationcomplete.tpl');
218
+	}
219 219
 }
Please login to merge, or discard this patch.
includes/Security/SecurityManager.php 3 patches
Indentation   +196 added lines, -196 removed lines patch added patch discarded remove patch
@@ -14,200 +14,200 @@
 block discarded – undo
14 14
 
15 15
 final class SecurityManager
16 16
 {
17
-    const ALLOWED = 1;
18
-    const ERROR_NOT_IDENTIFIED = 2;
19
-    const ERROR_DENIED = 3;
20
-    /** @var IdentificationVerifier */
21
-    private $identificationVerifier;
22
-    /**
23
-     * @var RoleConfiguration
24
-     */
25
-    private $roleConfiguration;
26
-
27
-    /**
28
-     * SecurityManager constructor.
29
-     *
30
-     * @param IdentificationVerifier $identificationVerifier
31
-     * @param RoleConfiguration      $roleConfiguration
32
-     */
33
-    public function __construct(
34
-        IdentificationVerifier $identificationVerifier,
35
-        RoleConfiguration $roleConfiguration
36
-    ) {
37
-        $this->identificationVerifier = $identificationVerifier;
38
-        $this->roleConfiguration = $roleConfiguration;
39
-    }
40
-
41
-    /**
42
-     * Tests if a user is allowed to perform an action.
43
-     *
44
-     * This method should form a hard, deterministic security barrier, and only return true if it is absolutely sure
45
-     * that a user should have access to something.
46
-     *
47
-     * @param string $page
48
-     * @param string $route
49
-     * @param User   $user
50
-     *
51
-     * @return int
52
-     *
53
-     * @category Security-Critical
54
-     */
55
-    public function allows($page, $route, User $user)
56
-    {
57
-        $this->getActiveRoles($user, $activeRoles, $inactiveRoles);
58
-
59
-        $availableRights = $this->flattenRoles($activeRoles);
60
-        $testResult = $this->findResult($availableRights, $page, $route);
61
-
62
-        if ($testResult !== null) {
63
-            // We got a firm result here, so just return it.
64
-            return $testResult;
65
-        }
66
-
67
-        // No firm result yet, so continue testing the inactive roles so we can give a better error.
68
-        $inactiveRights = $this->flattenRoles($inactiveRoles);
69
-        $testResult = $this->findResult($inactiveRights, $page, $route);
70
-
71
-        if ($testResult === self::ALLOWED) {
72
-            // The user is allowed to access this, but their role is inactive.
73
-            return self::ERROR_NOT_IDENTIFIED;
74
-        }
75
-
76
-        // Other options from the secondary test are denied and inconclusive, which at this point defaults to denied.
77
-        return self::ERROR_DENIED;
78
-    }
79
-
80
-    /**
81
-     * @param array  $pseudoRole The role (flattened) to check
82
-     * @param string $page       The page class to check
83
-     * @param string $route      The page route to check
84
-     *
85
-     * @return int|null
86
-     */
87
-    private function findResult($pseudoRole, $page, $route)
88
-    {
89
-        if (isset($pseudoRole[$page])) {
90
-            // check for deny on catch-all route
91
-            if (isset($pseudoRole[$page][RoleConfiguration::ALL])) {
92
-                if ($pseudoRole[$page][RoleConfiguration::ALL] === RoleConfiguration::ACCESS_DENY) {
93
-                    return self::ERROR_DENIED;
94
-                }
95
-            }
96
-
97
-            // check normal route
98
-            if (isset($pseudoRole[$page][$route])) {
99
-                if ($pseudoRole[$page][$route] === RoleConfiguration::ACCESS_DENY) {
100
-                    return self::ERROR_DENIED;
101
-                }
102
-
103
-                if ($pseudoRole[$page][$route] === RoleConfiguration::ACCESS_ALLOW) {
104
-                    return self::ALLOWED;
105
-                }
106
-            }
107
-
108
-            // check for allowed on catch-all route
109
-            if (isset($pseudoRole[$page][RoleConfiguration::ALL])) {
110
-                if ($pseudoRole[$page][RoleConfiguration::ALL] === RoleConfiguration::ACCESS_ALLOW) {
111
-                    return self::ALLOWED;
112
-                }
113
-            }
114
-        }
115
-
116
-        // return indeterminate result
117
-        return null;
118
-    }
119
-
120
-    /**
121
-     * Takes an array of roles and flattens the values to a single set.
122
-     *
123
-     * @param array $activeRoles
124
-     *
125
-     * @return array
126
-     */
127
-    private function flattenRoles($activeRoles)
128
-    {
129
-        $result = array();
130
-
131
-        $roleConfig = $this->roleConfiguration->getApplicableRoles($activeRoles);
132
-
133
-        // Iterate over every page in every role
134
-        foreach ($roleConfig as $role) {
135
-            foreach ($role as $page => $pageRights) {
136
-                // Create holder in result for this page
137
-                if (!isset($result[$page])) {
138
-                    $result[$page] = array();
139
-                }
140
-
141
-                foreach ($pageRights as $action => $permission) {
142
-                    // Deny takes precedence, so if it's set, don't change it.
143
-                    if (isset($result[$page][$action])) {
144
-                        if ($result[$page][$action] === RoleConfiguration::ACCESS_DENY) {
145
-                            continue;
146
-                        }
147
-                    }
148
-
149
-                    if ($permission === RoleConfiguration::ACCESS_DEFAULT) {
150
-                        // Configured to do precisely nothing.
151
-                        continue;
152
-                    }
153
-
154
-                    $result[$page][$action] = $permission;
155
-                }
156
-            }
157
-        }
158
-
159
-        return $result;
160
-    }
161
-
162
-    /**
163
-     * @param User  $user
164
-     * @param array $activeRoles
165
-     * @param array $inactiveRoles
166
-     */
167
-    public function getActiveRoles(User $user, &$activeRoles, &$inactiveRoles)
168
-    {
169
-        // Default to the community user here, because the main user is logged out
170
-        $identified = false;
171
-        $userRoles = array('public');
172
-
173
-        // if we're not the community user, get our real rights.
174
-        if (!$user->isCommunityUser()) {
175
-            // Check the user's status - only active users are allowed the effects of roles
176
-
177
-            $userRoles[] = 'loggedIn';
178
-
179
-            if ($user->isActive()) {
180
-                $ur = UserRole::getForUser($user->getId(), $user->getDatabase());
181
-
182
-                // NOTE: public is still in this array.
183
-                foreach ($ur as $r) {
184
-                    $userRoles[] = $r->getRole();
185
-                }
186
-
187
-                $identified = $user->isIdentified($this->identificationVerifier);
188
-            }
189
-        }
190
-
191
-        $activeRoles = array();
192
-        $inactiveRoles = array();
193
-
194
-        /** @var string $v */
195
-        foreach ($userRoles as $v) {
196
-            if ($this->roleConfiguration->roleNeedsIdentification($v)) {
197
-                if ($identified) {
198
-                    $activeRoles[] = $v;
199
-                }
200
-                else {
201
-                    $inactiveRoles[] = $v;
202
-                }
203
-            }
204
-            else {
205
-                $activeRoles[] = $v;
206
-            }
207
-        }
208
-    }
209
-
210
-    public function getRoleConfiguration(){
211
-        return $this->roleConfiguration;
212
-    }
17
+	const ALLOWED = 1;
18
+	const ERROR_NOT_IDENTIFIED = 2;
19
+	const ERROR_DENIED = 3;
20
+	/** @var IdentificationVerifier */
21
+	private $identificationVerifier;
22
+	/**
23
+	 * @var RoleConfiguration
24
+	 */
25
+	private $roleConfiguration;
26
+
27
+	/**
28
+	 * SecurityManager constructor.
29
+	 *
30
+	 * @param IdentificationVerifier $identificationVerifier
31
+	 * @param RoleConfiguration      $roleConfiguration
32
+	 */
33
+	public function __construct(
34
+		IdentificationVerifier $identificationVerifier,
35
+		RoleConfiguration $roleConfiguration
36
+	) {
37
+		$this->identificationVerifier = $identificationVerifier;
38
+		$this->roleConfiguration = $roleConfiguration;
39
+	}
40
+
41
+	/**
42
+	 * Tests if a user is allowed to perform an action.
43
+	 *
44
+	 * This method should form a hard, deterministic security barrier, and only return true if it is absolutely sure
45
+	 * that a user should have access to something.
46
+	 *
47
+	 * @param string $page
48
+	 * @param string $route
49
+	 * @param User   $user
50
+	 *
51
+	 * @return int
52
+	 *
53
+	 * @category Security-Critical
54
+	 */
55
+	public function allows($page, $route, User $user)
56
+	{
57
+		$this->getActiveRoles($user, $activeRoles, $inactiveRoles);
58
+
59
+		$availableRights = $this->flattenRoles($activeRoles);
60
+		$testResult = $this->findResult($availableRights, $page, $route);
61
+
62
+		if ($testResult !== null) {
63
+			// We got a firm result here, so just return it.
64
+			return $testResult;
65
+		}
66
+
67
+		// No firm result yet, so continue testing the inactive roles so we can give a better error.
68
+		$inactiveRights = $this->flattenRoles($inactiveRoles);
69
+		$testResult = $this->findResult($inactiveRights, $page, $route);
70
+
71
+		if ($testResult === self::ALLOWED) {
72
+			// The user is allowed to access this, but their role is inactive.
73
+			return self::ERROR_NOT_IDENTIFIED;
74
+		}
75
+
76
+		// Other options from the secondary test are denied and inconclusive, which at this point defaults to denied.
77
+		return self::ERROR_DENIED;
78
+	}
79
+
80
+	/**
81
+	 * @param array  $pseudoRole The role (flattened) to check
82
+	 * @param string $page       The page class to check
83
+	 * @param string $route      The page route to check
84
+	 *
85
+	 * @return int|null
86
+	 */
87
+	private function findResult($pseudoRole, $page, $route)
88
+	{
89
+		if (isset($pseudoRole[$page])) {
90
+			// check for deny on catch-all route
91
+			if (isset($pseudoRole[$page][RoleConfiguration::ALL])) {
92
+				if ($pseudoRole[$page][RoleConfiguration::ALL] === RoleConfiguration::ACCESS_DENY) {
93
+					return self::ERROR_DENIED;
94
+				}
95
+			}
96
+
97
+			// check normal route
98
+			if (isset($pseudoRole[$page][$route])) {
99
+				if ($pseudoRole[$page][$route] === RoleConfiguration::ACCESS_DENY) {
100
+					return self::ERROR_DENIED;
101
+				}
102
+
103
+				if ($pseudoRole[$page][$route] === RoleConfiguration::ACCESS_ALLOW) {
104
+					return self::ALLOWED;
105
+				}
106
+			}
107
+
108
+			// check for allowed on catch-all route
109
+			if (isset($pseudoRole[$page][RoleConfiguration::ALL])) {
110
+				if ($pseudoRole[$page][RoleConfiguration::ALL] === RoleConfiguration::ACCESS_ALLOW) {
111
+					return self::ALLOWED;
112
+				}
113
+			}
114
+		}
115
+
116
+		// return indeterminate result
117
+		return null;
118
+	}
119
+
120
+	/**
121
+	 * Takes an array of roles and flattens the values to a single set.
122
+	 *
123
+	 * @param array $activeRoles
124
+	 *
125
+	 * @return array
126
+	 */
127
+	private function flattenRoles($activeRoles)
128
+	{
129
+		$result = array();
130
+
131
+		$roleConfig = $this->roleConfiguration->getApplicableRoles($activeRoles);
132
+
133
+		// Iterate over every page in every role
134
+		foreach ($roleConfig as $role) {
135
+			foreach ($role as $page => $pageRights) {
136
+				// Create holder in result for this page
137
+				if (!isset($result[$page])) {
138
+					$result[$page] = array();
139
+				}
140
+
141
+				foreach ($pageRights as $action => $permission) {
142
+					// Deny takes precedence, so if it's set, don't change it.
143
+					if (isset($result[$page][$action])) {
144
+						if ($result[$page][$action] === RoleConfiguration::ACCESS_DENY) {
145
+							continue;
146
+						}
147
+					}
148
+
149
+					if ($permission === RoleConfiguration::ACCESS_DEFAULT) {
150
+						// Configured to do precisely nothing.
151
+						continue;
152
+					}
153
+
154
+					$result[$page][$action] = $permission;
155
+				}
156
+			}
157
+		}
158
+
159
+		return $result;
160
+	}
161
+
162
+	/**
163
+	 * @param User  $user
164
+	 * @param array $activeRoles
165
+	 * @param array $inactiveRoles
166
+	 */
167
+	public function getActiveRoles(User $user, &$activeRoles, &$inactiveRoles)
168
+	{
169
+		// Default to the community user here, because the main user is logged out
170
+		$identified = false;
171
+		$userRoles = array('public');
172
+
173
+		// if we're not the community user, get our real rights.
174
+		if (!$user->isCommunityUser()) {
175
+			// Check the user's status - only active users are allowed the effects of roles
176
+
177
+			$userRoles[] = 'loggedIn';
178
+
179
+			if ($user->isActive()) {
180
+				$ur = UserRole::getForUser($user->getId(), $user->getDatabase());
181
+
182
+				// NOTE: public is still in this array.
183
+				foreach ($ur as $r) {
184
+					$userRoles[] = $r->getRole();
185
+				}
186
+
187
+				$identified = $user->isIdentified($this->identificationVerifier);
188
+			}
189
+		}
190
+
191
+		$activeRoles = array();
192
+		$inactiveRoles = array();
193
+
194
+		/** @var string $v */
195
+		foreach ($userRoles as $v) {
196
+			if ($this->roleConfiguration->roleNeedsIdentification($v)) {
197
+				if ($identified) {
198
+					$activeRoles[] = $v;
199
+				}
200
+				else {
201
+					$inactiveRoles[] = $v;
202
+				}
203
+			}
204
+			else {
205
+				$activeRoles[] = $v;
206
+			}
207
+		}
208
+	}
209
+
210
+	public function getRoleConfiguration(){
211
+		return $this->roleConfiguration;
212
+	}
213 213
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -207,7 +207,7 @@
 block discarded – undo
207 207
         }
208 208
     }
209 209
 
210
-    public function getRoleConfiguration(){
210
+    public function getRoleConfiguration() {
211 211
         return $this->roleConfiguration;
212 212
     }
213 213
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -207,7 +207,8 @@
 block discarded – undo
207 207
         }
208 208
     }
209 209
 
210
-    public function getRoleConfiguration(){
210
+    public function getRoleConfiguration()
211
+    {
211 212
         return $this->roleConfiguration;
212 213
     }
213 214
 }
Please login to merge, or discard this patch.