Completed
Push — newinternal-releasecandidate ( 06bb07...1c5b59 )
by Simon
06:04
created
smarty-plugins/modifier.relativedate.php 2 patches
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -16,73 +16,73 @@
 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
-        try {
28
-            $then = new DateTime($input);
29
-        }
30
-        catch(Exception $ex) {
31
-            return $input;
32
-        }
33
-    }
21
+	if (gettype($input) === 'object'
22
+		&& (get_class($input) === DateTime::class || get_class($input) === DateTimeImmutable::class)
23
+	) {
24
+		$then = $input;
25
+	}
26
+	else {
27
+		try {
28
+			$then = new DateTime($input);
29
+		}
30
+		catch(Exception $ex) {
31
+			return $input;
32
+		}
33
+	}
34 34
 
35
-    $secs = $now->getTimestamp() - $then->getTimestamp();
35
+	$secs = $now->getTimestamp() - $then->getTimestamp();
36 36
 
37
-    $second = 1;
38
-    $minute = 60 * $second;
39
-    $minuteCut = 60 * $second;
40
-    $hour = 60 * $minute;
41
-    $hourCut = 90 * $minute;
42
-    $day = 24 * $hour;
43
-    $dayCut = 48 * $hour;
44
-    $week = 7 * $day;
45
-    $weekCut = 14 * $day;
46
-    $month = 30 * $day;
47
-    $monthCut = 60 * $day;
48
-    $year = 365 * $day;
49
-    $yearCut = $year * 2;
37
+	$second = 1;
38
+	$minute = 60 * $second;
39
+	$minuteCut = 60 * $second;
40
+	$hour = 60 * $minute;
41
+	$hourCut = 90 * $minute;
42
+	$day = 24 * $hour;
43
+	$dayCut = 48 * $hour;
44
+	$week = 7 * $day;
45
+	$weekCut = 14 * $day;
46
+	$month = 30 * $day;
47
+	$monthCut = 60 * $day;
48
+	$year = 365 * $day;
49
+	$yearCut = $year * 2;
50 50
 
51
-    $pluralise = true;
51
+	$pluralise = true;
52 52
 
53
-    if ($secs <= 10) {
54
-        $output = "just now";
55
-        $pluralise = false;
56
-    }
57
-    elseif ($secs > 10 && $secs < $minuteCut) {
58
-        $output = round($secs / $second) . " second";
59
-    }
60
-    elseif ($secs >= $minuteCut && $secs < $hourCut) {
61
-        $output = round($secs / $minute) . " minute";
62
-    }
63
-    elseif ($secs >= $hourCut && $secs < $dayCut) {
64
-        $output = round($secs / $hour) . " hour";
65
-    }
66
-    elseif ($secs >= $dayCut && $secs < $weekCut) {
67
-        $output = round($secs / $day) . " day";
68
-    }
69
-    elseif ($secs >= $weekCut && $secs < $monthCut) {
70
-        $output = round($secs / $week) . " week";
71
-    }
72
-    elseif ($secs >= $monthCut && $secs < $yearCut) {
73
-        $output = round($secs / $month) . " month";
74
-    }
75
-    elseif ($secs >= $yearCut && $secs < $year * 10) {
76
-        $output = round($secs / $year) . " year";
77
-    }
78
-    else {
79
-        $output = "a long time ago";
80
-        $pluralise = false;
81
-    }
53
+	if ($secs <= 10) {
54
+		$output = "just now";
55
+		$pluralise = false;
56
+	}
57
+	elseif ($secs > 10 && $secs < $minuteCut) {
58
+		$output = round($secs / $second) . " second";
59
+	}
60
+	elseif ($secs >= $minuteCut && $secs < $hourCut) {
61
+		$output = round($secs / $minute) . " minute";
62
+	}
63
+	elseif ($secs >= $hourCut && $secs < $dayCut) {
64
+		$output = round($secs / $hour) . " hour";
65
+	}
66
+	elseif ($secs >= $dayCut && $secs < $weekCut) {
67
+		$output = round($secs / $day) . " day";
68
+	}
69
+	elseif ($secs >= $weekCut && $secs < $monthCut) {
70
+		$output = round($secs / $week) . " week";
71
+	}
72
+	elseif ($secs >= $monthCut && $secs < $yearCut) {
73
+		$output = round($secs / $month) . " month";
74
+	}
75
+	elseif ($secs >= $yearCut && $secs < $year * 10) {
76
+		$output = round($secs / $year) . " year";
77
+	}
78
+	else {
79
+		$output = "a long time ago";
80
+		$pluralise = false;
81
+	}
82 82
 
83
-    if ($pluralise) {
84
-        $output = (substr($output, 0, 2) <> "1 ") ? $output . "s ago" : $output . " ago";
85
-    }
83
+	if ($pluralise) {
84
+		$output = (substr($output, 0, 2) <> "1 ") ? $output . "s ago" : $output . " ago";
85
+	}
86 86
 
87
-    return $output;
87
+	return $output;
88 88
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -27,7 +27,7 @@  discard block
 block discarded – undo
27 27
         try {
28 28
             $then = new DateTime($input);
29 29
         }
30
-        catch(Exception $ex) {
30
+        catch (Exception $ex) {
31 31
             return $input;
32 32
         }
33 33
     }
@@ -55,25 +55,25 @@  discard block
 block discarded – undo
55 55
         $pluralise = false;
56 56
     }
57 57
     elseif ($secs > 10 && $secs < $minuteCut) {
58
-        $output = round($secs / $second) . " second";
58
+        $output = round($secs / $second)." second";
59 59
     }
60 60
     elseif ($secs >= $minuteCut && $secs < $hourCut) {
61
-        $output = round($secs / $minute) . " minute";
61
+        $output = round($secs / $minute)." minute";
62 62
     }
63 63
     elseif ($secs >= $hourCut && $secs < $dayCut) {
64
-        $output = round($secs / $hour) . " hour";
64
+        $output = round($secs / $hour)." hour";
65 65
     }
66 66
     elseif ($secs >= $dayCut && $secs < $weekCut) {
67
-        $output = round($secs / $day) . " day";
67
+        $output = round($secs / $day)." day";
68 68
     }
69 69
     elseif ($secs >= $weekCut && $secs < $monthCut) {
70
-        $output = round($secs / $week) . " week";
70
+        $output = round($secs / $week)." week";
71 71
     }
72 72
     elseif ($secs >= $monthCut && $secs < $yearCut) {
73
-        $output = round($secs / $month) . " month";
73
+        $output = round($secs / $month)." month";
74 74
     }
75 75
     elseif ($secs >= $yearCut && $secs < $year * 10) {
76
-        $output = round($secs / $year) . " year";
76
+        $output = round($secs / $year)." year";
77 77
     }
78 78
     else {
79 79
         $output = "a long time ago";
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
     }
82 82
 
83 83
     if ($pluralise) {
84
-        $output = (substr($output, 0, 2) <> "1 ") ? $output . "s ago" : $output . " ago";
84
+        $output = (substr($output, 0, 2) <> "1 ") ? $output."s ago" : $output." ago";
85 85
     }
86 86
 
87 87
     return $output;
Please login to merge, or discard this patch.
includes/DataObjects/User.php 2 patches
Indentation   +567 added lines, -567 removed lines patch added patch discarded remove patch
@@ -21,160 +21,160 @@  discard block
 block discarded – undo
21 21
  */
22 22
 class User extends DataObject
23 23
 {
24
-    const STATUS_ACTIVE = 'Active';
25
-    const STATUS_SUSPENDED = 'Suspended';
26
-    const STATUS_DECLINED = 'Declined';
27
-    const STATUS_NEW = 'New';
28
-    const CREATION_MANUAL = 0;
29
-    const CREATION_OAUTH = 1;
30
-    const CREATION_BOT = 2;
31
-    private $username;
32
-    private $email;
33
-    private $status = self::STATUS_NEW;
34
-    private $onwikiname;
35
-    private $welcome_sig = "";
36
-    private $lastactive = "0000-00-00 00:00:00";
37
-    private $forcelogout = 0;
38
-    private $forceidentified = null;
39
-    private $welcome_template = 0;
40
-    private $abortpref = 0;
41
-    private $confirmationdiff = 0;
42
-    private $emailsig = "";
43
-    private $creationmode = 0;
44
-    private $skin = "main";
45
-    /** @var User Cache variable of the current user - it's never going to change in the middle of a request. */
46
-    private static $currentUser;
47
-    #region Object load methods
48
-
49
-    /**
50
-     * Gets the currently logged in user
51
-     *
52
-     * @param PdoDatabase $database
53
-     *
54
-     * @return User|CommunityUser
55
-     */
56
-    public static function getCurrent(PdoDatabase $database)
57
-    {
58
-        if (self::$currentUser === null) {
59
-            $sessionId = WebRequest::getSessionUserId();
60
-
61
-            if ($sessionId !== null) {
62
-                /** @var User $user */
63
-                $user = self::getById($sessionId, $database);
64
-
65
-                if ($user === false) {
66
-                    self::$currentUser = new CommunityUser();
67
-                }
68
-                else {
69
-                    self::$currentUser = $user;
70
-                }
71
-            }
72
-            else {
73
-                $anonymousCoward = new CommunityUser();
74
-
75
-                self::$currentUser = $anonymousCoward;
76
-            }
77
-        }
78
-
79
-        return self::$currentUser;
80
-    }
81
-
82
-    /**
83
-     * Gets a user by their user ID
84
-     *
85
-     * Pass -1 to get the community user.
86
-     *
87
-     * @param int|null    $id
88
-     * @param PdoDatabase $database
89
-     *
90
-     * @return User|false
91
-     */
92
-    public static function getById($id, PdoDatabase $database)
93
-    {
94
-        if ($id === null || $id == -1) {
95
-            return new CommunityUser();
96
-        }
97
-
98
-        /** @var User|false $user */
99
-        $user = parent::getById($id, $database);
100
-
101
-        return $user;
102
-    }
103
-
104
-    /**
105
-     * @return CommunityUser
106
-     */
107
-    public static function getCommunity()
108
-    {
109
-        return new CommunityUser();
110
-    }
111
-
112
-    /**
113
-     * Gets a user by their username
114
-     *
115
-     * @param  string      $username
116
-     * @param  PdoDatabase $database
117
-     *
118
-     * @return CommunityUser|User|false
119
-     */
120
-    public static function getByUsername($username, PdoDatabase $database)
121
-    {
122
-        global $communityUsername;
123
-        if ($username == $communityUsername) {
124
-            return new CommunityUser();
125
-        }
126
-
127
-        $statement = $database->prepare("SELECT * FROM user WHERE username = :id LIMIT 1;");
128
-        $statement->bindValue(":id", $username);
129
-
130
-        $statement->execute();
131
-
132
-        $resultObject = $statement->fetchObject(get_called_class());
133
-
134
-        if ($resultObject != false) {
135
-            $resultObject->setDatabase($database);
136
-        }
137
-
138
-        return $resultObject;
139
-    }
140
-
141
-    /**
142
-     * Gets a user by their on-wiki username.
143
-     *
144
-     * @param string      $username
145
-     * @param PdoDatabase $database
146
-     *
147
-     * @return User|false
148
-     */
149
-    public static function getByOnWikiUsername($username, PdoDatabase $database)
150
-    {
151
-        $statement = $database->prepare("SELECT * FROM user WHERE onwikiname = :id LIMIT 1;");
152
-        $statement->bindValue(":id", $username);
153
-        $statement->execute();
154
-
155
-        $resultObject = $statement->fetchObject(get_called_class());
156
-
157
-        if ($resultObject != false) {
158
-            $resultObject->setDatabase($database);
159
-
160
-            return $resultObject;
161
-        }
162
-
163
-        return false;
164
-    }
165
-
166
-    #endregion
167
-
168
-    /**
169
-     * Saves the current object
170
-     *
171
-     * @throws Exception
172
-     */
173
-    public function save()
174
-    {
175
-        if ($this->isNew()) {
176
-            // insert
177
-            $statement = $this->dbObject->prepare(<<<SQL
24
+	const STATUS_ACTIVE = 'Active';
25
+	const STATUS_SUSPENDED = 'Suspended';
26
+	const STATUS_DECLINED = 'Declined';
27
+	const STATUS_NEW = 'New';
28
+	const CREATION_MANUAL = 0;
29
+	const CREATION_OAUTH = 1;
30
+	const CREATION_BOT = 2;
31
+	private $username;
32
+	private $email;
33
+	private $status = self::STATUS_NEW;
34
+	private $onwikiname;
35
+	private $welcome_sig = "";
36
+	private $lastactive = "0000-00-00 00:00:00";
37
+	private $forcelogout = 0;
38
+	private $forceidentified = null;
39
+	private $welcome_template = 0;
40
+	private $abortpref = 0;
41
+	private $confirmationdiff = 0;
42
+	private $emailsig = "";
43
+	private $creationmode = 0;
44
+	private $skin = "main";
45
+	/** @var User Cache variable of the current user - it's never going to change in the middle of a request. */
46
+	private static $currentUser;
47
+	#region Object load methods
48
+
49
+	/**
50
+	 * Gets the currently logged in user
51
+	 *
52
+	 * @param PdoDatabase $database
53
+	 *
54
+	 * @return User|CommunityUser
55
+	 */
56
+	public static function getCurrent(PdoDatabase $database)
57
+	{
58
+		if (self::$currentUser === null) {
59
+			$sessionId = WebRequest::getSessionUserId();
60
+
61
+			if ($sessionId !== null) {
62
+				/** @var User $user */
63
+				$user = self::getById($sessionId, $database);
64
+
65
+				if ($user === false) {
66
+					self::$currentUser = new CommunityUser();
67
+				}
68
+				else {
69
+					self::$currentUser = $user;
70
+				}
71
+			}
72
+			else {
73
+				$anonymousCoward = new CommunityUser();
74
+
75
+				self::$currentUser = $anonymousCoward;
76
+			}
77
+		}
78
+
79
+		return self::$currentUser;
80
+	}
81
+
82
+	/**
83
+	 * Gets a user by their user ID
84
+	 *
85
+	 * Pass -1 to get the community user.
86
+	 *
87
+	 * @param int|null    $id
88
+	 * @param PdoDatabase $database
89
+	 *
90
+	 * @return User|false
91
+	 */
92
+	public static function getById($id, PdoDatabase $database)
93
+	{
94
+		if ($id === null || $id == -1) {
95
+			return new CommunityUser();
96
+		}
97
+
98
+		/** @var User|false $user */
99
+		$user = parent::getById($id, $database);
100
+
101
+		return $user;
102
+	}
103
+
104
+	/**
105
+	 * @return CommunityUser
106
+	 */
107
+	public static function getCommunity()
108
+	{
109
+		return new CommunityUser();
110
+	}
111
+
112
+	/**
113
+	 * Gets a user by their username
114
+	 *
115
+	 * @param  string      $username
116
+	 * @param  PdoDatabase $database
117
+	 *
118
+	 * @return CommunityUser|User|false
119
+	 */
120
+	public static function getByUsername($username, PdoDatabase $database)
121
+	{
122
+		global $communityUsername;
123
+		if ($username == $communityUsername) {
124
+			return new CommunityUser();
125
+		}
126
+
127
+		$statement = $database->prepare("SELECT * FROM user WHERE username = :id LIMIT 1;");
128
+		$statement->bindValue(":id", $username);
129
+
130
+		$statement->execute();
131
+
132
+		$resultObject = $statement->fetchObject(get_called_class());
133
+
134
+		if ($resultObject != false) {
135
+			$resultObject->setDatabase($database);
136
+		}
137
+
138
+		return $resultObject;
139
+	}
140
+
141
+	/**
142
+	 * Gets a user by their on-wiki username.
143
+	 *
144
+	 * @param string      $username
145
+	 * @param PdoDatabase $database
146
+	 *
147
+	 * @return User|false
148
+	 */
149
+	public static function getByOnWikiUsername($username, PdoDatabase $database)
150
+	{
151
+		$statement = $database->prepare("SELECT * FROM user WHERE onwikiname = :id LIMIT 1;");
152
+		$statement->bindValue(":id", $username);
153
+		$statement->execute();
154
+
155
+		$resultObject = $statement->fetchObject(get_called_class());
156
+
157
+		if ($resultObject != false) {
158
+			$resultObject->setDatabase($database);
159
+
160
+			return $resultObject;
161
+		}
162
+
163
+		return false;
164
+	}
165
+
166
+	#endregion
167
+
168
+	/**
169
+	 * Saves the current object
170
+	 *
171
+	 * @throws Exception
172
+	 */
173
+	public function save()
174
+	{
175
+		if ($this->isNew()) {
176
+			// insert
177
+			$statement = $this->dbObject->prepare(<<<SQL
178 178
 				INSERT INTO `user` ( 
179 179
 					username, email, status, onwikiname, welcome_sig, 
180 180
 					lastactive, forcelogout, forceidentified,
@@ -185,32 +185,32 @@  discard block
 block discarded – undo
185 185
 					:welcome_template, :abortpref, :confirmationdiff, :emailsig, :creationmode, :skin
186 186
 				);
187 187
 SQL
188
-            );
189
-            $statement->bindValue(":username", $this->username);
190
-            $statement->bindValue(":email", $this->email);
191
-            $statement->bindValue(":status", $this->status);
192
-            $statement->bindValue(":onwikiname", $this->onwikiname);
193
-            $statement->bindValue(":welcome_sig", $this->welcome_sig);
194
-            $statement->bindValue(":lastactive", $this->lastactive);
195
-            $statement->bindValue(":forcelogout", $this->forcelogout);
196
-            $statement->bindValue(":forceidentified", $this->forceidentified);
197
-            $statement->bindValue(":welcome_template", $this->welcome_template);
198
-            $statement->bindValue(":abortpref", $this->abortpref);
199
-            $statement->bindValue(":confirmationdiff", $this->confirmationdiff);
200
-            $statement->bindValue(":emailsig", $this->emailsig);
201
-            $statement->bindValue(":creationmode", $this->creationmode);
202
-            $statement->bindValue(":skin", $this->skin);
203
-
204
-            if ($statement->execute()) {
205
-                $this->id = (int)$this->dbObject->lastInsertId();
206
-            }
207
-            else {
208
-                throw new Exception($statement->errorInfo());
209
-            }
210
-        }
211
-        else {
212
-            // update
213
-            $statement = $this->dbObject->prepare(<<<SQL
188
+			);
189
+			$statement->bindValue(":username", $this->username);
190
+			$statement->bindValue(":email", $this->email);
191
+			$statement->bindValue(":status", $this->status);
192
+			$statement->bindValue(":onwikiname", $this->onwikiname);
193
+			$statement->bindValue(":welcome_sig", $this->welcome_sig);
194
+			$statement->bindValue(":lastactive", $this->lastactive);
195
+			$statement->bindValue(":forcelogout", $this->forcelogout);
196
+			$statement->bindValue(":forceidentified", $this->forceidentified);
197
+			$statement->bindValue(":welcome_template", $this->welcome_template);
198
+			$statement->bindValue(":abortpref", $this->abortpref);
199
+			$statement->bindValue(":confirmationdiff", $this->confirmationdiff);
200
+			$statement->bindValue(":emailsig", $this->emailsig);
201
+			$statement->bindValue(":creationmode", $this->creationmode);
202
+			$statement->bindValue(":skin", $this->skin);
203
+
204
+			if ($statement->execute()) {
205
+				$this->id = (int)$this->dbObject->lastInsertId();
206
+			}
207
+			else {
208
+				throw new Exception($statement->errorInfo());
209
+			}
210
+		}
211
+		else {
212
+			// update
213
+			$statement = $this->dbObject->prepare(<<<SQL
214 214
 				UPDATE `user` SET 
215 215
 					username = :username, email = :email, 
216 216
 					status = :status,
@@ -223,387 +223,387 @@  discard block
 block discarded – undo
223 223
                     updateversion = updateversion + 1
224 224
 				WHERE id = :id AND updateversion = :updateversion;
225 225
 SQL
226
-            );
227
-            $statement->bindValue(":forceidentified", $this->forceidentified);
228
-
229
-            $statement->bindValue(':id', $this->id);
230
-            $statement->bindValue(':updateversion', $this->updateversion);
231
-
232
-            $statement->bindValue(':username', $this->username);
233
-            $statement->bindValue(':email', $this->email);
234
-            $statement->bindValue(':status', $this->status);
235
-            $statement->bindValue(':onwikiname', $this->onwikiname);
236
-            $statement->bindValue(':welcome_sig', $this->welcome_sig);
237
-            $statement->bindValue(':lastactive', $this->lastactive);
238
-            $statement->bindValue(':forcelogout', $this->forcelogout);
239
-            $statement->bindValue(':forceidentified', $this->forceidentified);
240
-            $statement->bindValue(':welcome_template', $this->welcome_template);
241
-            $statement->bindValue(':abortpref', $this->abortpref);
242
-            $statement->bindValue(':confirmationdiff', $this->confirmationdiff);
243
-            $statement->bindValue(':emailsig', $this->emailsig);
244
-            $statement->bindValue(':creationmode', $this->creationmode);
245
-            $statement->bindValue(':skin', $this->skin);
246
-
247
-            if (!$statement->execute()) {
248
-                throw new Exception($statement->errorInfo());
249
-            }
250
-
251
-            if ($statement->rowCount() !== 1) {
252
-                throw new OptimisticLockFailedException();
253
-            }
254
-
255
-            $this->updateversion++;
256
-        }
257
-    }
258
-
259
-    #region properties
260
-
261
-    /**
262
-     * Gets the tool username
263
-     * @return string
264
-     */
265
-    public function getUsername()
266
-    {
267
-        return $this->username;
268
-    }
269
-
270
-    /**
271
-     * Sets the tool username
272
-     *
273
-     * @param string $username
274
-     */
275
-    public function setUsername($username)
276
-    {
277
-        $this->username = $username;
278
-
279
-        // If this isn't a brand new user, then it's a rename, force the logout
280
-        if (!$this->isNew()) {
281
-            $this->forcelogout = 1;
282
-        }
283
-    }
284
-
285
-    /**
286
-     * Gets the user's email address
287
-     * @return string
288
-     */
289
-    public function getEmail()
290
-    {
291
-        return $this->email;
292
-    }
293
-
294
-    /**
295
-     * Sets the user's email address
296
-     *
297
-     * @param string $email
298
-     */
299
-    public function setEmail($email)
300
-    {
301
-        $this->email = $email;
302
-    }
303
-
304
-    /**
305
-     * Gets the status (User, Admin, Suspended, etc - excludes checkuser) of the user.
306
-     * @return string
307
-     */
308
-    public function getStatus()
309
-    {
310
-        return $this->status;
311
-    }
312
-
313
-    /**
314
-     * @param string $status
315
-     */
316
-    public function setStatus($status)
317
-    {
318
-        $this->status = $status;
319
-    }
320
-
321
-    /**
322
-     * Gets the user's on-wiki name
323
-     * @return string
324
-     */
325
-    public function getOnWikiName()
326
-    {
327
-        return $this->onwikiname;
328
-    }
329
-
330
-    /**
331
-     * Sets the user's on-wiki name
332
-     *
333
-     * This can have interesting side-effects with OAuth.
334
-     *
335
-     * @param string $onWikiName
336
-     */
337
-    public function setOnWikiName($onWikiName)
338
-    {
339
-        $this->onwikiname = $onWikiName;
340
-    }
341
-
342
-    /**
343
-     * Gets the welcome signature
344
-     * @return string
345
-     */
346
-    public function getWelcomeSig()
347
-    {
348
-        return $this->welcome_sig;
349
-    }
350
-
351
-    /**
352
-     * Sets the welcome signature
353
-     *
354
-     * @param string $welcomeSig
355
-     */
356
-    public function setWelcomeSig($welcomeSig)
357
-    {
358
-        $this->welcome_sig = $welcomeSig;
359
-    }
360
-
361
-    /**
362
-     * Gets the last activity date for the user
363
-     *
364
-     * @return string
365
-     * @todo This should probably return an instance of DateTime
366
-     */
367
-    public function getLastActive()
368
-    {
369
-        return $this->lastactive;
370
-    }
371
-
372
-    /**
373
-     * Gets the user's forced logout status
374
-     *
375
-     * @return bool
376
-     */
377
-    public function getForceLogout()
378
-    {
379
-        return $this->forcelogout == 1;
380
-    }
381
-
382
-    /**
383
-     * Sets the user's forced logout status
384
-     *
385
-     * @param bool $forceLogout
386
-     */
387
-    public function setForceLogout($forceLogout)
388
-    {
389
-        $this->forcelogout = $forceLogout ? 1 : 0;
390
-    }
391
-
392
-    /**
393
-     * Returns the ID of the welcome template used.
394
-     * @return int
395
-     */
396
-    public function getWelcomeTemplate()
397
-    {
398
-        return $this->welcome_template;
399
-    }
400
-
401
-    /**
402
-     * Sets the ID of the welcome template used.
403
-     *
404
-     * @param int $welcomeTemplate
405
-     */
406
-    public function setWelcomeTemplate($welcomeTemplate)
407
-    {
408
-        $this->welcome_template = $welcomeTemplate;
409
-    }
410
-
411
-    /**
412
-     * Gets the user's abort preference
413
-     * @todo this is badly named too! Also a bool that's actually an int.
414
-     * @return int
415
-     */
416
-    public function getAbortPref()
417
-    {
418
-        return $this->abortpref;
419
-    }
420
-
421
-    /**
422
-     * Sets the user's abort preference
423
-     * @todo rename, retype, and re-comment.
424
-     *
425
-     * @param int $abortPreference
426
-     */
427
-    public function setAbortPref($abortPreference)
428
-    {
429
-        $this->abortpref = $abortPreference;
430
-    }
431
-
432
-    /**
433
-     * Gets the user's confirmation diff. Unused if OAuth is in use.
434
-     * @return int the diff ID
435
-     */
436
-    public function getConfirmationDiff()
437
-    {
438
-        return $this->confirmationdiff;
439
-    }
440
-
441
-    /**
442
-     * Sets the user's confirmation diff.
443
-     *
444
-     * @param int $confirmationDiff
445
-     */
446
-    public function setConfirmationDiff($confirmationDiff)
447
-    {
448
-        $this->confirmationdiff = $confirmationDiff;
449
-    }
450
-
451
-    /**
452
-     * Gets the users' email signature used on outbound mail.
453
-     * @todo rename me!
454
-     * @return string
455
-     */
456
-    public function getEmailSig()
457
-    {
458
-        return $this->emailsig;
459
-    }
460
-
461
-    /**
462
-     * Sets the user's email signature for outbound mail.
463
-     *
464
-     * @param string $emailSignature
465
-     */
466
-    public function setEmailSig($emailSignature)
467
-    {
468
-        $this->emailsig = $emailSignature;
469
-    }
470
-
471
-    /**
472
-     * @return int
473
-     */
474
-    public function getCreationMode()
475
-    {
476
-        return $this->creationmode;
477
-    }
478
-
479
-    /**
480
-     * @param $creationMode int
481
-     */
482
-    public function setCreationMode($creationMode)
483
-    {
484
-        $this->creationmode = $creationMode;
485
-    }
486
-
487
-    /**
488
-     * @return boolean
489
-     */
490
-    public function getUseAlternateSkin()
491
-    {
492
-        return $this->skin === 'alt';
493
-    }
494
-
495
-    /**
496
-     * @return string
497
-     */
498
-    public function getSkin()
499
-    {
500
-        return $this->skin;
501
-    }
502
-
503
-    /**
504
-     * @param $skin string
505
-     */
506
-    public function setSkin($skin)
507
-    {
508
-        $this->skin = $skin;
509
-    }
510
-
511
-    #endregion
512
-
513
-    #region user access checks
514
-
515
-    public function isActive()
516
-    {
517
-        return $this->status == self::STATUS_ACTIVE;
518
-    }
519
-
520
-    /**
521
-     * Tests if the user is identified
522
-     *
523
-     * @param IdentificationVerifier $iv
524
-     *
525
-     * @return bool
526
-     * @todo     Figure out what on earth is going on with PDO's typecasting here.  Apparently, it returns string("0") for
527
-     *       the force-unidentified case, and int(1) for the identified case?!  This is quite ugly, but probably needed
528
-     *       to play it safe for now.
529
-     * @category Security-Critical
530
-     */
531
-    public function isIdentified(IdentificationVerifier $iv)
532
-    {
533
-        if ($this->forceidentified === 0 || $this->forceidentified === "0") {
534
-            // User forced to unidentified in the database.
535
-            return false;
536
-        }
537
-        elseif ($this->forceidentified === 1 || $this->forceidentified === "1") {
538
-            // User forced to identified in the database.
539
-            return true;
540
-        }
541
-        else {
542
-            // User not forced to any particular identified status; consult IdentificationVerifier
543
-            return $iv->isUserIdentified($this->getOnWikiName());
544
-        }
545
-    }
546
-
547
-    /**
548
-     * DO NOT USE FOR TESTING IDENTIFICATION STATUS.
549
-     *
550
-     * @return bool|null
551
-     */
552
-    public function getForceIdentified() {
553
-        return $this->forceidentified;
554
-    }
555
-
556
-    /**
557
-     * Tests if the user is suspended
558
-     * @return bool
559
-     * @category Security-Critical
560
-     */
561
-    public function isSuspended()
562
-    {
563
-        return $this->status == self::STATUS_SUSPENDED;
564
-    }
565
-
566
-    /**
567
-     * Tests if the user is new
568
-     * @return bool
569
-     * @category Security-Critical
570
-     */
571
-    public function isNewUser()
572
-    {
573
-        return $this->status == self::STATUS_NEW;
574
-    }
575
-
576
-    /**
577
-     * Tests if the user has been declined access to the tool
578
-     * @return bool
579
-     * @category Security-Critical
580
-     */
581
-    public function isDeclined()
582
-    {
583
-        return $this->status == self::STATUS_DECLINED;
584
-    }
585
-
586
-    /**
587
-     * Tests if the user is the community user
588
-     *
589
-     * @todo     decide if this means logged out. I think it usually does.
590
-     * @return bool
591
-     * @category Security-Critical
592
-     */
593
-    public function isCommunityUser()
594
-    {
595
-        return false;
596
-    }
597
-
598
-    #endregion 
599
-
600
-    /**
601
-     * Gets the approval date of the user
602
-     * @return DateTime|false
603
-     */
604
-    public function getApprovalDate()
605
-    {
606
-        $query = $this->dbObject->prepare(<<<SQL
226
+			);
227
+			$statement->bindValue(":forceidentified", $this->forceidentified);
228
+
229
+			$statement->bindValue(':id', $this->id);
230
+			$statement->bindValue(':updateversion', $this->updateversion);
231
+
232
+			$statement->bindValue(':username', $this->username);
233
+			$statement->bindValue(':email', $this->email);
234
+			$statement->bindValue(':status', $this->status);
235
+			$statement->bindValue(':onwikiname', $this->onwikiname);
236
+			$statement->bindValue(':welcome_sig', $this->welcome_sig);
237
+			$statement->bindValue(':lastactive', $this->lastactive);
238
+			$statement->bindValue(':forcelogout', $this->forcelogout);
239
+			$statement->bindValue(':forceidentified', $this->forceidentified);
240
+			$statement->bindValue(':welcome_template', $this->welcome_template);
241
+			$statement->bindValue(':abortpref', $this->abortpref);
242
+			$statement->bindValue(':confirmationdiff', $this->confirmationdiff);
243
+			$statement->bindValue(':emailsig', $this->emailsig);
244
+			$statement->bindValue(':creationmode', $this->creationmode);
245
+			$statement->bindValue(':skin', $this->skin);
246
+
247
+			if (!$statement->execute()) {
248
+				throw new Exception($statement->errorInfo());
249
+			}
250
+
251
+			if ($statement->rowCount() !== 1) {
252
+				throw new OptimisticLockFailedException();
253
+			}
254
+
255
+			$this->updateversion++;
256
+		}
257
+	}
258
+
259
+	#region properties
260
+
261
+	/**
262
+	 * Gets the tool username
263
+	 * @return string
264
+	 */
265
+	public function getUsername()
266
+	{
267
+		return $this->username;
268
+	}
269
+
270
+	/**
271
+	 * Sets the tool username
272
+	 *
273
+	 * @param string $username
274
+	 */
275
+	public function setUsername($username)
276
+	{
277
+		$this->username = $username;
278
+
279
+		// If this isn't a brand new user, then it's a rename, force the logout
280
+		if (!$this->isNew()) {
281
+			$this->forcelogout = 1;
282
+		}
283
+	}
284
+
285
+	/**
286
+	 * Gets the user's email address
287
+	 * @return string
288
+	 */
289
+	public function getEmail()
290
+	{
291
+		return $this->email;
292
+	}
293
+
294
+	/**
295
+	 * Sets the user's email address
296
+	 *
297
+	 * @param string $email
298
+	 */
299
+	public function setEmail($email)
300
+	{
301
+		$this->email = $email;
302
+	}
303
+
304
+	/**
305
+	 * Gets the status (User, Admin, Suspended, etc - excludes checkuser) of the user.
306
+	 * @return string
307
+	 */
308
+	public function getStatus()
309
+	{
310
+		return $this->status;
311
+	}
312
+
313
+	/**
314
+	 * @param string $status
315
+	 */
316
+	public function setStatus($status)
317
+	{
318
+		$this->status = $status;
319
+	}
320
+
321
+	/**
322
+	 * Gets the user's on-wiki name
323
+	 * @return string
324
+	 */
325
+	public function getOnWikiName()
326
+	{
327
+		return $this->onwikiname;
328
+	}
329
+
330
+	/**
331
+	 * Sets the user's on-wiki name
332
+	 *
333
+	 * This can have interesting side-effects with OAuth.
334
+	 *
335
+	 * @param string $onWikiName
336
+	 */
337
+	public function setOnWikiName($onWikiName)
338
+	{
339
+		$this->onwikiname = $onWikiName;
340
+	}
341
+
342
+	/**
343
+	 * Gets the welcome signature
344
+	 * @return string
345
+	 */
346
+	public function getWelcomeSig()
347
+	{
348
+		return $this->welcome_sig;
349
+	}
350
+
351
+	/**
352
+	 * Sets the welcome signature
353
+	 *
354
+	 * @param string $welcomeSig
355
+	 */
356
+	public function setWelcomeSig($welcomeSig)
357
+	{
358
+		$this->welcome_sig = $welcomeSig;
359
+	}
360
+
361
+	/**
362
+	 * Gets the last activity date for the user
363
+	 *
364
+	 * @return string
365
+	 * @todo This should probably return an instance of DateTime
366
+	 */
367
+	public function getLastActive()
368
+	{
369
+		return $this->lastactive;
370
+	}
371
+
372
+	/**
373
+	 * Gets the user's forced logout status
374
+	 *
375
+	 * @return bool
376
+	 */
377
+	public function getForceLogout()
378
+	{
379
+		return $this->forcelogout == 1;
380
+	}
381
+
382
+	/**
383
+	 * Sets the user's forced logout status
384
+	 *
385
+	 * @param bool $forceLogout
386
+	 */
387
+	public function setForceLogout($forceLogout)
388
+	{
389
+		$this->forcelogout = $forceLogout ? 1 : 0;
390
+	}
391
+
392
+	/**
393
+	 * Returns the ID of the welcome template used.
394
+	 * @return int
395
+	 */
396
+	public function getWelcomeTemplate()
397
+	{
398
+		return $this->welcome_template;
399
+	}
400
+
401
+	/**
402
+	 * Sets the ID of the welcome template used.
403
+	 *
404
+	 * @param int $welcomeTemplate
405
+	 */
406
+	public function setWelcomeTemplate($welcomeTemplate)
407
+	{
408
+		$this->welcome_template = $welcomeTemplate;
409
+	}
410
+
411
+	/**
412
+	 * Gets the user's abort preference
413
+	 * @todo this is badly named too! Also a bool that's actually an int.
414
+	 * @return int
415
+	 */
416
+	public function getAbortPref()
417
+	{
418
+		return $this->abortpref;
419
+	}
420
+
421
+	/**
422
+	 * Sets the user's abort preference
423
+	 * @todo rename, retype, and re-comment.
424
+	 *
425
+	 * @param int $abortPreference
426
+	 */
427
+	public function setAbortPref($abortPreference)
428
+	{
429
+		$this->abortpref = $abortPreference;
430
+	}
431
+
432
+	/**
433
+	 * Gets the user's confirmation diff. Unused if OAuth is in use.
434
+	 * @return int the diff ID
435
+	 */
436
+	public function getConfirmationDiff()
437
+	{
438
+		return $this->confirmationdiff;
439
+	}
440
+
441
+	/**
442
+	 * Sets the user's confirmation diff.
443
+	 *
444
+	 * @param int $confirmationDiff
445
+	 */
446
+	public function setConfirmationDiff($confirmationDiff)
447
+	{
448
+		$this->confirmationdiff = $confirmationDiff;
449
+	}
450
+
451
+	/**
452
+	 * Gets the users' email signature used on outbound mail.
453
+	 * @todo rename me!
454
+	 * @return string
455
+	 */
456
+	public function getEmailSig()
457
+	{
458
+		return $this->emailsig;
459
+	}
460
+
461
+	/**
462
+	 * Sets the user's email signature for outbound mail.
463
+	 *
464
+	 * @param string $emailSignature
465
+	 */
466
+	public function setEmailSig($emailSignature)
467
+	{
468
+		$this->emailsig = $emailSignature;
469
+	}
470
+
471
+	/**
472
+	 * @return int
473
+	 */
474
+	public function getCreationMode()
475
+	{
476
+		return $this->creationmode;
477
+	}
478
+
479
+	/**
480
+	 * @param $creationMode int
481
+	 */
482
+	public function setCreationMode($creationMode)
483
+	{
484
+		$this->creationmode = $creationMode;
485
+	}
486
+
487
+	/**
488
+	 * @return boolean
489
+	 */
490
+	public function getUseAlternateSkin()
491
+	{
492
+		return $this->skin === 'alt';
493
+	}
494
+
495
+	/**
496
+	 * @return string
497
+	 */
498
+	public function getSkin()
499
+	{
500
+		return $this->skin;
501
+	}
502
+
503
+	/**
504
+	 * @param $skin string
505
+	 */
506
+	public function setSkin($skin)
507
+	{
508
+		$this->skin = $skin;
509
+	}
510
+
511
+	#endregion
512
+
513
+	#region user access checks
514
+
515
+	public function isActive()
516
+	{
517
+		return $this->status == self::STATUS_ACTIVE;
518
+	}
519
+
520
+	/**
521
+	 * Tests if the user is identified
522
+	 *
523
+	 * @param IdentificationVerifier $iv
524
+	 *
525
+	 * @return bool
526
+	 * @todo     Figure out what on earth is going on with PDO's typecasting here.  Apparently, it returns string("0") for
527
+	 *       the force-unidentified case, and int(1) for the identified case?!  This is quite ugly, but probably needed
528
+	 *       to play it safe for now.
529
+	 * @category Security-Critical
530
+	 */
531
+	public function isIdentified(IdentificationVerifier $iv)
532
+	{
533
+		if ($this->forceidentified === 0 || $this->forceidentified === "0") {
534
+			// User forced to unidentified in the database.
535
+			return false;
536
+		}
537
+		elseif ($this->forceidentified === 1 || $this->forceidentified === "1") {
538
+			// User forced to identified in the database.
539
+			return true;
540
+		}
541
+		else {
542
+			// User not forced to any particular identified status; consult IdentificationVerifier
543
+			return $iv->isUserIdentified($this->getOnWikiName());
544
+		}
545
+	}
546
+
547
+	/**
548
+	 * DO NOT USE FOR TESTING IDENTIFICATION STATUS.
549
+	 *
550
+	 * @return bool|null
551
+	 */
552
+	public function getForceIdentified() {
553
+		return $this->forceidentified;
554
+	}
555
+
556
+	/**
557
+	 * Tests if the user is suspended
558
+	 * @return bool
559
+	 * @category Security-Critical
560
+	 */
561
+	public function isSuspended()
562
+	{
563
+		return $this->status == self::STATUS_SUSPENDED;
564
+	}
565
+
566
+	/**
567
+	 * Tests if the user is new
568
+	 * @return bool
569
+	 * @category Security-Critical
570
+	 */
571
+	public function isNewUser()
572
+	{
573
+		return $this->status == self::STATUS_NEW;
574
+	}
575
+
576
+	/**
577
+	 * Tests if the user has been declined access to the tool
578
+	 * @return bool
579
+	 * @category Security-Critical
580
+	 */
581
+	public function isDeclined()
582
+	{
583
+		return $this->status == self::STATUS_DECLINED;
584
+	}
585
+
586
+	/**
587
+	 * Tests if the user is the community user
588
+	 *
589
+	 * @todo     decide if this means logged out. I think it usually does.
590
+	 * @return bool
591
+	 * @category Security-Critical
592
+	 */
593
+	public function isCommunityUser()
594
+	{
595
+		return false;
596
+	}
597
+
598
+	#endregion 
599
+
600
+	/**
601
+	 * Gets the approval date of the user
602
+	 * @return DateTime|false
603
+	 */
604
+	public function getApprovalDate()
605
+	{
606
+		$query = $this->dbObject->prepare(<<<SQL
607 607
 			SELECT timestamp 
608 608
 			FROM log 
609 609
 			WHERE objectid = :userid
@@ -612,12 +612,12 @@  discard block
 block discarded – undo
612 612
 			ORDER BY id DESC 
613 613
 			LIMIT 1;
614 614
 SQL
615
-        );
616
-        $query->execute(array(":userid" => $this->id));
615
+		);
616
+		$query->execute(array(":userid" => $this->id));
617 617
 
618
-        $data = DateTime::createFromFormat("Y-m-d H:i:s", $query->fetchColumn());
619
-        $query->closeCursor();
618
+		$data = DateTime::createFromFormat("Y-m-d H:i:s", $query->fetchColumn());
619
+		$query->closeCursor();
620 620
 
621
-        return $data;
622
-    }
621
+		return $data;
622
+	}
623 623
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -549,7 +549,8 @@
 block discarded – undo
549 549
      *
550 550
      * @return bool|null
551 551
      */
552
-    public function getForceIdentified() {
552
+    public function getForceIdentified()
553
+    {
553 554
         return $this->forceidentified;
554 555
     }
555 556
 
Please login to merge, or discard this patch.
includes/Pages/Statistics/StatsUsers.php 3 patches
Indentation   +88 added lines, -88 removed lines patch added patch discarded remove patch
@@ -23,13 +23,13 @@  discard block
 block discarded – undo
23 23
 
24 24
 class StatsUsers extends InternalPageBase
25 25
 {
26
-    public function main()
27
-    {
28
-        $this->setHtmlTitle('Users :: Statistics');
26
+	public function main()
27
+	{
28
+		$this->setHtmlTitle('Users :: Statistics');
29 29
 
30
-        $database = $this->getDatabase();
30
+		$database = $this->getDatabase();
31 31
 
32
-        $query = <<<SQL
32
+		$query = <<<SQL
33 33
 SELECT
34 34
     u.id
35 35
     , u.username
@@ -45,34 +45,34 @@  discard block
 block discarded – undo
45 45
 WHERE u.status = 'Active'
46 46
 SQL;
47 47
 
48
-        $users = $database->query($query)->fetchAll(PDO::FETCH_ASSOC);
49
-        $this->assign('users', $users);
48
+		$users = $database->query($query)->fetchAll(PDO::FETCH_ASSOC);
49
+		$this->assign('users', $users);
50 50
 
51
-        $this->assign('statsPageTitle', 'Account Creation Tool users');
52
-        $this->setTemplate("statistics/users.tpl");
53
-    }
51
+		$this->assign('statsPageTitle', 'Account Creation Tool users');
52
+		$this->setTemplate("statistics/users.tpl");
53
+	}
54 54
 
55
-    /**
56
-     * Entry point for the detail action.
57
-     *
58
-     * @throws ApplicationLogicException
59
-     */
60
-    protected function detail()
61
-    {
62
-        $userId = WebRequest::getInt('user');
63
-        if ($userId === null) {
64
-            throw new ApplicationLogicException("User not found");
65
-        }
55
+	/**
56
+	 * Entry point for the detail action.
57
+	 *
58
+	 * @throws ApplicationLogicException
59
+	 */
60
+	protected function detail()
61
+	{
62
+		$userId = WebRequest::getInt('user');
63
+		if ($userId === null) {
64
+			throw new ApplicationLogicException("User not found");
65
+		}
66 66
 
67
-        $database = $this->getDatabase();
67
+		$database = $this->getDatabase();
68 68
 
69
-        $user = User::getById($userId, $database);
70
-        if ($user == false) {
71
-            throw new ApplicationLogicException('User not found');
72
-        }
69
+		$user = User::getById($userId, $database);
70
+		if ($user == false) {
71
+			throw new ApplicationLogicException('User not found');
72
+		}
73 73
 
74 74
 
75
-        $activitySummary = $database->prepare(<<<SQL
75
+		$activitySummary = $database->prepare(<<<SQL
76 76
 SELECT COALESCE(closes.mail_desc, log.action) AS action, COUNT(*) AS count
77 77
 FROM log
78 78
 INNER JOIN user ON log.user = user.id
@@ -80,14 +80,14 @@  discard block
 block discarded – undo
80 80
 WHERE user.username = :username
81 81
 GROUP BY action;
82 82
 SQL
83
-        );
84
-        $activitySummary->execute(array(":username" => $user->getUsername()));
85
-        $activitySummaryData = $activitySummary->fetchAll(PDO::FETCH_ASSOC);
83
+		);
84
+		$activitySummary->execute(array(":username" => $user->getUsername()));
85
+		$activitySummaryData = $activitySummary->fetchAll(PDO::FETCH_ASSOC);
86 86
 
87
-        $this->assign("user", $user);
88
-        $this->assign("activity", $activitySummaryData);
87
+		$this->assign("user", $user);
88
+		$this->assign("activity", $activitySummaryData);
89 89
 
90
-        $usersCreatedQuery = $database->prepare(<<<SQL
90
+		$usersCreatedQuery = $database->prepare(<<<SQL
91 91
 SELECT log.timestamp time, request.name name, request.id id
92 92
 FROM log
93 93
 INNER JOIN request ON (request.id = log.objectid AND log.objecttype = 'Request')
@@ -98,12 +98,12 @@  discard block
 block discarded – undo
98 98
     AND (emailtemplate.oncreated = '1' OR log.action = 'Closed custom-y')
99 99
 ORDER BY log.timestamp;
100 100
 SQL
101
-        );
102
-        $usersCreatedQuery->execute(array(":username" => $user->getUsername()));
103
-        $usersCreated = $usersCreatedQuery->fetchAll(PDO::FETCH_ASSOC);
104
-        $this->assign("created", $usersCreated);
101
+		);
102
+		$usersCreatedQuery->execute(array(":username" => $user->getUsername()));
103
+		$usersCreated = $usersCreatedQuery->fetchAll(PDO::FETCH_ASSOC);
104
+		$this->assign("created", $usersCreated);
105 105
 
106
-        $usersNotCreatedQuery = $database->prepare(<<<SQL
106
+		$usersNotCreatedQuery = $database->prepare(<<<SQL
107 107
 SELECT log.timestamp time, request.name name, request.id id
108 108
 FROM log
109 109
 JOIN request ON request.id = log.objectid AND log.objecttype = 'Request'
@@ -114,54 +114,54 @@  discard block
 block discarded – undo
114 114
     AND (emailtemplate.oncreated = '0' OR log.action = 'Closed custom-n' OR log.action = 'Closed 0')
115 115
 ORDER BY log.timestamp;
116 116
 SQL
117
-        );
118
-        $usersNotCreatedQuery->execute(array(":username" => $user->getUsername()));
119
-        $usersNotCreated = $usersNotCreatedQuery->fetchAll(PDO::FETCH_ASSOC);
120
-        $this->assign("notcreated", $usersNotCreated);
121
-
122
-        /** @var Log[] $logs */
123
-        $logs = LogSearchHelper::get($database)
124
-            ->byObjectType('User')
125
-            ->byObjectId($user->getId())
126
-            ->getRecordCount($logCount)
127
-            ->fetch();
128
-
129
-        if ($logCount === 0) {
130
-            $this->assign('accountlog', array());
131
-        }
132
-        else {
133
-            list($users, $logData) = LogHelper::prepareLogsForTemplate($logs, $database, $this->getSiteConfiguration());
134
-
135
-            $this->assign("accountlog", $logData);
136
-            $this->assign("users", $users);
137
-        }
138
-
139
-        $currentUser = User::getCurrent($database);
140
-        $this->assign('canApprove', $this->barrierTest('approve', $currentUser, PageUserManagement::class));
141
-        $this->assign('canDecline', $this->barrierTest('decline', $currentUser, PageUserManagement::class));
142
-        $this->assign('canRename', $this->barrierTest('rename', $currentUser, PageUserManagement::class));
143
-        $this->assign('canEditUser', $this->barrierTest('editUser', $currentUser, PageUserManagement::class));
144
-        $this->assign('canSuspend', $this->barrierTest('suspend', $currentUser, PageUserManagement::class));
145
-        $this->assign('canEditRoles', $this->barrierTest('editRoles', $currentUser, PageUserManagement::class));
146
-
147
-        $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
148
-        $this->assign('oauth', $oauth);
149
-
150
-        if($user->getForceIdentified() === null) {
151
-            $idVerifier = new IdentificationVerifier($this->getHttpHelper(), $this->getSiteConfiguration(), $this->getDatabase());
152
-            $this->assign('identificationStatus', $idVerifier->isUserIdentified($user->getOnWikiName()) ? 'detected' : 'missing');
153
-        } else {
154
-            $this->assign('identificationStatus', $user->getForceIdentified() == 1 ? 'forced-on' : 'forced-off');
155
-        }
156
-
157
-        if ($oauth->isFullyLinked()) {
158
-            $this->assign('identity', $oauth->getIdentity(true));
159
-            $this->assign('identityExpired', $oauth->identityExpired());
160
-        }
161
-
162
-        $this->assign('statsPageTitle', 'Account Creation Tool users');
163
-
164
-        $this->setHtmlTitle('{$user->getUsername()|escape} :: Users :: Statistics');
165
-        $this->setTemplate("statistics/userdetail.tpl");
166
-    }
117
+		);
118
+		$usersNotCreatedQuery->execute(array(":username" => $user->getUsername()));
119
+		$usersNotCreated = $usersNotCreatedQuery->fetchAll(PDO::FETCH_ASSOC);
120
+		$this->assign("notcreated", $usersNotCreated);
121
+
122
+		/** @var Log[] $logs */
123
+		$logs = LogSearchHelper::get($database)
124
+			->byObjectType('User')
125
+			->byObjectId($user->getId())
126
+			->getRecordCount($logCount)
127
+			->fetch();
128
+
129
+		if ($logCount === 0) {
130
+			$this->assign('accountlog', array());
131
+		}
132
+		else {
133
+			list($users, $logData) = LogHelper::prepareLogsForTemplate($logs, $database, $this->getSiteConfiguration());
134
+
135
+			$this->assign("accountlog", $logData);
136
+			$this->assign("users", $users);
137
+		}
138
+
139
+		$currentUser = User::getCurrent($database);
140
+		$this->assign('canApprove', $this->barrierTest('approve', $currentUser, PageUserManagement::class));
141
+		$this->assign('canDecline', $this->barrierTest('decline', $currentUser, PageUserManagement::class));
142
+		$this->assign('canRename', $this->barrierTest('rename', $currentUser, PageUserManagement::class));
143
+		$this->assign('canEditUser', $this->barrierTest('editUser', $currentUser, PageUserManagement::class));
144
+		$this->assign('canSuspend', $this->barrierTest('suspend', $currentUser, PageUserManagement::class));
145
+		$this->assign('canEditRoles', $this->barrierTest('editRoles', $currentUser, PageUserManagement::class));
146
+
147
+		$oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
148
+		$this->assign('oauth', $oauth);
149
+
150
+		if($user->getForceIdentified() === null) {
151
+			$idVerifier = new IdentificationVerifier($this->getHttpHelper(), $this->getSiteConfiguration(), $this->getDatabase());
152
+			$this->assign('identificationStatus', $idVerifier->isUserIdentified($user->getOnWikiName()) ? 'detected' : 'missing');
153
+		} else {
154
+			$this->assign('identificationStatus', $user->getForceIdentified() == 1 ? 'forced-on' : 'forced-off');
155
+		}
156
+
157
+		if ($oauth->isFullyLinked()) {
158
+			$this->assign('identity', $oauth->getIdentity(true));
159
+			$this->assign('identityExpired', $oauth->identityExpired());
160
+		}
161
+
162
+		$this->assign('statsPageTitle', 'Account Creation Tool users');
163
+
164
+		$this->setHtmlTitle('{$user->getUsername()|escape} :: Users :: Statistics');
165
+		$this->setTemplate("statistics/userdetail.tpl");
166
+	}
167 167
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -147,7 +147,7 @@
 block discarded – undo
147 147
         $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
148 148
         $this->assign('oauth', $oauth);
149 149
 
150
-        if($user->getForceIdentified() === null) {
150
+        if ($user->getForceIdentified() === null) {
151 151
             $idVerifier = new IdentificationVerifier($this->getHttpHelper(), $this->getSiteConfiguration(), $this->getDatabase());
152 152
             $this->assign('identificationStatus', $idVerifier->isUserIdentified($user->getOnWikiName()) ? 'detected' : 'missing');
153 153
         } else {
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -150,7 +150,8 @@
 block discarded – undo
150 150
         if($user->getForceIdentified() === null) {
151 151
             $idVerifier = new IdentificationVerifier($this->getHttpHelper(), $this->getSiteConfiguration(), $this->getDatabase());
152 152
             $this->assign('identificationStatus', $idVerifier->isUserIdentified($user->getOnWikiName()) ? 'detected' : 'missing');
153
-        } else {
153
+        }
154
+        else {
154 155
             $this->assign('identificationStatus', $user->getForceIdentified() == 1 ? 'forced-on' : 'forced-off');
155 156
         }
156 157
 
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCreateRequest.php 1 patch
Indentation   +147 added lines, -147 removed lines patch added patch discarded remove patch
@@ -33,151 +33,151 @@
 block discarded – undo
33 33
  */
34 34
 class PageCreateRequest extends RequestActionBase
35 35
 {
36
-    /**
37
-     * Main function for this page, when no specific actions are called.
38
-     * @return void
39
-     * @throws AccessDeniedException
40
-     * @throws ApplicationLogicException
41
-     */
42
-    protected function main()
43
-    {
44
-        $this->checkPosted();
45
-
46
-        $database = $this->getDatabase();
47
-
48
-        $request = $this->getRequest($database);
49
-        $template = $this->getTemplate($database);
50
-        $creationMode = $this->getCreationMode();
51
-        $user = User::getCurrent($database);
52
-
53
-        $secMgr = $this->getSecurityManager();
54
-        if ($secMgr->allows('RequestCreation', User::CREATION_BOT, $user) !== SecurityManager::ALLOWED
55
-            && $creationMode === 'bot'
56
-        ) {
57
-            throw new AccessDeniedException($secMgr);
58
-        }
59
-        elseif ($secMgr->allows('RequestCreation', User::CREATION_OAUTH, $user) !== SecurityManager::ALLOWED
60
-            && $creationMode === 'oauth'
61
-        ) {
62
-            throw new AccessDeniedException($secMgr);
63
-        }
64
-
65
-        if ($request->getEmailSent()) {
66
-            throw new ApplicationLogicException('This requester has already had an email sent to them. Please fall back to manual creation');
67
-        }
68
-
69
-        $request->setStatus(RequestStatus::JOBQUEUE);
70
-        $request->setReserved(null);
71
-        $request->save();
72
-
73
-        Logger::enqueuedJobQueue($database, $request);
74
-
75
-        $creationTaskId = $this->enqueueCreationTask($creationMode, $request, $template, $user, $database);
76
-
77
-        if ($user->getWelcomeTemplate() !== null && !WebRequest::postBoolean('skipAutoWelcome')) {
78
-            $this->enqueueWelcomeTask($request, $creationTaskId, $user, $database);
79
-        }
80
-
81
-        SessionAlert::success("Request {$request->getId()} has been queued for autocreation");
82
-
83
-        $this->redirect();
84
-    }
85
-
86
-    protected function getCreationMode()
87
-    {
88
-        $creationMode = WebRequest::postString('mode');
89
-        if ($creationMode !== 'oauth' && $creationMode !== 'bot') {
90
-            throw new ApplicationLogicException('Unknown creation mode');
91
-        }
92
-
93
-        return $creationMode;
94
-    }
95
-
96
-    /**
97
-     * @param PdoDatabase $database
98
-     *
99
-     * @return EmailTemplate
100
-     * @throws ApplicationLogicException
101
-     */
102
-    protected function getTemplate(PdoDatabase $database)
103
-    {
104
-        $templateId = WebRequest::postInt('template');
105
-        if ($templateId === null) {
106
-            throw new ApplicationLogicException('No template specified');
107
-        }
108
-
109
-        /** @var EmailTemplate $template */
110
-        $template = EmailTemplate::getById($templateId, $database);
111
-        if ($template === false || !$template->getActive()) {
112
-            throw new ApplicationLogicException('Invalid or inactive template specified');
113
-        }
114
-
115
-        if ($template->getDefaultAction() !== EmailTemplate::CREATED) {
116
-            throw new ApplicationLogicException('Specified template is not a creation template!');
117
-        }
118
-
119
-        return $template;
120
-    }
121
-
122
-    /**
123
-     * @param PdoDatabase $database
124
-     *
125
-     * @return Request
126
-     * @throws ApplicationLogicException
127
-     */
128
-    protected function getRequest(PdoDatabase $database)
129
-    {
130
-        $request = parent::getRequest($database);
131
-
132
-        if ($request->getStatus() == RequestStatus::CLOSED) {
133
-            throw new ApplicationLogicException('Request is already closed');
134
-        }
135
-
136
-        return $request;
137
-    }
138
-
139
-    /**
140
-     * @param               $creationMode
141
-     * @param Request       $request
142
-     * @param EmailTemplate $template
143
-     * @param User          $user
144
-     *
145
-     * @param PdoDatabase   $database
146
-     *
147
-     * @return int
148
-     * @throws ApplicationLogicException
149
-     */
150
-    protected function enqueueCreationTask(
151
-        $creationMode,
152
-        Request $request,
153
-        EmailTemplate $template,
154
-        User $user,
155
-        PdoDatabase $database
156
-    ) {
157
-        $creationTaskClass = null;
158
-
159
-        if ($creationMode == "oauth") {
160
-            $creationTaskClass = UserCreationTask::class;
161
-        }
162
-
163
-        if ($creationMode == "bot") {
164
-            $creationTaskClass = BotCreationTask::class;
165
-        }
166
-
167
-        if ($creationTaskClass === null) {
168
-            throw new ApplicationLogicException('Cannot determine creation mode');
169
-        }
170
-
171
-        $creationTask = new JobQueue();
172
-        $creationTask->setTask($creationTaskClass);
173
-        $creationTask->setRequest($request->getId());
174
-        $creationTask->setEmailTemplate($template->getId());
175
-        $creationTask->setTriggerUserId($user->getId());
176
-        $creationTask->setDatabase($database);
177
-        $creationTask->save();
178
-
179
-        $creationTaskId = $creationTask->getId();
180
-
181
-        return $creationTaskId;
182
-    }
36
+	/**
37
+	 * Main function for this page, when no specific actions are called.
38
+	 * @return void
39
+	 * @throws AccessDeniedException
40
+	 * @throws ApplicationLogicException
41
+	 */
42
+	protected function main()
43
+	{
44
+		$this->checkPosted();
45
+
46
+		$database = $this->getDatabase();
47
+
48
+		$request = $this->getRequest($database);
49
+		$template = $this->getTemplate($database);
50
+		$creationMode = $this->getCreationMode();
51
+		$user = User::getCurrent($database);
52
+
53
+		$secMgr = $this->getSecurityManager();
54
+		if ($secMgr->allows('RequestCreation', User::CREATION_BOT, $user) !== SecurityManager::ALLOWED
55
+			&& $creationMode === 'bot'
56
+		) {
57
+			throw new AccessDeniedException($secMgr);
58
+		}
59
+		elseif ($secMgr->allows('RequestCreation', User::CREATION_OAUTH, $user) !== SecurityManager::ALLOWED
60
+			&& $creationMode === 'oauth'
61
+		) {
62
+			throw new AccessDeniedException($secMgr);
63
+		}
64
+
65
+		if ($request->getEmailSent()) {
66
+			throw new ApplicationLogicException('This requester has already had an email sent to them. Please fall back to manual creation');
67
+		}
68
+
69
+		$request->setStatus(RequestStatus::JOBQUEUE);
70
+		$request->setReserved(null);
71
+		$request->save();
72
+
73
+		Logger::enqueuedJobQueue($database, $request);
74
+
75
+		$creationTaskId = $this->enqueueCreationTask($creationMode, $request, $template, $user, $database);
76
+
77
+		if ($user->getWelcomeTemplate() !== null && !WebRequest::postBoolean('skipAutoWelcome')) {
78
+			$this->enqueueWelcomeTask($request, $creationTaskId, $user, $database);
79
+		}
80
+
81
+		SessionAlert::success("Request {$request->getId()} has been queued for autocreation");
82
+
83
+		$this->redirect();
84
+	}
85
+
86
+	protected function getCreationMode()
87
+	{
88
+		$creationMode = WebRequest::postString('mode');
89
+		if ($creationMode !== 'oauth' && $creationMode !== 'bot') {
90
+			throw new ApplicationLogicException('Unknown creation mode');
91
+		}
92
+
93
+		return $creationMode;
94
+	}
95
+
96
+	/**
97
+	 * @param PdoDatabase $database
98
+	 *
99
+	 * @return EmailTemplate
100
+	 * @throws ApplicationLogicException
101
+	 */
102
+	protected function getTemplate(PdoDatabase $database)
103
+	{
104
+		$templateId = WebRequest::postInt('template');
105
+		if ($templateId === null) {
106
+			throw new ApplicationLogicException('No template specified');
107
+		}
108
+
109
+		/** @var EmailTemplate $template */
110
+		$template = EmailTemplate::getById($templateId, $database);
111
+		if ($template === false || !$template->getActive()) {
112
+			throw new ApplicationLogicException('Invalid or inactive template specified');
113
+		}
114
+
115
+		if ($template->getDefaultAction() !== EmailTemplate::CREATED) {
116
+			throw new ApplicationLogicException('Specified template is not a creation template!');
117
+		}
118
+
119
+		return $template;
120
+	}
121
+
122
+	/**
123
+	 * @param PdoDatabase $database
124
+	 *
125
+	 * @return Request
126
+	 * @throws ApplicationLogicException
127
+	 */
128
+	protected function getRequest(PdoDatabase $database)
129
+	{
130
+		$request = parent::getRequest($database);
131
+
132
+		if ($request->getStatus() == RequestStatus::CLOSED) {
133
+			throw new ApplicationLogicException('Request is already closed');
134
+		}
135
+
136
+		return $request;
137
+	}
138
+
139
+	/**
140
+	 * @param               $creationMode
141
+	 * @param Request       $request
142
+	 * @param EmailTemplate $template
143
+	 * @param User          $user
144
+	 *
145
+	 * @param PdoDatabase   $database
146
+	 *
147
+	 * @return int
148
+	 * @throws ApplicationLogicException
149
+	 */
150
+	protected function enqueueCreationTask(
151
+		$creationMode,
152
+		Request $request,
153
+		EmailTemplate $template,
154
+		User $user,
155
+		PdoDatabase $database
156
+	) {
157
+		$creationTaskClass = null;
158
+
159
+		if ($creationMode == "oauth") {
160
+			$creationTaskClass = UserCreationTask::class;
161
+		}
162
+
163
+		if ($creationMode == "bot") {
164
+			$creationTaskClass = BotCreationTask::class;
165
+		}
166
+
167
+		if ($creationTaskClass === null) {
168
+			throw new ApplicationLogicException('Cannot determine creation mode');
169
+		}
170
+
171
+		$creationTask = new JobQueue();
172
+		$creationTask->setTask($creationTaskClass);
173
+		$creationTask->setRequest($request->getId());
174
+		$creationTask->setEmailTemplate($template->getId());
175
+		$creationTask->setTriggerUserId($user->getId());
176
+		$creationTask->setDatabase($database);
177
+		$creationTask->save();
178
+
179
+		$creationTaskId = $creationTask->getId();
180
+
181
+		return $creationTaskId;
182
+	}
183 183
 }
Please login to merge, or discard this patch.
includes/Pages/UserAuth/PageLogout.php 2 patches
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -14,22 +14,22 @@
 block discarded – undo
14 14
 
15 15
 class PageLogout extends InternalPageBase
16 16
 {
17
-    /**
18
-     * Main function for this page, when no specific actions are called.
19
-     */
20
-    protected function main()
21
-    {
22
-        if(WebRequest::wasPosted()) {
23
-            Session::destroy();
24
-            $this->redirect("login");
25
-            return;
26
-        }
17
+	/**
18
+	 * Main function for this page, when no specific actions are called.
19
+	 */
20
+	protected function main()
21
+	{
22
+		if(WebRequest::wasPosted()) {
23
+			Session::destroy();
24
+			$this->redirect("login");
25
+			return;
26
+		}
27 27
 
28
-        $this->redirect();
29
-    }
28
+		$this->redirect();
29
+	}
30 30
 
31
-    protected function isProtectedPage()
32
-    {
33
-        return false;
34
-    }
31
+	protected function isProtectedPage()
32
+	{
33
+		return false;
34
+	}
35 35
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@
 block discarded – undo
19 19
      */
20 20
     protected function main()
21 21
     {
22
-        if(WebRequest::wasPosted()) {
22
+        if (WebRequest::wasPosted()) {
23 23
             Session::destroy();
24 24
             $this->redirect("login");
25 25
             return;
Please login to merge, or discard this patch.
includes/WebStart.php 1 patch
Indentation   +221 added lines, -221 removed lines patch added patch discarded remove patch
@@ -32,225 +32,225 @@
 block discarded – undo
32 32
  */
33 33
 class WebStart extends ApplicationBase
34 34
 {
35
-    /**
36
-     * @var IRequestRouter $requestRouter The request router to use. Note that different entry points have different
37
-     *                                    routers and hence different URL mappings
38
-     */
39
-    private $requestRouter;
40
-    /**
41
-     * @var bool $isPublic Determines whether to use public interface objects or internal interface objects
42
-     */
43
-    private $isPublic = false;
44
-
45
-    /**
46
-     * WebStart constructor.
47
-     *
48
-     * @param SiteConfiguration $configuration The site configuration
49
-     * @param IRequestRouter    $router        The request router to use
50
-     */
51
-    public function __construct(SiteConfiguration $configuration, IRequestRouter $router)
52
-    {
53
-        parent::__construct($configuration);
54
-
55
-        $this->requestRouter = $router;
56
-    }
57
-
58
-    /**
59
-     * @param ITask             $page
60
-     * @param SiteConfiguration $siteConfiguration
61
-     * @param PdoDatabase       $database
62
-     * @param PdoDatabase       $notificationsDatabase
63
-     *
64
-     * @return void
65
-     */
66
-    protected function setupHelpers(
67
-        ITask $page,
68
-        SiteConfiguration $siteConfiguration,
69
-        PdoDatabase $database,
70
-        PdoDatabase $notificationsDatabase = null
71
-    ) {
72
-        parent::setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
73
-
74
-        if ($page instanceof PageBase) {
75
-            $page->setTokenManager(new TokenManager());
76
-            $page->setCspManager(new ContentSecurityPolicyManager($siteConfiguration));
77
-
78
-            if ($page instanceof InternalPageBase) {
79
-                $page->setTypeAheadHelper(new TypeAheadHelper());
80
-
81
-                $identificationVerifier = new IdentificationVerifier($page->getHttpHelper(), $siteConfiguration,
82
-                    $database);
83
-                $page->setIdentificationVerifier($identificationVerifier);
84
-
85
-                $page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration()));
86
-
87
-                if ($siteConfiguration->getTitleBlacklistEnabled()) {
88
-                    $page->setBlacklistHelper(new FakeBlacklistHelper());
89
-                }
90
-                else {
91
-                    $page->setBlacklistHelper(new BlacklistHelper($page->getHttpHelper(),
92
-                        $siteConfiguration->getMediawikiWebServiceEndpoint()));
93
-                }
94
-            }
95
-        }
96
-    }
97
-
98
-    /**
99
-     * Application entry point.
100
-     *
101
-     * Sets up the environment and runs the application, performing any global cleanup operations when done.
102
-     */
103
-    public function run()
104
-    {
105
-        try {
106
-            if ($this->setupEnvironment()) {
107
-                $this->main();
108
-            }
109
-        }
110
-        catch (EnvironmentException $ex) {
111
-            ob_end_clean();
112
-            print Offline::getOfflineMessage($this->isPublic(), $ex->getMessage());
113
-        }
114
-        catch (ReadableException $ex) {
115
-            ob_end_clean();
116
-            print $ex->getReadableError();
117
-        }
118
-        finally {
119
-            $this->cleanupEnvironment();
120
-        }
121
-    }
122
-
123
-    /**
124
-     * Environment setup
125
-     *
126
-     * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
127
-     * and shut down prematurely.
128
-     *
129
-     * @return bool
130
-     * @throws EnvironmentException
131
-     */
132
-    protected function setupEnvironment()
133
-    {
134
-        // initialise global exception handler
135
-        set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
136
-        set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
137
-
138
-        // start output buffering if necessary
139
-        if (ob_get_level() === 0) {
140
-            ob_start();
141
-        }
142
-
143
-        // initialise super-global providers
144
-        WebRequest::setGlobalStateProvider(new GlobalStateProvider());
145
-
146
-        if (Offline::isOffline()) {
147
-            print Offline::getOfflineMessage($this->isPublic());
148
-            ob_end_flush();
149
-
150
-            return false;
151
-        }
152
-
153
-        // Call parent setup
154
-        if (!parent::setupEnvironment()) {
155
-            return false;
156
-        }
157
-
158
-        // Start up sessions
159
-        Session::start();
160
-
161
-        // Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
162
-        // get the current user cached.
163
-        // I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
164
-        // session I suppose.
165
-        $this->checkForceLogout();
166
-
167
-        // environment initialised!
168
-        return true;
169
-    }
170
-
171
-    /**
172
-     * Main application logic
173
-     */
174
-    protected function main()
175
-    {
176
-        // Get the right route for the request
177
-        $page = $this->requestRouter->route();
178
-
179
-        $siteConfiguration = $this->getConfiguration();
180
-        $database = PdoDatabase::getDatabaseConnection('acc');
181
-
182
-        if ($siteConfiguration->getIrcNotificationsEnabled()) {
183
-            $notificationsDatabase = PdoDatabase::getDatabaseConnection('notifications');
184
-        }
185
-        else {
186
-            // @todo federated table here?
187
-            $notificationsDatabase = $database;
188
-        }
189
-
190
-        $this->setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
191
-
192
-        /* @todo Remove this global statement! It's here for User.php, which does far more than it should. */
193
-        global $oauthProtocolHelper;
194
-        $oauthProtocolHelper = $page->getOAuthProtocolHelper();
195
-
196
-        /* @todo Remove this global statement! It's here for Request.php, which does far more than it should. */
197
-        global $globalXffTrustProvider;
198
-        $globalXffTrustProvider = $page->getXffTrustProvider();
199
-
200
-        // run the route code for the request.
201
-        $page->execute();
202
-    }
203
-
204
-    /**
205
-     * Any cleanup tasks should go here
206
-     *
207
-     * Note that we need to be very careful here, as exceptions may have been thrown and handled.
208
-     * This should *only* be for cleaning up, no logic should go here.
209
-     */
210
-    protected function cleanupEnvironment()
211
-    {
212
-        // Clean up anything we splurged after sending the page.
213
-        if (ob_get_level() > 0) {
214
-            for ($i = ob_get_level(); $i > 0; $i--) {
215
-                ob_end_clean();
216
-            }
217
-        }
218
-    }
219
-
220
-    private function checkForceLogout()
221
-    {
222
-        $database = PdoDatabase::getDatabaseConnection('acc');
223
-
224
-        $sessionUserId = WebRequest::getSessionUserId();
225
-        iF ($sessionUserId === null) {
226
-            return;
227
-        }
228
-
229
-        // Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
230
-        $currentUser = User::getById($sessionUserId, $database);
231
-
232
-        if ($currentUser === false) {
233
-            // Umm... this user has a session cookie with a userId set, but no user exists...
234
-            Session::restart();
235
-
236
-            $currentUser = User::getCurrent($database);
237
-        }
238
-
239
-        if ($currentUser->getForceLogout()) {
240
-            Session::restart();
241
-
242
-            $currentUser->setForceLogout(false);
243
-            $currentUser->save();
244
-        }
245
-    }
246
-
247
-    public function isPublic()
248
-    {
249
-        return $this->isPublic;
250
-    }
251
-
252
-    public function setPublic($isPublic)
253
-    {
254
-        $this->isPublic = $isPublic;
255
-    }
35
+	/**
36
+	 * @var IRequestRouter $requestRouter The request router to use. Note that different entry points have different
37
+	 *                                    routers and hence different URL mappings
38
+	 */
39
+	private $requestRouter;
40
+	/**
41
+	 * @var bool $isPublic Determines whether to use public interface objects or internal interface objects
42
+	 */
43
+	private $isPublic = false;
44
+
45
+	/**
46
+	 * WebStart constructor.
47
+	 *
48
+	 * @param SiteConfiguration $configuration The site configuration
49
+	 * @param IRequestRouter    $router        The request router to use
50
+	 */
51
+	public function __construct(SiteConfiguration $configuration, IRequestRouter $router)
52
+	{
53
+		parent::__construct($configuration);
54
+
55
+		$this->requestRouter = $router;
56
+	}
57
+
58
+	/**
59
+	 * @param ITask             $page
60
+	 * @param SiteConfiguration $siteConfiguration
61
+	 * @param PdoDatabase       $database
62
+	 * @param PdoDatabase       $notificationsDatabase
63
+	 *
64
+	 * @return void
65
+	 */
66
+	protected function setupHelpers(
67
+		ITask $page,
68
+		SiteConfiguration $siteConfiguration,
69
+		PdoDatabase $database,
70
+		PdoDatabase $notificationsDatabase = null
71
+	) {
72
+		parent::setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
73
+
74
+		if ($page instanceof PageBase) {
75
+			$page->setTokenManager(new TokenManager());
76
+			$page->setCspManager(new ContentSecurityPolicyManager($siteConfiguration));
77
+
78
+			if ($page instanceof InternalPageBase) {
79
+				$page->setTypeAheadHelper(new TypeAheadHelper());
80
+
81
+				$identificationVerifier = new IdentificationVerifier($page->getHttpHelper(), $siteConfiguration,
82
+					$database);
83
+				$page->setIdentificationVerifier($identificationVerifier);
84
+
85
+				$page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration()));
86
+
87
+				if ($siteConfiguration->getTitleBlacklistEnabled()) {
88
+					$page->setBlacklistHelper(new FakeBlacklistHelper());
89
+				}
90
+				else {
91
+					$page->setBlacklistHelper(new BlacklistHelper($page->getHttpHelper(),
92
+						$siteConfiguration->getMediawikiWebServiceEndpoint()));
93
+				}
94
+			}
95
+		}
96
+	}
97
+
98
+	/**
99
+	 * Application entry point.
100
+	 *
101
+	 * Sets up the environment and runs the application, performing any global cleanup operations when done.
102
+	 */
103
+	public function run()
104
+	{
105
+		try {
106
+			if ($this->setupEnvironment()) {
107
+				$this->main();
108
+			}
109
+		}
110
+		catch (EnvironmentException $ex) {
111
+			ob_end_clean();
112
+			print Offline::getOfflineMessage($this->isPublic(), $ex->getMessage());
113
+		}
114
+		catch (ReadableException $ex) {
115
+			ob_end_clean();
116
+			print $ex->getReadableError();
117
+		}
118
+		finally {
119
+			$this->cleanupEnvironment();
120
+		}
121
+	}
122
+
123
+	/**
124
+	 * Environment setup
125
+	 *
126
+	 * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
127
+	 * and shut down prematurely.
128
+	 *
129
+	 * @return bool
130
+	 * @throws EnvironmentException
131
+	 */
132
+	protected function setupEnvironment()
133
+	{
134
+		// initialise global exception handler
135
+		set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
136
+		set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
137
+
138
+		// start output buffering if necessary
139
+		if (ob_get_level() === 0) {
140
+			ob_start();
141
+		}
142
+
143
+		// initialise super-global providers
144
+		WebRequest::setGlobalStateProvider(new GlobalStateProvider());
145
+
146
+		if (Offline::isOffline()) {
147
+			print Offline::getOfflineMessage($this->isPublic());
148
+			ob_end_flush();
149
+
150
+			return false;
151
+		}
152
+
153
+		// Call parent setup
154
+		if (!parent::setupEnvironment()) {
155
+			return false;
156
+		}
157
+
158
+		// Start up sessions
159
+		Session::start();
160
+
161
+		// Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
162
+		// get the current user cached.
163
+		// I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
164
+		// session I suppose.
165
+		$this->checkForceLogout();
166
+
167
+		// environment initialised!
168
+		return true;
169
+	}
170
+
171
+	/**
172
+	 * Main application logic
173
+	 */
174
+	protected function main()
175
+	{
176
+		// Get the right route for the request
177
+		$page = $this->requestRouter->route();
178
+
179
+		$siteConfiguration = $this->getConfiguration();
180
+		$database = PdoDatabase::getDatabaseConnection('acc');
181
+
182
+		if ($siteConfiguration->getIrcNotificationsEnabled()) {
183
+			$notificationsDatabase = PdoDatabase::getDatabaseConnection('notifications');
184
+		}
185
+		else {
186
+			// @todo federated table here?
187
+			$notificationsDatabase = $database;
188
+		}
189
+
190
+		$this->setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
191
+
192
+		/* @todo Remove this global statement! It's here for User.php, which does far more than it should. */
193
+		global $oauthProtocolHelper;
194
+		$oauthProtocolHelper = $page->getOAuthProtocolHelper();
195
+
196
+		/* @todo Remove this global statement! It's here for Request.php, which does far more than it should. */
197
+		global $globalXffTrustProvider;
198
+		$globalXffTrustProvider = $page->getXffTrustProvider();
199
+
200
+		// run the route code for the request.
201
+		$page->execute();
202
+	}
203
+
204
+	/**
205
+	 * Any cleanup tasks should go here
206
+	 *
207
+	 * Note that we need to be very careful here, as exceptions may have been thrown and handled.
208
+	 * This should *only* be for cleaning up, no logic should go here.
209
+	 */
210
+	protected function cleanupEnvironment()
211
+	{
212
+		// Clean up anything we splurged after sending the page.
213
+		if (ob_get_level() > 0) {
214
+			for ($i = ob_get_level(); $i > 0; $i--) {
215
+				ob_end_clean();
216
+			}
217
+		}
218
+	}
219
+
220
+	private function checkForceLogout()
221
+	{
222
+		$database = PdoDatabase::getDatabaseConnection('acc');
223
+
224
+		$sessionUserId = WebRequest::getSessionUserId();
225
+		iF ($sessionUserId === null) {
226
+			return;
227
+		}
228
+
229
+		// Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
230
+		$currentUser = User::getById($sessionUserId, $database);
231
+
232
+		if ($currentUser === false) {
233
+			// Umm... this user has a session cookie with a userId set, but no user exists...
234
+			Session::restart();
235
+
236
+			$currentUser = User::getCurrent($database);
237
+		}
238
+
239
+		if ($currentUser->getForceLogout()) {
240
+			Session::restart();
241
+
242
+			$currentUser->setForceLogout(false);
243
+			$currentUser->save();
244
+		}
245
+	}
246
+
247
+	public function isPublic()
248
+	{
249
+		return $this->isPublic;
250
+	}
251
+
252
+	public function setPublic($isPublic)
253
+	{
254
+		$this->isPublic = $isPublic;
255
+	}
256 256
 }
Please login to merge, or discard this patch.
includes/Helpers/OAuthUserHelper.php 2 patches
Indentation   +417 added lines, -417 removed lines patch added patch discarded remove patch
@@ -22,425 +22,425 @@
 block discarded – undo
22 22
 
23 23
 class OAuthUserHelper implements IMediaWikiClient
24 24
 {
25
-    const TOKEN_REQUEST = 'request';
26
-    const TOKEN_ACCESS = 'access';
27
-    /** @var PDOStatement */
28
-    private static $tokenCountStatement = null;
29
-    /** @var PDOStatement */
30
-    private $getTokenStatement;
31
-    /**
32
-     * @var User
33
-     */
34
-    private $user;
35
-    /**
36
-     * @var PdoDatabase
37
-     */
38
-    private $database;
39
-    /**
40
-     * @var IOAuthProtocolHelper
41
-     */
42
-    private $oauthProtocolHelper;
43
-    /**
44
-     * @var bool|null Is the user linked to OAuth
45
-     */
46
-    private $linked;
47
-    private $partiallyLinked;
48
-    /** @var OAuthToken */
49
-    private $accessToken;
50
-    /** @var bool */
51
-    private $accessTokenLoaded = false;
52
-    /**
53
-     * @var OAuthIdentity
54
-     */
55
-    private $identity = null;
56
-    /**
57
-     * @var bool
58
-     */
59
-    private $identityLoaded = false;
60
-    /**
61
-     * @var SiteConfiguration
62
-     */
63
-    private $siteConfiguration;
64
-
65
-    #region Static methods
66
-    public static function findUserByRequestToken($requestToken, PdoDatabase $database)
67
-    {
68
-        $statement = $database->prepare(<<<'SQL'
25
+	const TOKEN_REQUEST = 'request';
26
+	const TOKEN_ACCESS = 'access';
27
+	/** @var PDOStatement */
28
+	private static $tokenCountStatement = null;
29
+	/** @var PDOStatement */
30
+	private $getTokenStatement;
31
+	/**
32
+	 * @var User
33
+	 */
34
+	private $user;
35
+	/**
36
+	 * @var PdoDatabase
37
+	 */
38
+	private $database;
39
+	/**
40
+	 * @var IOAuthProtocolHelper
41
+	 */
42
+	private $oauthProtocolHelper;
43
+	/**
44
+	 * @var bool|null Is the user linked to OAuth
45
+	 */
46
+	private $linked;
47
+	private $partiallyLinked;
48
+	/** @var OAuthToken */
49
+	private $accessToken;
50
+	/** @var bool */
51
+	private $accessTokenLoaded = false;
52
+	/**
53
+	 * @var OAuthIdentity
54
+	 */
55
+	private $identity = null;
56
+	/**
57
+	 * @var bool
58
+	 */
59
+	private $identityLoaded = false;
60
+	/**
61
+	 * @var SiteConfiguration
62
+	 */
63
+	private $siteConfiguration;
64
+
65
+	#region Static methods
66
+	public static function findUserByRequestToken($requestToken, PdoDatabase $database)
67
+	{
68
+		$statement = $database->prepare(<<<'SQL'
69 69
             SELECT u.* FROM user u 
70 70
             INNER JOIN oauthtoken t ON t.user = u.id 
71 71
             WHERE t.type = :type AND t.token = :token
72 72
 SQL
73
-        );
74
-        $statement->execute(array(':type' => self::TOKEN_REQUEST, ':token' => $requestToken));
75
-
76
-        /** @var User $user */
77
-        $user = $statement->fetchObject(User::class);
78
-        $statement->closeCursor();
79
-
80
-        if ($user === false) {
81
-            throw new ApplicationLogicException('Token not found in store, please try again');
82
-        }
83
-
84
-        $user->setDatabase($database);
85
-
86
-        return $user;
87
-    }
88
-
89
-    public static function userIsFullyLinked(User $user, PdoDatabase $database = null)
90
-    {
91
-        if (self::$tokenCountStatement === null && $database === null) {
92
-            throw new ApplicationLogicException('Static link request without initialised statement');
93
-        }
94
-
95
-        return self::runTokenCount($user->getId(), $database, self::TOKEN_ACCESS);
96
-    }
97
-
98
-    public static function userIsPartiallyLinked(User $user, PdoDatabase $database = null)
99
-    {
100
-        if (self::$tokenCountStatement === null && $database === null) {
101
-            throw new ApplicationLogicException('Static link request without initialised statement');
102
-        }
103
-
104
-        if (self::userIsFullyLinked($user, $database)) {
105
-            return false;
106
-        }
107
-
108
-        return self::runTokenCount($user->getId(), $database, self::TOKEN_REQUEST)
109
-            || $user->getOnWikiName() == null;
110
-    }
111
-
112
-    /**
113
-     * @param PdoDatabase $database
114
-     */
115
-    public static function prepareTokenCountStatement(PdoDatabase $database)
116
-    {
117
-        if (self::$tokenCountStatement === null) {
118
-            self::$tokenCountStatement = $database->prepare('SELECT COUNT(*) FROM oauthtoken WHERE user = :user AND type = :type');
119
-        }
120
-    }
121
-
122
-    private static function runTokenCount($userId, $database, $tokenType)
123
-    {
124
-        if (self::$tokenCountStatement === null) {
125
-            self::prepareTokenCountStatement($database);
126
-        }
127
-
128
-        self::$tokenCountStatement->execute(array(
129
-            ':user' => $userId,
130
-            ':type' => $tokenType,
131
-        ));
132
-
133
-        $tokenCount = self::$tokenCountStatement->fetchColumn();
134
-        $linked = $tokenCount > 0;
135
-        self::$tokenCountStatement->closeCursor();
136
-
137
-        return $linked;
138
-    }
139
-
140
-    #endregion Static methods
141
-
142
-    /**
143
-     * OAuthUserHelper constructor.
144
-     *
145
-     * @param User                 $user
146
-     * @param PdoDatabase          $database
147
-     * @param IOAuthProtocolHelper $oauthProtocolHelper
148
-     * @param SiteConfiguration    $siteConfiguration
149
-     */
150
-    public function __construct(
151
-        User $user,
152
-        PdoDatabase $database,
153
-        IOAuthProtocolHelper $oauthProtocolHelper,
154
-        SiteConfiguration $siteConfiguration
155
-    ) {
156
-        $this->user = $user;
157
-        $this->database = $database;
158
-        $this->oauthProtocolHelper = $oauthProtocolHelper;
159
-
160
-        $this->linked = null;
161
-        $this->partiallyLinked = null;
162
-        $this->siteConfiguration = $siteConfiguration;
163
-
164
-        self::prepareTokenCountStatement($database);
165
-        $this->getTokenStatement = $this->database->prepare('SELECT * FROM oauthtoken WHERE user = :user AND type = :type');
166
-    }
167
-
168
-    /**
169
-     * Determines if the user is fully connected to OAuth.
170
-     *
171
-     * @return bool
172
-     */
173
-    public function isFullyLinked()
174
-    {
175
-        if ($this->linked === null) {
176
-            $this->linked = self::userIsFullyLinked($this->user, $this->database);
177
-        }
178
-
179
-        return $this->linked;
180
-    }
181
-
182
-    /**
183
-     * Attempts to figure out if a user is partially linked to OAuth, and therefore needs to complete the OAuth
184
-     * procedure before configuring.
185
-     * @return bool
186
-     */
187
-    public function isPartiallyLinked()
188
-    {
189
-        if ($this->partiallyLinked === null) {
190
-            $this->partiallyLinked = self::userIsPartiallyLinked($this->user, $this->database);
191
-        }
192
-
193
-        return $this->partiallyLinked;
194
-    }
195
-
196
-    public function canCreateAccount() {
197
-        return $this->isFullyLinked()
198
-            && $this->getIdentity(true)->getGrantBasic()
199
-            && $this->getIdentity(true)->getGrantHighVolume()
200
-            && $this->getIdentity(true)->getGrantCreateAccount();
201
-    }
202
-
203
-    public function canWelcome() {
204
-        return $this->isFullyLinked()
205
-            && $this->getIdentity(true)->getGrantBasic()
206
-            && $this->getIdentity(true)->getGrantHighVolume()
207
-            && $this->getIdentity(true)->getGrantCreateEditMovePage();
208
-    }
209
-
210
-    /**
211
-     * @throws OAuthException
212
-     */
213
-    public function refreshIdentity()
214
-    {
215
-        $this->loadIdentity();
216
-
217
-        if ($this->identity === null) {
218
-            $this->identity = new OAuthIdentity();
219
-            $this->identity->setUserId($this->user->getId());
220
-            $this->identity->setDatabase($this->database);
221
-        }
222
-
223
-        $token = $this->loadAccessToken();
224
-
225
-        $rawTicket = $this->oauthProtocolHelper->getIdentityTicket($token->getToken(), $token->getSecret());
226
-
227
-        $this->identity->populate($rawTicket);
228
-
229
-        if (!$this->identityIsValid()) {
230
-            throw new OAuthException('Identity ticket is not valid!');
231
-        }
232
-
233
-        $this->identity->save();
234
-
235
-        $this->user->setOnWikiName($this->identity->getUsername());
236
-        $this->user->save();
237
-    }
238
-
239
-    public function getRequestToken()
240
-    {
241
-        $token = $this->oauthProtocolHelper->getRequestToken();
242
-
243
-        $this->partiallyLinked = true;
244
-        $this->linked = false;
245
-
246
-        $this->database
247
-            ->prepare('DELETE FROM oauthtoken WHERE user = :user AND type = :type')
248
-            ->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_REQUEST));
249
-
250
-        $this->database
251
-            ->prepare('INSERT INTO oauthtoken (user, type, token, secret, expiry) VALUES (:user, :type, :token, :secret, DATE_ADD(NOW(), INTERVAL 1 DAY))')
252
-            ->execute(array(
253
-                ':user'   => $this->user->getId(),
254
-                ':type'   => self::TOKEN_REQUEST,
255
-                ':token'  => $token->key,
256
-                ':secret' => $token->secret,
257
-            ));
258
-
259
-        return $this->oauthProtocolHelper->getAuthoriseUrl($token->key);
260
-    }
261
-
262
-    public function completeHandshake($verificationToken)
263
-    {
264
-        $this->getTokenStatement->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_REQUEST));
265
-
266
-        /** @var OAuthToken $token */
267
-        $token = $this->getTokenStatement->fetchObject(OAuthToken::class);
268
-        $this->getTokenStatement->closeCursor();
269
-
270
-        if ($token === false) {
271
-            throw new ApplicationLogicException('Cannot find request token');
272
-        }
273
-
274
-        $token->setDatabase($this->database);
275
-
276
-        $accessToken = $this->oauthProtocolHelper->callbackCompleted($token->getToken(), $token->getSecret(),
277
-            $verificationToken);
278
-
279
-        $clearStatement = $this->database->prepare('DELETE FROM oauthtoken WHERE user = :u AND type = :t');
280
-        $clearStatement->execute(array(':u' => $this->user->getId(), ':t' => self::TOKEN_ACCESS));
281
-
282
-        $token->setToken($accessToken->key);
283
-        $token->setSecret($accessToken->secret);
284
-        $token->setType(self::TOKEN_ACCESS);
285
-        $token->setExpiry(null);
286
-        $token->save();
287
-
288
-        $this->partiallyLinked = false;
289
-        $this->linked = true;
290
-
291
-        $this->refreshIdentity();
292
-    }
293
-
294
-    public function detach()
295
-    {
296
-        $this->loadIdentity();
297
-
298
-        $this->identity->delete();
299
-        $statement = $this->database->prepare('DELETE FROM oauthtoken WHERE user = :user');
300
-        $statement->execute(array(':user' => $this->user->getId()));
301
-
302
-        $this->identity = null;
303
-        $this->linked = false;
304
-        $this->partiallyLinked = false;
305
-    }
306
-
307
-    /**
308
-     * @param bool $expiredOk
309
-     *
310
-     * @return OAuthIdentity
311
-     * @throws OAuthException
312
-     */
313
-    public function getIdentity($expiredOk = false)
314
-    {
315
-        $this->loadIdentity();
316
-
317
-        if (!$this->identityIsValid($expiredOk)) {
318
-            throw new OAuthException('Stored identity is not valid.');
319
-        }
320
-
321
-        return $this->identity;
322
-    }
323
-
324
-    public function doApiCall($params, $method)
325
-    {
326
-        // Ensure we're logged in
327
-        $params['assert'] = 'user';
328
-
329
-        $token = $this->loadAccessToken();
330
-        return $this->oauthProtocolHelper->apiCall($params, $token->getToken(), $token->getSecret(), $method);
331
-    }
332
-
333
-    /**
334
-     * @param bool $expiredOk
335
-     *
336
-     * @return bool
337
-     */
338
-    private function identityIsValid($expiredOk = false)
339
-    {
340
-        $this->loadIdentity();
341
-
342
-        if ($this->identity === null) {
343
-            return false;
344
-        }
345
-
346
-        if ($this->identity->getIssuedAtTime() === false
347
-            || $this->identity->getExpirationTime() === false
348
-            || $this->identity->getAudience() === false
349
-            || $this->identity->getIssuer() === false
350
-        ) {
351
-            // this isn't populated properly.
352
-            return false;
353
-        }
354
-
355
-        $issue = DateTimeImmutable::createFromFormat("U", $this->identity->getIssuedAtTime());
356
-        $now = new DateTimeImmutable();
357
-
358
-        if ($issue > $now) {
359
-            // wat.
360
-            return false;
361
-        }
362
-
363
-        if ($this->identityExpired() && !$expiredOk) {
364
-            // soz.
365
-            return false;
366
-        }
367
-
368
-        if ($this->identity->getAudience() !== $this->siteConfiguration->getOAuthConsumerToken()) {
369
-            // token not issued for us
370
-            return false;
371
-        }
372
-
373
-        if ($this->identity->getIssuer() !== $this->siteConfiguration->getOauthMediaWikiCanonicalServer()) {
374
-            // token not issued by the right person
375
-            return false;
376
-        }
377
-
378
-        // can't find a reason to not trust it
379
-        return true;
380
-    }
381
-
382
-    /**
383
-     * @return bool
384
-     */
385
-    public function identityExpired()
386
-    {
387
-        // allowed max age
388
-        $gracePeriod = $this->siteConfiguration->getOauthIdentityGraceTime();
389
-
390
-        $expiry = DateTimeImmutable::createFromFormat("U", $this->identity->getExpirationTime());
391
-        $graceExpiry = $expiry->modify($gracePeriod);
392
-        $now = new DateTimeImmutable();
393
-
394
-        return $graceExpiry < $now;
395
-    }
396
-
397
-    /**
398
-     * Loads the OAuth identity from the database for the current user.
399
-     */
400
-    private function loadIdentity()
401
-    {
402
-        if ($this->identityLoaded) {
403
-            return;
404
-        }
405
-
406
-        $statement = $this->database->prepare('SELECT * FROM oauthidentity WHERE user = :user');
407
-        $statement->execute(array(':user' => $this->user->getId()));
408
-        /** @var OAuthIdentity $obj */
409
-        $obj = $statement->fetchObject(OAuthIdentity::class);
410
-
411
-        if ($obj === false) {
412
-            // failed to load identity.
413
-            $this->identityLoaded = true;
414
-            $this->identity = null;
415
-
416
-            return;
417
-        }
418
-
419
-        $obj->setDatabase($this->database);
420
-        $this->identityLoaded = true;
421
-        $this->identity = $obj;
422
-    }
423
-
424
-    /**
425
-     * @return OAuthToken
426
-     * @throws OAuthException
427
-     */
428
-    private function loadAccessToken()
429
-    {
430
-        if (!$this->accessTokenLoaded) {
431
-            $this->getTokenStatement->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_ACCESS));
432
-            /** @var OAuthToken $token */
433
-            $token = $this->getTokenStatement->fetchObject(OAuthToken::class);
434
-            $this->getTokenStatement->closeCursor();
435
-
436
-            if ($token === false) {
437
-                throw new OAuthException('Access token not found!');
438
-            }
439
-
440
-            $this->accessToken = $token;
441
-            $this->accessTokenLoaded = true;
442
-        }
443
-
444
-        return $this->accessToken;
445
-    }
73
+		);
74
+		$statement->execute(array(':type' => self::TOKEN_REQUEST, ':token' => $requestToken));
75
+
76
+		/** @var User $user */
77
+		$user = $statement->fetchObject(User::class);
78
+		$statement->closeCursor();
79
+
80
+		if ($user === false) {
81
+			throw new ApplicationLogicException('Token not found in store, please try again');
82
+		}
83
+
84
+		$user->setDatabase($database);
85
+
86
+		return $user;
87
+	}
88
+
89
+	public static function userIsFullyLinked(User $user, PdoDatabase $database = null)
90
+	{
91
+		if (self::$tokenCountStatement === null && $database === null) {
92
+			throw new ApplicationLogicException('Static link request without initialised statement');
93
+		}
94
+
95
+		return self::runTokenCount($user->getId(), $database, self::TOKEN_ACCESS);
96
+	}
97
+
98
+	public static function userIsPartiallyLinked(User $user, PdoDatabase $database = null)
99
+	{
100
+		if (self::$tokenCountStatement === null && $database === null) {
101
+			throw new ApplicationLogicException('Static link request without initialised statement');
102
+		}
103
+
104
+		if (self::userIsFullyLinked($user, $database)) {
105
+			return false;
106
+		}
107
+
108
+		return self::runTokenCount($user->getId(), $database, self::TOKEN_REQUEST)
109
+			|| $user->getOnWikiName() == null;
110
+	}
111
+
112
+	/**
113
+	 * @param PdoDatabase $database
114
+	 */
115
+	public static function prepareTokenCountStatement(PdoDatabase $database)
116
+	{
117
+		if (self::$tokenCountStatement === null) {
118
+			self::$tokenCountStatement = $database->prepare('SELECT COUNT(*) FROM oauthtoken WHERE user = :user AND type = :type');
119
+		}
120
+	}
121
+
122
+	private static function runTokenCount($userId, $database, $tokenType)
123
+	{
124
+		if (self::$tokenCountStatement === null) {
125
+			self::prepareTokenCountStatement($database);
126
+		}
127
+
128
+		self::$tokenCountStatement->execute(array(
129
+			':user' => $userId,
130
+			':type' => $tokenType,
131
+		));
132
+
133
+		$tokenCount = self::$tokenCountStatement->fetchColumn();
134
+		$linked = $tokenCount > 0;
135
+		self::$tokenCountStatement->closeCursor();
136
+
137
+		return $linked;
138
+	}
139
+
140
+	#endregion Static methods
141
+
142
+	/**
143
+	 * OAuthUserHelper constructor.
144
+	 *
145
+	 * @param User                 $user
146
+	 * @param PdoDatabase          $database
147
+	 * @param IOAuthProtocolHelper $oauthProtocolHelper
148
+	 * @param SiteConfiguration    $siteConfiguration
149
+	 */
150
+	public function __construct(
151
+		User $user,
152
+		PdoDatabase $database,
153
+		IOAuthProtocolHelper $oauthProtocolHelper,
154
+		SiteConfiguration $siteConfiguration
155
+	) {
156
+		$this->user = $user;
157
+		$this->database = $database;
158
+		$this->oauthProtocolHelper = $oauthProtocolHelper;
159
+
160
+		$this->linked = null;
161
+		$this->partiallyLinked = null;
162
+		$this->siteConfiguration = $siteConfiguration;
163
+
164
+		self::prepareTokenCountStatement($database);
165
+		$this->getTokenStatement = $this->database->prepare('SELECT * FROM oauthtoken WHERE user = :user AND type = :type');
166
+	}
167
+
168
+	/**
169
+	 * Determines if the user is fully connected to OAuth.
170
+	 *
171
+	 * @return bool
172
+	 */
173
+	public function isFullyLinked()
174
+	{
175
+		if ($this->linked === null) {
176
+			$this->linked = self::userIsFullyLinked($this->user, $this->database);
177
+		}
178
+
179
+		return $this->linked;
180
+	}
181
+
182
+	/**
183
+	 * Attempts to figure out if a user is partially linked to OAuth, and therefore needs to complete the OAuth
184
+	 * procedure before configuring.
185
+	 * @return bool
186
+	 */
187
+	public function isPartiallyLinked()
188
+	{
189
+		if ($this->partiallyLinked === null) {
190
+			$this->partiallyLinked = self::userIsPartiallyLinked($this->user, $this->database);
191
+		}
192
+
193
+		return $this->partiallyLinked;
194
+	}
195
+
196
+	public function canCreateAccount() {
197
+		return $this->isFullyLinked()
198
+			&& $this->getIdentity(true)->getGrantBasic()
199
+			&& $this->getIdentity(true)->getGrantHighVolume()
200
+			&& $this->getIdentity(true)->getGrantCreateAccount();
201
+	}
202
+
203
+	public function canWelcome() {
204
+		return $this->isFullyLinked()
205
+			&& $this->getIdentity(true)->getGrantBasic()
206
+			&& $this->getIdentity(true)->getGrantHighVolume()
207
+			&& $this->getIdentity(true)->getGrantCreateEditMovePage();
208
+	}
209
+
210
+	/**
211
+	 * @throws OAuthException
212
+	 */
213
+	public function refreshIdentity()
214
+	{
215
+		$this->loadIdentity();
216
+
217
+		if ($this->identity === null) {
218
+			$this->identity = new OAuthIdentity();
219
+			$this->identity->setUserId($this->user->getId());
220
+			$this->identity->setDatabase($this->database);
221
+		}
222
+
223
+		$token = $this->loadAccessToken();
224
+
225
+		$rawTicket = $this->oauthProtocolHelper->getIdentityTicket($token->getToken(), $token->getSecret());
226
+
227
+		$this->identity->populate($rawTicket);
228
+
229
+		if (!$this->identityIsValid()) {
230
+			throw new OAuthException('Identity ticket is not valid!');
231
+		}
232
+
233
+		$this->identity->save();
234
+
235
+		$this->user->setOnWikiName($this->identity->getUsername());
236
+		$this->user->save();
237
+	}
238
+
239
+	public function getRequestToken()
240
+	{
241
+		$token = $this->oauthProtocolHelper->getRequestToken();
242
+
243
+		$this->partiallyLinked = true;
244
+		$this->linked = false;
245
+
246
+		$this->database
247
+			->prepare('DELETE FROM oauthtoken WHERE user = :user AND type = :type')
248
+			->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_REQUEST));
249
+
250
+		$this->database
251
+			->prepare('INSERT INTO oauthtoken (user, type, token, secret, expiry) VALUES (:user, :type, :token, :secret, DATE_ADD(NOW(), INTERVAL 1 DAY))')
252
+			->execute(array(
253
+				':user'   => $this->user->getId(),
254
+				':type'   => self::TOKEN_REQUEST,
255
+				':token'  => $token->key,
256
+				':secret' => $token->secret,
257
+			));
258
+
259
+		return $this->oauthProtocolHelper->getAuthoriseUrl($token->key);
260
+	}
261
+
262
+	public function completeHandshake($verificationToken)
263
+	{
264
+		$this->getTokenStatement->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_REQUEST));
265
+
266
+		/** @var OAuthToken $token */
267
+		$token = $this->getTokenStatement->fetchObject(OAuthToken::class);
268
+		$this->getTokenStatement->closeCursor();
269
+
270
+		if ($token === false) {
271
+			throw new ApplicationLogicException('Cannot find request token');
272
+		}
273
+
274
+		$token->setDatabase($this->database);
275
+
276
+		$accessToken = $this->oauthProtocolHelper->callbackCompleted($token->getToken(), $token->getSecret(),
277
+			$verificationToken);
278
+
279
+		$clearStatement = $this->database->prepare('DELETE FROM oauthtoken WHERE user = :u AND type = :t');
280
+		$clearStatement->execute(array(':u' => $this->user->getId(), ':t' => self::TOKEN_ACCESS));
281
+
282
+		$token->setToken($accessToken->key);
283
+		$token->setSecret($accessToken->secret);
284
+		$token->setType(self::TOKEN_ACCESS);
285
+		$token->setExpiry(null);
286
+		$token->save();
287
+
288
+		$this->partiallyLinked = false;
289
+		$this->linked = true;
290
+
291
+		$this->refreshIdentity();
292
+	}
293
+
294
+	public function detach()
295
+	{
296
+		$this->loadIdentity();
297
+
298
+		$this->identity->delete();
299
+		$statement = $this->database->prepare('DELETE FROM oauthtoken WHERE user = :user');
300
+		$statement->execute(array(':user' => $this->user->getId()));
301
+
302
+		$this->identity = null;
303
+		$this->linked = false;
304
+		$this->partiallyLinked = false;
305
+	}
306
+
307
+	/**
308
+	 * @param bool $expiredOk
309
+	 *
310
+	 * @return OAuthIdentity
311
+	 * @throws OAuthException
312
+	 */
313
+	public function getIdentity($expiredOk = false)
314
+	{
315
+		$this->loadIdentity();
316
+
317
+		if (!$this->identityIsValid($expiredOk)) {
318
+			throw new OAuthException('Stored identity is not valid.');
319
+		}
320
+
321
+		return $this->identity;
322
+	}
323
+
324
+	public function doApiCall($params, $method)
325
+	{
326
+		// Ensure we're logged in
327
+		$params['assert'] = 'user';
328
+
329
+		$token = $this->loadAccessToken();
330
+		return $this->oauthProtocolHelper->apiCall($params, $token->getToken(), $token->getSecret(), $method);
331
+	}
332
+
333
+	/**
334
+	 * @param bool $expiredOk
335
+	 *
336
+	 * @return bool
337
+	 */
338
+	private function identityIsValid($expiredOk = false)
339
+	{
340
+		$this->loadIdentity();
341
+
342
+		if ($this->identity === null) {
343
+			return false;
344
+		}
345
+
346
+		if ($this->identity->getIssuedAtTime() === false
347
+			|| $this->identity->getExpirationTime() === false
348
+			|| $this->identity->getAudience() === false
349
+			|| $this->identity->getIssuer() === false
350
+		) {
351
+			// this isn't populated properly.
352
+			return false;
353
+		}
354
+
355
+		$issue = DateTimeImmutable::createFromFormat("U", $this->identity->getIssuedAtTime());
356
+		$now = new DateTimeImmutable();
357
+
358
+		if ($issue > $now) {
359
+			// wat.
360
+			return false;
361
+		}
362
+
363
+		if ($this->identityExpired() && !$expiredOk) {
364
+			// soz.
365
+			return false;
366
+		}
367
+
368
+		if ($this->identity->getAudience() !== $this->siteConfiguration->getOAuthConsumerToken()) {
369
+			// token not issued for us
370
+			return false;
371
+		}
372
+
373
+		if ($this->identity->getIssuer() !== $this->siteConfiguration->getOauthMediaWikiCanonicalServer()) {
374
+			// token not issued by the right person
375
+			return false;
376
+		}
377
+
378
+		// can't find a reason to not trust it
379
+		return true;
380
+	}
381
+
382
+	/**
383
+	 * @return bool
384
+	 */
385
+	public function identityExpired()
386
+	{
387
+		// allowed max age
388
+		$gracePeriod = $this->siteConfiguration->getOauthIdentityGraceTime();
389
+
390
+		$expiry = DateTimeImmutable::createFromFormat("U", $this->identity->getExpirationTime());
391
+		$graceExpiry = $expiry->modify($gracePeriod);
392
+		$now = new DateTimeImmutable();
393
+
394
+		return $graceExpiry < $now;
395
+	}
396
+
397
+	/**
398
+	 * Loads the OAuth identity from the database for the current user.
399
+	 */
400
+	private function loadIdentity()
401
+	{
402
+		if ($this->identityLoaded) {
403
+			return;
404
+		}
405
+
406
+		$statement = $this->database->prepare('SELECT * FROM oauthidentity WHERE user = :user');
407
+		$statement->execute(array(':user' => $this->user->getId()));
408
+		/** @var OAuthIdentity $obj */
409
+		$obj = $statement->fetchObject(OAuthIdentity::class);
410
+
411
+		if ($obj === false) {
412
+			// failed to load identity.
413
+			$this->identityLoaded = true;
414
+			$this->identity = null;
415
+
416
+			return;
417
+		}
418
+
419
+		$obj->setDatabase($this->database);
420
+		$this->identityLoaded = true;
421
+		$this->identity = $obj;
422
+	}
423
+
424
+	/**
425
+	 * @return OAuthToken
426
+	 * @throws OAuthException
427
+	 */
428
+	private function loadAccessToken()
429
+	{
430
+		if (!$this->accessTokenLoaded) {
431
+			$this->getTokenStatement->execute(array(':user' => $this->user->getId(), ':type' => self::TOKEN_ACCESS));
432
+			/** @var OAuthToken $token */
433
+			$token = $this->getTokenStatement->fetchObject(OAuthToken::class);
434
+			$this->getTokenStatement->closeCursor();
435
+
436
+			if ($token === false) {
437
+				throw new OAuthException('Access token not found!');
438
+			}
439
+
440
+			$this->accessToken = $token;
441
+			$this->accessTokenLoaded = true;
442
+		}
443
+
444
+		return $this->accessToken;
445
+	}
446 446
 }
Please login to merge, or discard this patch.
Braces   +4 added lines, -2 removed lines patch added patch discarded remove patch
@@ -193,14 +193,16 @@
 block discarded – undo
193 193
         return $this->partiallyLinked;
194 194
     }
195 195
 
196
-    public function canCreateAccount() {
196
+    public function canCreateAccount()
197
+    {
197 198
         return $this->isFullyLinked()
198 199
             && $this->getIdentity(true)->getGrantBasic()
199 200
             && $this->getIdentity(true)->getGrantHighVolume()
200 201
             && $this->getIdentity(true)->getGrantCreateAccount();
201 202
     }
202 203
 
203
-    public function canWelcome() {
204
+    public function canWelcome()
205
+    {
204 206
         return $this->isFullyLinked()
205 207
             && $this->getIdentity(true)->getGrantBasic()
206 208
             && $this->getIdentity(true)->getGrantHighVolume()
Please login to merge, or discard this patch.
includes/Tasks/InternalPageBase.php 1 patch
Indentation   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -23,228 +23,228 @@
 block discarded – undo
23 23
 
24 24
 abstract class InternalPageBase extends PageBase
25 25
 {
26
-    use NavigationMenuAccessControl;
27
-
28
-    /** @var IdentificationVerifier */
29
-    private $identificationVerifier;
30
-    /** @var ITypeAheadHelper */
31
-    private $typeAheadHelper;
32
-    /** @var SecurityManager */
33
-    private $securityManager;
34
-    /** @var IBlacklistHelper */
35
-    private $blacklistHelper;
36
-
37
-    /**
38
-     * @return ITypeAheadHelper
39
-     */
40
-    public function getTypeAheadHelper()
41
-    {
42
-        return $this->typeAheadHelper;
43
-    }
44
-
45
-    /**
46
-     * Sets up the internal IdentificationVerifier instance.  Intended to be called from WebStart::setupHelpers().
47
-     *
48
-     * @param IdentificationVerifier $identificationVerifier
49
-     *
50
-     * @return void
51
-     */
52
-    public function setIdentificationVerifier(IdentificationVerifier $identificationVerifier)
53
-    {
54
-        $this->identificationVerifier = $identificationVerifier;
55
-    }
56
-
57
-    /**
58
-     * @param ITypeAheadHelper $typeAheadHelper
59
-     */
60
-    public function setTypeAheadHelper(ITypeAheadHelper $typeAheadHelper)
61
-    {
62
-        $this->typeAheadHelper = $typeAheadHelper;
63
-    }
64
-
65
-    /**
66
-     * Runs the page code
67
-     *
68
-     * @throws Exception
69
-     * @category Security-Critical
70
-     */
71
-    final public function execute()
72
-    {
73
-        if ($this->getRouteName() === null) {
74
-            throw new Exception("Request is unrouted.");
75
-        }
76
-
77
-        if ($this->getSiteConfiguration() === null) {
78
-            throw new Exception("Page has no configuration!");
79
-        }
80
-
81
-        $this->setupPage();
82
-
83
-        $this->touchUserLastActive();
84
-
85
-        $currentUser = User::getCurrent($this->getDatabase());
86
-
87
-        // Hey, this is also a security barrier, in addition to the below. Separated out for readability.
88
-        if (!$this->isProtectedPage()) {
89
-            // This page is /not/ a protected page, as such we can just run it.
90
-            $this->runPage();
91
-
92
-            return;
93
-        }
94
-
95
-        // Security barrier.
96
-        //
97
-        // This code essentially doesn't care if the user is logged in or not, as the security manager hides all that
98
-        // away for us
99
-        $securityResult = $this->getSecurityManager()->allows(get_called_class(), $this->getRouteName(), $currentUser);
100
-        if ($securityResult === SecurityManager::ALLOWED) {
101
-            // We're allowed to run the page, so let's run it.
102
-            $this->runPage();
103
-        }
104
-        else {
105
-            $this->handleAccessDenied($securityResult);
106
-
107
-            // Send the headers
108
-            $this->sendResponseHeaders();
109
-        }
110
-    }
111
-
112
-    /**
113
-     * Performs final tasks needed before rendering the page.
114
-     */
115
-    final public function finalisePage()
116
-    {
117
-        parent::finalisePage();
118
-
119
-        $database = $this->getDatabase();
120
-        $currentUser = User::getCurrent($database);
121
-
122
-        if ($this->barrierTest('viewSiteNotice', User::getCurrent($database), 'GlobalInfo')) {
123
-            $siteNoticeText = SiteNotice::get($this->getDatabase());
124
-            $this->assign('siteNoticeText', $siteNoticeText);
125
-        }
126
-
127
-        if ($this->barrierTest('viewOnlineUsers', User::getCurrent($database), 'GlobalInfo')) {
128
-            $sql = 'SELECT * FROM user WHERE lastactive > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE);';
129
-            $statement = $database->query($sql);
130
-            $activeUsers = $statement->fetchAll(PDO::FETCH_CLASS, User::class);
131
-            $this->assign('onlineusers', $activeUsers);
132
-        }
133
-
134
-        $this->setupNavMenuAccess($currentUser);
135
-    }
136
-
137
-    /**
138
-     * Configures whether the page respects roles or not. You probably want this to return true.
139
-     *
140
-     * Set to false for public pages. You probably want this to return true.
141
-     *
142
-     * This defaults to true unless you explicitly set it to false. Setting it to false means anybody can do anything
143
-     * on this page, so you probably want this to return true.
144
-     *
145
-     * @return bool
146
-     * @category Security-Critical
147
-     */
148
-    protected function isProtectedPage()
149
-    {
150
-        return true;
151
-    }
152
-
153
-    protected function handleAccessDenied($denyReason)
154
-    {
155
-        $currentUser = User::getCurrent($this->getDatabase());
156
-
157
-        // Not allowed to access this resource.
158
-        // Firstly, let's check if we're even logged in.
159
-        if ($currentUser->isCommunityUser()) {
160
-            // Not logged in, redirect to login page
161
-            WebRequest::setPostLoginRedirect();
162
-            $this->redirect("login");
163
-
164
-            return;
165
-        }
166
-        else {
167
-            // Decide whether this was a rights failure, or an identification failure.
168
-
169
-            if ($denyReason === SecurityManager::ERROR_NOT_IDENTIFIED) {
170
-                // Not identified
171
-                throw new NotIdentifiedException($this->getSecurityManager());
172
-            }
173
-            elseif ($denyReason === SecurityManager::ERROR_DENIED) {
174
-                // Nope, plain old access denied
175
-                throw new AccessDeniedException($this->getSecurityManager());
176
-            }
177
-            else {
178
-                throw new Exception('Unknown response from security manager.');
179
-            }
180
-        }
181
-    }
182
-
183
-    /**
184
-     * Tests the security barrier for a specified action.
185
-     *
186
-     * Don't use within templates
187
-     *
188
-     * @param string      $action
189
-     *
190
-     * @param User        $user
191
-     * @param null|string $pageName
192
-     *
193
-     * @return bool
194
-     * @category Security-Critical
195
-     */
196
-    final public function barrierTest($action, User $user, $pageName = null)
197
-    {
198
-        $page = get_called_class();
199
-        if ($pageName !== null) {
200
-            $page = $pageName;
201
-        }
202
-
203
-        $securityResult = $this->getSecurityManager()->allows($page, $action, $user);
204
-
205
-        return $securityResult === SecurityManager::ALLOWED;
206
-    }
207
-
208
-    /**
209
-     * Updates the lastactive timestamp
210
-     */
211
-    private function touchUserLastActive()
212
-    {
213
-        if (WebRequest::getSessionUserId() !== null) {
214
-            $query = 'UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;';
215
-            $this->getDatabase()->prepare($query)->execute(array(":id" => WebRequest::getSessionUserId()));
216
-        }
217
-    }
218
-
219
-    /**
220
-     * @return SecurityManager
221
-     */
222
-    public function getSecurityManager()
223
-    {
224
-        return $this->securityManager;
225
-    }
226
-
227
-    /**
228
-     * @param SecurityManager $securityManager
229
-     */
230
-    public function setSecurityManager(SecurityManager $securityManager)
231
-    {
232
-        $this->securityManager = $securityManager;
233
-    }
234
-
235
-    /**
236
-     * @return IBlacklistHelper
237
-     */
238
-    public function getBlacklistHelper()
239
-    {
240
-        return $this->blacklistHelper;
241
-    }
242
-
243
-    /**
244
-     * @param IBlacklistHelper $blacklistHelper
245
-     */
246
-    public function setBlacklistHelper(IBlacklistHelper $blacklistHelper)
247
-    {
248
-        $this->blacklistHelper = $blacklistHelper;
249
-    }
26
+	use NavigationMenuAccessControl;
27
+
28
+	/** @var IdentificationVerifier */
29
+	private $identificationVerifier;
30
+	/** @var ITypeAheadHelper */
31
+	private $typeAheadHelper;
32
+	/** @var SecurityManager */
33
+	private $securityManager;
34
+	/** @var IBlacklistHelper */
35
+	private $blacklistHelper;
36
+
37
+	/**
38
+	 * @return ITypeAheadHelper
39
+	 */
40
+	public function getTypeAheadHelper()
41
+	{
42
+		return $this->typeAheadHelper;
43
+	}
44
+
45
+	/**
46
+	 * Sets up the internal IdentificationVerifier instance.  Intended to be called from WebStart::setupHelpers().
47
+	 *
48
+	 * @param IdentificationVerifier $identificationVerifier
49
+	 *
50
+	 * @return void
51
+	 */
52
+	public function setIdentificationVerifier(IdentificationVerifier $identificationVerifier)
53
+	{
54
+		$this->identificationVerifier = $identificationVerifier;
55
+	}
56
+
57
+	/**
58
+	 * @param ITypeAheadHelper $typeAheadHelper
59
+	 */
60
+	public function setTypeAheadHelper(ITypeAheadHelper $typeAheadHelper)
61
+	{
62
+		$this->typeAheadHelper = $typeAheadHelper;
63
+	}
64
+
65
+	/**
66
+	 * Runs the page code
67
+	 *
68
+	 * @throws Exception
69
+	 * @category Security-Critical
70
+	 */
71
+	final public function execute()
72
+	{
73
+		if ($this->getRouteName() === null) {
74
+			throw new Exception("Request is unrouted.");
75
+		}
76
+
77
+		if ($this->getSiteConfiguration() === null) {
78
+			throw new Exception("Page has no configuration!");
79
+		}
80
+
81
+		$this->setupPage();
82
+
83
+		$this->touchUserLastActive();
84
+
85
+		$currentUser = User::getCurrent($this->getDatabase());
86
+
87
+		// Hey, this is also a security barrier, in addition to the below. Separated out for readability.
88
+		if (!$this->isProtectedPage()) {
89
+			// This page is /not/ a protected page, as such we can just run it.
90
+			$this->runPage();
91
+
92
+			return;
93
+		}
94
+
95
+		// Security barrier.
96
+		//
97
+		// This code essentially doesn't care if the user is logged in or not, as the security manager hides all that
98
+		// away for us
99
+		$securityResult = $this->getSecurityManager()->allows(get_called_class(), $this->getRouteName(), $currentUser);
100
+		if ($securityResult === SecurityManager::ALLOWED) {
101
+			// We're allowed to run the page, so let's run it.
102
+			$this->runPage();
103
+		}
104
+		else {
105
+			$this->handleAccessDenied($securityResult);
106
+
107
+			// Send the headers
108
+			$this->sendResponseHeaders();
109
+		}
110
+	}
111
+
112
+	/**
113
+	 * Performs final tasks needed before rendering the page.
114
+	 */
115
+	final public function finalisePage()
116
+	{
117
+		parent::finalisePage();
118
+
119
+		$database = $this->getDatabase();
120
+		$currentUser = User::getCurrent($database);
121
+
122
+		if ($this->barrierTest('viewSiteNotice', User::getCurrent($database), 'GlobalInfo')) {
123
+			$siteNoticeText = SiteNotice::get($this->getDatabase());
124
+			$this->assign('siteNoticeText', $siteNoticeText);
125
+		}
126
+
127
+		if ($this->barrierTest('viewOnlineUsers', User::getCurrent($database), 'GlobalInfo')) {
128
+			$sql = 'SELECT * FROM user WHERE lastactive > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE);';
129
+			$statement = $database->query($sql);
130
+			$activeUsers = $statement->fetchAll(PDO::FETCH_CLASS, User::class);
131
+			$this->assign('onlineusers', $activeUsers);
132
+		}
133
+
134
+		$this->setupNavMenuAccess($currentUser);
135
+	}
136
+
137
+	/**
138
+	 * Configures whether the page respects roles or not. You probably want this to return true.
139
+	 *
140
+	 * Set to false for public pages. You probably want this to return true.
141
+	 *
142
+	 * This defaults to true unless you explicitly set it to false. Setting it to false means anybody can do anything
143
+	 * on this page, so you probably want this to return true.
144
+	 *
145
+	 * @return bool
146
+	 * @category Security-Critical
147
+	 */
148
+	protected function isProtectedPage()
149
+	{
150
+		return true;
151
+	}
152
+
153
+	protected function handleAccessDenied($denyReason)
154
+	{
155
+		$currentUser = User::getCurrent($this->getDatabase());
156
+
157
+		// Not allowed to access this resource.
158
+		// Firstly, let's check if we're even logged in.
159
+		if ($currentUser->isCommunityUser()) {
160
+			// Not logged in, redirect to login page
161
+			WebRequest::setPostLoginRedirect();
162
+			$this->redirect("login");
163
+
164
+			return;
165
+		}
166
+		else {
167
+			// Decide whether this was a rights failure, or an identification failure.
168
+
169
+			if ($denyReason === SecurityManager::ERROR_NOT_IDENTIFIED) {
170
+				// Not identified
171
+				throw new NotIdentifiedException($this->getSecurityManager());
172
+			}
173
+			elseif ($denyReason === SecurityManager::ERROR_DENIED) {
174
+				// Nope, plain old access denied
175
+				throw new AccessDeniedException($this->getSecurityManager());
176
+			}
177
+			else {
178
+				throw new Exception('Unknown response from security manager.');
179
+			}
180
+		}
181
+	}
182
+
183
+	/**
184
+	 * Tests the security barrier for a specified action.
185
+	 *
186
+	 * Don't use within templates
187
+	 *
188
+	 * @param string      $action
189
+	 *
190
+	 * @param User        $user
191
+	 * @param null|string $pageName
192
+	 *
193
+	 * @return bool
194
+	 * @category Security-Critical
195
+	 */
196
+	final public function barrierTest($action, User $user, $pageName = null)
197
+	{
198
+		$page = get_called_class();
199
+		if ($pageName !== null) {
200
+			$page = $pageName;
201
+		}
202
+
203
+		$securityResult = $this->getSecurityManager()->allows($page, $action, $user);
204
+
205
+		return $securityResult === SecurityManager::ALLOWED;
206
+	}
207
+
208
+	/**
209
+	 * Updates the lastactive timestamp
210
+	 */
211
+	private function touchUserLastActive()
212
+	{
213
+		if (WebRequest::getSessionUserId() !== null) {
214
+			$query = 'UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;';
215
+			$this->getDatabase()->prepare($query)->execute(array(":id" => WebRequest::getSessionUserId()));
216
+		}
217
+	}
218
+
219
+	/**
220
+	 * @return SecurityManager
221
+	 */
222
+	public function getSecurityManager()
223
+	{
224
+		return $this->securityManager;
225
+	}
226
+
227
+	/**
228
+	 * @param SecurityManager $securityManager
229
+	 */
230
+	public function setSecurityManager(SecurityManager $securityManager)
231
+	{
232
+		$this->securityManager = $securityManager;
233
+	}
234
+
235
+	/**
236
+	 * @return IBlacklistHelper
237
+	 */
238
+	public function getBlacklistHelper()
239
+	{
240
+		return $this->blacklistHelper;
241
+	}
242
+
243
+	/**
244
+	 * @param IBlacklistHelper $blacklistHelper
245
+	 */
246
+	public function setBlacklistHelper(IBlacklistHelper $blacklistHelper)
247
+	{
248
+		$this->blacklistHelper = $blacklistHelper;
249
+	}
250 250
 }
Please login to merge, or discard this patch.
includes/ConsoleTasks/RunJobQueueTask.php 3 patches
Indentation   +112 added lines, -112 removed lines patch added patch discarded remove patch
@@ -22,116 +22,116 @@
 block discarded – undo
22 22
 
23 23
 class RunJobQueueTask extends ConsoleTaskBase
24 24
 {
25
-    private $taskList = array(
26
-        WelcomeUserTask::class,
27
-        BotCreationTask::class,
28
-        UserCreationTask::class
29
-    );
30
-
31
-    public function execute()
32
-    {
33
-        $database = $this->getDatabase();
34
-
35
-        // ensure we're running inside a tx here.
36
-        if (!$database->hasActiveTransaction()) {
37
-            $database->beginTransaction();
38
-        }
39
-
40
-        $sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
41
-        $statement = $database->prepare($sql);
42
-        $statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
43
-        /** @var JobQueue[] $queuedJobs */
44
-        $queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
45
-
46
-        // mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
47
-        // We'll re-lock the row when we get to it.
48
-        foreach ($queuedJobs as $job) {
49
-            $job->setDatabase($database);
50
-            $job->setStatus(JobQueue::STATUS_WAITING);
51
-            $job->setError(null);
52
-            $job->setAcknowledged(null);
53
-            $job->save();
54
-        }
55
-
56
-        $database->commit();
57
-
58
-        set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
59
-
60
-        foreach ($queuedJobs as $job) {
61
-            try {
62
-                $database->beginTransaction();
63
-                $job->setStatus(JobQueue::STATUS_RUNNING);
64
-                $job->save();
65
-                $database->commit();
66
-
67
-                $database->beginTransaction();
68
-
69
-                // re-lock the job
70
-                $job->setStatus(JobQueue::STATUS_RUNNING);
71
-                $job->save();
72
-
73
-                // validate we're allowed to run the requested task (whitelist)
74
-                if (!in_array($job->getTask(), $this->taskList)) {
75
-                    throw new ApplicationLogicException('Job task not registered');
76
-                }
77
-
78
-                // Create a task.
79
-                $taskName = $job->getTask();
80
-
81
-                if(!class_exists($taskName)) {
82
-                    throw new ApplicationLogicException('Job task does not exist');
83
-                }
84
-
85
-                /** @var BackgroundTaskBase $task */
86
-                $task = new $taskName;
87
-
88
-                $this->setupTask($task, $job);
89
-                $task->run();
90
-            }
91
-            catch (Exception $ex) {
92
-                $database->rollBack();
93
-                $database->beginTransaction();
94
-
95
-                /** @var JobQueue $job */
96
-                $job = JobQueue::getById($job->getId(), $database);
97
-                $job->setDatabase($database);
98
-                $job->setStatus(JobQueue::STATUS_FAILED);
99
-                $job->setError($ex->getMessage());
100
-                $job->setAcknowledged(0);
101
-                $job->save();
102
-
103
-                /** @var Request $request */
104
-                $request = Request::getById($job->getRequest(), $database);
105
-                if ($request === false) {
106
-                    $request = null;
107
-                }
108
-
109
-                Logger::backgroundJobIssue($this->getDatabase(), $job);
110
-
111
-                $database->commit();
112
-            }
113
-            finally {
114
-                $database->commit();
115
-            }
116
-        }
117
-    }
118
-
119
-    /**
120
-     * @param BackgroundTaskBase $task
121
-     * @param JobQueue           $job
122
-     */
123
-    private function setupTask(BackgroundTaskBase $task, JobQueue $job)
124
-    {
125
-        $task->setJob($job);
126
-        $task->setDatabase($this->getDatabase());
127
-        $task->setHttpHelper($this->getHttpHelper());
128
-        $task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
129
-        $task->setEmailHelper($this->getEmailHelper());
130
-        $task->setSiteConfiguration($this->getSiteConfiguration());
131
-        $task->setNotificationHelper($this->getNotificationHelper());
132
-    }
133
-
134
-    public static function errorHandler($errno, $errstr, $errfile, $errline) {
135
-        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
136
-    }
25
+	private $taskList = array(
26
+		WelcomeUserTask::class,
27
+		BotCreationTask::class,
28
+		UserCreationTask::class
29
+	);
30
+
31
+	public function execute()
32
+	{
33
+		$database = $this->getDatabase();
34
+
35
+		// ensure we're running inside a tx here.
36
+		if (!$database->hasActiveTransaction()) {
37
+			$database->beginTransaction();
38
+		}
39
+
40
+		$sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
41
+		$statement = $database->prepare($sql);
42
+		$statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
43
+		/** @var JobQueue[] $queuedJobs */
44
+		$queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
45
+
46
+		// mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
47
+		// We'll re-lock the row when we get to it.
48
+		foreach ($queuedJobs as $job) {
49
+			$job->setDatabase($database);
50
+			$job->setStatus(JobQueue::STATUS_WAITING);
51
+			$job->setError(null);
52
+			$job->setAcknowledged(null);
53
+			$job->save();
54
+		}
55
+
56
+		$database->commit();
57
+
58
+		set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
59
+
60
+		foreach ($queuedJobs as $job) {
61
+			try {
62
+				$database->beginTransaction();
63
+				$job->setStatus(JobQueue::STATUS_RUNNING);
64
+				$job->save();
65
+				$database->commit();
66
+
67
+				$database->beginTransaction();
68
+
69
+				// re-lock the job
70
+				$job->setStatus(JobQueue::STATUS_RUNNING);
71
+				$job->save();
72
+
73
+				// validate we're allowed to run the requested task (whitelist)
74
+				if (!in_array($job->getTask(), $this->taskList)) {
75
+					throw new ApplicationLogicException('Job task not registered');
76
+				}
77
+
78
+				// Create a task.
79
+				$taskName = $job->getTask();
80
+
81
+				if(!class_exists($taskName)) {
82
+					throw new ApplicationLogicException('Job task does not exist');
83
+				}
84
+
85
+				/** @var BackgroundTaskBase $task */
86
+				$task = new $taskName;
87
+
88
+				$this->setupTask($task, $job);
89
+				$task->run();
90
+			}
91
+			catch (Exception $ex) {
92
+				$database->rollBack();
93
+				$database->beginTransaction();
94
+
95
+				/** @var JobQueue $job */
96
+				$job = JobQueue::getById($job->getId(), $database);
97
+				$job->setDatabase($database);
98
+				$job->setStatus(JobQueue::STATUS_FAILED);
99
+				$job->setError($ex->getMessage());
100
+				$job->setAcknowledged(0);
101
+				$job->save();
102
+
103
+				/** @var Request $request */
104
+				$request = Request::getById($job->getRequest(), $database);
105
+				if ($request === false) {
106
+					$request = null;
107
+				}
108
+
109
+				Logger::backgroundJobIssue($this->getDatabase(), $job);
110
+
111
+				$database->commit();
112
+			}
113
+			finally {
114
+				$database->commit();
115
+			}
116
+		}
117
+	}
118
+
119
+	/**
120
+	 * @param BackgroundTaskBase $task
121
+	 * @param JobQueue           $job
122
+	 */
123
+	private function setupTask(BackgroundTaskBase $task, JobQueue $job)
124
+	{
125
+		$task->setJob($job);
126
+		$task->setDatabase($this->getDatabase());
127
+		$task->setHttpHelper($this->getHttpHelper());
128
+		$task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
129
+		$task->setEmailHelper($this->getEmailHelper());
130
+		$task->setSiteConfiguration($this->getSiteConfiguration());
131
+		$task->setNotificationHelper($this->getNotificationHelper());
132
+	}
133
+
134
+	public static function errorHandler($errno, $errstr, $errfile, $errline) {
135
+		throw new Exception($errfile . "@" . $errline . ": " . $errstr);
136
+	}
137 137
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
                 // Create a task.
79 79
                 $taskName = $job->getTask();
80 80
 
81
-                if(!class_exists($taskName)) {
81
+                if (!class_exists($taskName)) {
82 82
                     throw new ApplicationLogicException('Job task does not exist');
83 83
                 }
84 84
 
@@ -132,6 +132,6 @@  discard block
 block discarded – undo
132 132
     }
133 133
 
134 134
     public static function errorHandler($errno, $errstr, $errfile, $errline) {
135
-        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
135
+        throw new Exception($errfile."@".$errline.": ".$errstr);
136 136
     }
137 137
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -131,7 +131,8 @@
 block discarded – undo
131 131
         $task->setNotificationHelper($this->getNotificationHelper());
132 132
     }
133 133
 
134
-    public static function errorHandler($errno, $errstr, $errfile, $errline) {
134
+    public static function errorHandler($errno, $errstr, $errfile, $errline)
135
+    {
135 136
         throw new Exception($errfile . "@" . $errline . ": " . $errstr);
136 137
     }
137 138
 }
Please login to merge, or discard this patch.