stwalkerster /
waca
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * User data object |
||
| 5 | */ |
||
| 6 | class User extends DataObject |
||
| 7 | { |
||
| 8 | private $username; |
||
| 9 | private $email; |
||
| 10 | private $password; |
||
| 11 | private $status = "New"; |
||
| 12 | private $onwikiname = "##OAUTH##"; |
||
| 13 | private $welcome_sig = ""; |
||
| 14 | private $lastactive = "0000-00-00 00:00:00"; |
||
| 15 | private $forcelogout = 0; |
||
| 16 | private $checkuser = 0; |
||
| 17 | private $identified = 0; |
||
| 18 | private $welcome_template = 0; |
||
| 19 | private $abortpref = 0; |
||
| 20 | private $confirmationdiff = 0; |
||
| 21 | private $emailsig = ""; |
||
| 22 | private $oauthrequesttoken = null; |
||
| 23 | private $oauthrequestsecret = null; |
||
| 24 | private $oauthaccesstoken = null; |
||
| 25 | private $oauthaccesssecret = null; |
||
| 26 | private $oauthidentitycache = null; |
||
| 27 | |||
| 28 | // cache variable of the current user - it's never going to change in the middle of a request. |
||
| 29 | private static $currentUser; |
||
| 30 | |||
| 31 | private $identityCache = null; |
||
| 32 | |||
| 33 | private $isCheckuserCache = null; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Summary of getCurrent |
||
| 37 | * @param PdoDatabase $database |
||
| 38 | * @return User The currently logged in user, or an anonymous coward with userid -1. |
||
| 39 | */ |
||
| 40 | public static function getCurrent(PdoDatabase $database = null) |
||
| 41 | { |
||
| 42 | if ($database === null) { |
||
| 43 | $database = gGetDb(); |
||
| 44 | } |
||
| 45 | |||
| 46 | if (self::$currentUser === null) { |
||
| 47 | if (isset($_SESSION['userID'])) { |
||
| 48 | self::$currentUser = self::getById($_SESSION['userID'], $database); |
||
| 49 | } |
||
| 50 | else { |
||
| 51 | $anonymousCoward = new CommunityUser(); |
||
| 52 | |||
| 53 | self::$currentUser = $anonymousCoward; |
||
| 54 | } |
||
| 55 | } |
||
| 56 | |||
| 57 | |||
| 58 | return self::$currentUser; |
||
| 59 | } |
||
| 60 | |||
| 61 | public static function getById($id, PdoDatabase $database) |
||
| 62 | { |
||
| 63 | if ($id == "-1") { |
||
| 64 | return new CommunityUser(); |
||
| 65 | } |
||
| 66 | |||
| 67 | return parent::getById($id, $database); |
||
| 68 | } |
||
| 69 | |||
| 70 | public static function getCommunity() |
||
| 71 | { |
||
| 72 | return new CommunityUser(); |
||
| 73 | } |
||
| 74 | |||
| 75 | public static function getByUsername($username, PdoDatabase $database) |
||
| 76 | { |
||
| 77 | global $communityUsername; |
||
| 78 | if ($username == $communityUsername) { |
||
| 79 | return new CommunityUser(); |
||
| 80 | } |
||
| 81 | |||
| 82 | $statement = $database->prepare("SELECT * FROM user WHERE username = :id LIMIT 1;"); |
||
| 83 | $statement->bindValue(":id", $username); |
||
| 84 | |||
| 85 | $statement->execute(); |
||
| 86 | |||
| 87 | $resultObject = $statement->fetchObject(get_called_class()); |
||
| 88 | |||
| 89 | if ($resultObject != false) { |
||
| 90 | $resultObject->isNew = false; |
||
| 91 | $resultObject->setDatabase($database); |
||
| 92 | } |
||
| 93 | |||
| 94 | return $resultObject; |
||
| 95 | } |
||
| 96 | |||
| 97 | /** |
||
| 98 | * Gets a user by their on-wiki username. |
||
| 99 | * |
||
| 100 | * Don't use without asking me first. It's really inefficient in it's current implementation. |
||
| 101 | * We need to restructure the user table again to make this more efficient. |
||
| 102 | * We don't actually store the on-wiki name in the table any more, instead we |
||
| 103 | * are storing JSON in a column (!!). Yep, my fault. Code review is an awesome thing. |
||
| 104 | * -- stw 2015-10-20 |
||
| 105 | * @param string $username |
||
| 106 | * @param PdoDatabase $database |
||
| 107 | * @return User|false |
||
| 108 | */ |
||
| 109 | public static function getByOnWikiUsername($username, PdoDatabase $database) |
||
| 110 | { |
||
| 111 | // Firstly, try to search by the efficient database lookup. |
||
| 112 | $statement = $database->prepare("SELECT * FROM user WHERE onwikiname = :id LIMIT 1;"); |
||
| 113 | $statement->bindValue(":id", $username); |
||
| 114 | $statement->execute(); |
||
| 115 | |||
| 116 | $resultObject = $statement->fetchObject(get_called_class()); |
||
| 117 | |||
| 118 | if ($resultObject != false) { |
||
| 119 | $resultObject->isNew = false; |
||
| 120 | $resultObject->setDatabase($database); |
||
| 121 | |||
| 122 | return $resultObject; |
||
| 123 | } |
||
| 124 | |||
| 125 | // For active users, the above has failed. Let's do it the hard way. |
||
| 126 | $sqlStatement = "SELECT * FROM user WHERE onwikiname = '##OAUTH##' AND oauthaccesstoken IS NOT NULL;"; |
||
| 127 | $statement = $database->prepare($sqlStatement); |
||
| 128 | $statement->execute(); |
||
| 129 | $resultSet = $statement->fetchAll(PDO::FETCH_CLASS, get_called_class()); |
||
| 130 | |||
| 131 | /** @var User $user */ |
||
| 132 | View Code Duplication | foreach ($resultSet as $user) { |
|
| 133 | // We have to set this before doing OAuth queries. :( |
||
| 134 | $user->isNew = false; |
||
| 135 | $user->setDatabase($database); |
||
| 136 | |||
| 137 | // Using cached data here! |
||
| 138 | if ($user->getOAuthOnWikiName(true) == $username) { |
||
| 139 | // Success. |
||
| 140 | return $user; |
||
| 141 | } |
||
| 142 | } |
||
| 143 | |||
| 144 | // Cached data failed. Let's do it the *REALLY* hard way. |
||
| 145 | View Code Duplication | foreach ($resultSet as $user) { |
|
| 146 | // We have to set this before doing OAuth queries. :( |
||
| 147 | $user->isNew = false; |
||
| 148 | $user->setDatabase($database); |
||
| 149 | |||
| 150 | // Don't use the cached data, but instead query the API. |
||
| 151 | if ($user->getOAuthOnWikiName(false) == $username) { |
||
| 152 | // Success. |
||
| 153 | return $user; |
||
| 154 | } |
||
| 155 | } |
||
| 156 | |||
| 157 | // Nope. Sorry. |
||
| 158 | return false; |
||
| 159 | } |
||
| 160 | |||
| 161 | public static function getByRequestToken($requestToken, PdoDatabase $database) |
||
| 162 | { |
||
| 163 | $statement = $database->prepare("SELECT * FROM user WHERE oauthrequesttoken = :id LIMIT 1;"); |
||
| 164 | $statement->bindValue(":id", $requestToken); |
||
| 165 | |||
| 166 | $statement->execute(); |
||
| 167 | |||
| 168 | $resultObject = $statement->fetchObject(get_called_class()); |
||
| 169 | |||
| 170 | if ($resultObject != false) { |
||
| 171 | $resultObject->isNew = false; |
||
| 172 | $resultObject->setDatabase($database); |
||
| 173 | } |
||
| 174 | |||
| 175 | return $resultObject; |
||
| 176 | } |
||
| 177 | |||
| 178 | /** |
||
| 179 | * @param string $status |
||
| 180 | * @param PdoDatabase $database |
||
| 181 | * @return User[] |
||
| 182 | */ |
||
| 183 | public static function getAllWithStatus($status, PdoDatabase $database) |
||
| 184 | { |
||
| 185 | $statement = $database->prepare("SELECT * FROM user WHERE status = :status"); |
||
| 186 | $statement->execute(array(":status" => $status)); |
||
| 187 | |||
| 188 | $resultObject = $statement->fetchAll(PDO::FETCH_CLASS, get_called_class()); |
||
| 189 | |||
| 190 | /** @var User $u */ |
||
| 191 | foreach ($resultObject as $u) { |
||
| 192 | $u->setDatabase($database); |
||
| 193 | $u->isNew = false; |
||
| 194 | } |
||
| 195 | |||
| 196 | return $resultObject; |
||
| 197 | } |
||
| 198 | |||
| 199 | public static function getAllCheckusers(PdoDatabase $database) |
||
| 200 | { |
||
| 201 | $statement = $database->prepare("SELECT * FROM user WHERE checkuser = 1;"); |
||
| 202 | $statement->execute(); |
||
| 203 | |||
| 204 | $resultObject = $statement->fetchAll(PDO::FETCH_CLASS, get_called_class()); |
||
| 205 | |||
| 206 | $resultsCollection = array(); |
||
| 207 | |||
| 208 | /** @var User $u */ |
||
| 209 | foreach ($resultObject as $u) { |
||
| 210 | $u->setDatabase($database); |
||
| 211 | $u->isNew = false; |
||
| 212 | |||
| 213 | if (!$u->isCheckuser()) { |
||
| 214 | continue; |
||
| 215 | } |
||
| 216 | |||
| 217 | $resultsCollection[] = $u; |
||
| 218 | } |
||
| 219 | |||
| 220 | return $resultsCollection; |
||
| 221 | } |
||
| 222 | |||
| 223 | public static function getAllInactive(PdoDatabase $database) |
||
| 224 | { |
||
| 225 | $date = new DateTime(); |
||
| 226 | $date->modify("-90 days"); |
||
| 227 | |||
| 228 | $statement = $database->prepare(<<<SQL |
||
| 229 | SELECT * |
||
| 230 | FROM user |
||
| 231 | WHERE lastactive < :lastactivelimit |
||
| 232 | AND status != 'Suspended' |
||
| 233 | AND status != 'Declined' |
||
| 234 | AND status != 'New' |
||
| 235 | ORDER BY lastactive ASC; |
||
| 236 | SQL |
||
| 237 | ); |
||
| 238 | $statement->execute(array(":lastactivelimit" => $date->format("Y-m-d H:i:s"))); |
||
| 239 | |||
| 240 | $resultObject = $statement->fetchAll(PDO::FETCH_CLASS, get_called_class()); |
||
| 241 | |||
| 242 | /** @var User $u */ |
||
| 243 | foreach ($resultObject as $u) { |
||
| 244 | $u->setDatabase($database); |
||
| 245 | $u->isNew = false; |
||
| 246 | } |
||
| 247 | |||
| 248 | return $resultObject; |
||
| 249 | } |
||
| 250 | |||
| 251 | /** |
||
| 252 | * Gets all the usernames in the system |
||
| 253 | * @param PdoDatabase $database |
||
| 254 | * @param null|bool|string $filter If null, no filter. If true, active users only, otherwise provided status. |
||
| 255 | * @return string[] |
||
| 256 | */ |
||
| 257 | public static function getAllUsernames(PdoDatabase $database, $filter = null) |
||
| 258 | { |
||
| 259 | if ($filter === null) { |
||
| 260 | $userListQuery = "SELECT username FROM user;"; |
||
| 261 | $userListResult = $database->query($userListQuery); |
||
| 262 | } |
||
| 263 | elseif ($filter === true) { |
||
| 264 | $userListQuery = "SELECT username FROM user WHERE status IN ('User', 'Admin');"; |
||
| 265 | $userListResult = $database->query($userListQuery); |
||
| 266 | } |
||
| 267 | else { |
||
| 268 | $userListQuery = "SELECT username FROM user WHERE status = :status;"; |
||
| 269 | $userListResult = $database->prepare($userListQuery); |
||
| 270 | $userListResult->execute(array(":status" => $filter)); |
||
| 271 | } |
||
| 272 | |||
| 273 | return $userListResult->fetchAll(PDO::FETCH_COLUMN); |
||
| 274 | } |
||
| 275 | |||
| 276 | public function save() |
||
| 277 | { |
||
| 278 | if ($this->isNew) { |
||
| 279 | // insert |
||
| 280 | $statement = $this->dbObject->prepare(<<<SQL |
||
| 281 | INSERT INTO `user` ( |
||
| 282 | username, email, password, status, onwikiname, welcome_sig, |
||
| 283 | lastactive, forcelogout, checkuser, identified, |
||
| 284 | welcome_template, abortpref, confirmationdiff, emailsig, |
||
| 285 | oauthrequesttoken, oauthrequestsecret, |
||
| 286 | oauthaccesstoken, oauthaccesssecret |
||
| 287 | ) VALUES ( |
||
| 288 | :username, :email, :password, :status, :onwikiname, :welcome_sig, |
||
| 289 | :lastactive, :forcelogout, :checkuser, :identified, |
||
| 290 | :welcome_template, :abortpref, :confirmationdiff, :emailsig, |
||
| 291 | :ort, :ors, :oat, :oas |
||
| 292 | ); |
||
| 293 | SQL |
||
| 294 | ); |
||
| 295 | $statement->bindValue(":username", $this->username); |
||
| 296 | $statement->bindValue(":email", $this->email); |
||
| 297 | $statement->bindValue(":password", $this->password); |
||
| 298 | $statement->bindValue(":status", $this->status); |
||
| 299 | $statement->bindValue(":onwikiname", $this->onwikiname); |
||
| 300 | $statement->bindValue(":welcome_sig", $this->welcome_sig); |
||
| 301 | $statement->bindValue(":lastactive", $this->lastactive); |
||
| 302 | $statement->bindValue(":forcelogout", $this->forcelogout); |
||
| 303 | $statement->bindValue(":checkuser", $this->checkuser); |
||
| 304 | $statement->bindValue(":identified", $this->identified); |
||
| 305 | $statement->bindValue(":welcome_template", $this->welcome_template); |
||
| 306 | $statement->bindValue(":abortpref", $this->abortpref); |
||
| 307 | $statement->bindValue(":confirmationdiff", $this->confirmationdiff); |
||
| 308 | $statement->bindValue(":emailsig", $this->emailsig); |
||
| 309 | $statement->bindValue(":ort", $this->oauthrequesttoken); |
||
| 310 | $statement->bindValue(":ors", $this->oauthrequestsecret); |
||
| 311 | $statement->bindValue(":oat", $this->oauthaccesstoken); |
||
| 312 | $statement->bindValue(":oas", $this->oauthaccesssecret); |
||
| 313 | |||
| 314 | if ($statement->execute()) { |
||
| 315 | $this->isNew = false; |
||
| 316 | $this->id = (int)$this->dbObject->lastInsertId(); |
||
| 317 | } |
||
| 318 | else { |
||
| 319 | throw new Exception($statement->errorInfo()); |
||
| 320 | } |
||
| 321 | } |
||
| 322 | else { |
||
| 323 | // update |
||
| 324 | $statement = $this->dbObject->prepare(<<<SQL |
||
| 325 | UPDATE `user` SET |
||
| 326 | username = :username, email = :email, |
||
| 327 | password = :password, status = :status, |
||
| 328 | onwikiname = :onwikiname, welcome_sig = :welcome_sig, |
||
| 329 | lastactive = :lastactive, forcelogout = :forcelogout, |
||
| 330 | checkuser = :checkuser, identified = :identified, |
||
| 331 | welcome_template = :welcome_template, abortpref = :abortpref, |
||
| 332 | confirmationdiff = :confirmationdiff, emailsig = :emailsig, |
||
| 333 | oauthrequesttoken = :ort, oauthrequestsecret = :ors, |
||
| 334 | oauthaccesstoken = :oat, oauthaccesssecret = :oas |
||
| 335 | WHERE id = :id |
||
| 336 | LIMIT 1; |
||
| 337 | SQL |
||
| 338 | ); |
||
| 339 | $statement->bindValue(":id", $this->id); |
||
| 340 | $statement->bindValue(":username", $this->username); |
||
| 341 | $statement->bindValue(":email", $this->email); |
||
| 342 | $statement->bindValue(":password", $this->password); |
||
| 343 | $statement->bindValue(":status", $this->status); |
||
| 344 | $statement->bindValue(":onwikiname", $this->onwikiname); |
||
| 345 | $statement->bindValue(":welcome_sig", $this->welcome_sig); |
||
| 346 | $statement->bindValue(":lastactive", $this->lastactive); |
||
| 347 | $statement->bindValue(":forcelogout", $this->forcelogout); |
||
| 348 | $statement->bindValue(":checkuser", $this->checkuser); |
||
| 349 | $statement->bindValue(":identified", $this->identified); |
||
| 350 | $statement->bindValue(":welcome_template", $this->welcome_template); |
||
| 351 | $statement->bindValue(":abortpref", $this->abortpref); |
||
| 352 | $statement->bindValue(":confirmationdiff", $this->confirmationdiff); |
||
| 353 | $statement->bindValue(":emailsig", $this->emailsig); |
||
| 354 | $statement->bindValue(":ort", $this->oauthrequesttoken); |
||
| 355 | $statement->bindValue(":ors", $this->oauthrequestsecret); |
||
| 356 | $statement->bindValue(":oat", $this->oauthaccesstoken); |
||
| 357 | $statement->bindValue(":oas", $this->oauthaccesssecret); |
||
| 358 | |||
| 359 | if (!$statement->execute()) { |
||
| 360 | throw new Exception($statement->errorInfo()); |
||
| 361 | } |
||
| 362 | } |
||
| 363 | } |
||
| 364 | |||
| 365 | public function authenticate($password) |
||
| 366 | { |
||
| 367 | $result = AuthUtility::testCredentials($password, $this->password); |
||
| 368 | |||
| 369 | if ($result === true) { |
||
| 370 | // password version is out of date, update it. |
||
| 371 | if (!AuthUtility::isCredentialVersionLatest($this->password)) { |
||
| 372 | $this->password = AuthUtility::encryptPassword($password); |
||
| 373 | $this->save(); |
||
| 374 | } |
||
| 375 | } |
||
| 376 | |||
| 377 | return $result; |
||
| 378 | } |
||
| 379 | |||
| 380 | public function touchLastLogin() |
||
| 381 | { |
||
| 382 | $query = "UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;"; |
||
| 383 | $this->dbObject->prepare($query)->execute(array(":id" => $this->id)); |
||
| 384 | } |
||
| 385 | |||
| 386 | #region properties |
||
| 387 | |||
| 388 | public function getUsername() |
||
|
0 ignored issues
–
show
|
|||
| 389 | { |
||
| 390 | return $this->username; |
||
| 391 | } |
||
| 392 | |||
| 393 | public function setUsername($username) |
||
| 394 | { |
||
| 395 | $this->username = $username; |
||
| 396 | $this->forcelogout = 1; |
||
| 397 | } |
||
| 398 | |||
| 399 | public function getEmail() |
||
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a Loading history...
|
|||
| 400 | { |
||
| 401 | return $this->email; |
||
| 402 | } |
||
| 403 | |||
| 404 | public function setEmail($email) |
||
| 405 | { |
||
| 406 | $this->email = $email; |
||
| 407 | } |
||
| 408 | |||
| 409 | public function setPassword($password) |
||
| 410 | { |
||
| 411 | $this->password = AuthUtility::encryptPassword($password); |
||
| 412 | } |
||
| 413 | |||
| 414 | public function getStatus() |
||
| 415 | { |
||
| 416 | return $this->status; |
||
| 417 | } |
||
| 418 | |||
| 419 | /** |
||
| 420 | * Gets the user's on-wiki name |
||
| 421 | * @return mixed |
||
| 422 | */ |
||
| 423 | public function getOnWikiName() |
||
| 424 | { |
||
| 425 | if ($this->oauthaccesstoken != null) { |
||
| 426 | try { |
||
| 427 | return $this->getOAuthOnWikiName(); |
||
| 428 | } |
||
| 429 | catch (Exception $ex) { |
||
| 430 | // urm.. log this? |
||
| 431 | return $this->onwikiname; |
||
| 432 | } |
||
| 433 | } |
||
| 434 | |||
| 435 | return $this->onwikiname; |
||
| 436 | } |
||
| 437 | |||
| 438 | /** |
||
| 439 | * This is probably NOT the function you want! |
||
| 440 | * |
||
| 441 | * Take a look at getOnWikiName() instead. |
||
| 442 | * @return string |
||
| 443 | */ |
||
| 444 | public function getStoredOnWikiName() |
||
| 445 | { |
||
| 446 | return $this->onwikiname; |
||
| 447 | } |
||
| 448 | |||
| 449 | public function setOnWikiName($onWikiName) |
||
| 450 | { |
||
| 451 | $this->onwikiname = $onWikiName; |
||
| 452 | } |
||
| 453 | |||
| 454 | public function getWelcomeSig() |
||
| 455 | { |
||
| 456 | return $this->welcome_sig; |
||
| 457 | } |
||
| 458 | |||
| 459 | public function setWelcomeSig($welcomeSig) |
||
| 460 | { |
||
| 461 | $this->welcome_sig = $welcomeSig; |
||
| 462 | } |
||
| 463 | |||
| 464 | public function getLastActive() |
||
| 465 | { |
||
| 466 | return $this->lastactive; |
||
| 467 | } |
||
| 468 | |||
| 469 | public function setLastActive($lastActive) |
||
| 470 | { |
||
| 471 | $this->lastactive = $lastActive; |
||
| 472 | } |
||
| 473 | |||
| 474 | public function getForcelogout() |
||
| 475 | { |
||
| 476 | return $this->forcelogout; |
||
| 477 | } |
||
| 478 | |||
| 479 | public function setForcelogout($forceLogout) |
||
| 480 | { |
||
| 481 | $this->forcelogout = $forceLogout ? 1 : 0; |
||
| 482 | } |
||
| 483 | |||
| 484 | public function getSecure() |
||
| 485 | { |
||
| 486 | return true; |
||
| 487 | } |
||
| 488 | |||
| 489 | public function getCheckuser() |
||
| 490 | { |
||
| 491 | return $this->checkuser; |
||
| 492 | } |
||
| 493 | |||
| 494 | public function setCheckuser($checkuser) |
||
| 495 | { |
||
| 496 | $this->checkuser = $checkuser; |
||
| 497 | } |
||
| 498 | |||
| 499 | public function getIdentified() |
||
| 500 | { |
||
| 501 | return $this->identified; |
||
| 502 | } |
||
| 503 | |||
| 504 | public function setIdentified($identified) |
||
| 505 | { |
||
| 506 | $this->identified = $identified; |
||
| 507 | } |
||
| 508 | |||
| 509 | public function getWelcomeTemplate() |
||
| 510 | { |
||
| 511 | return $this->welcome_template; |
||
| 512 | } |
||
| 513 | |||
| 514 | public function setWelcomeTemplate($welcomeTemplate) |
||
| 515 | { |
||
| 516 | $this->welcome_template = $welcomeTemplate; |
||
| 517 | } |
||
| 518 | |||
| 519 | public function getAbortPref() |
||
| 520 | { |
||
| 521 | return $this->abortpref; |
||
| 522 | } |
||
| 523 | |||
| 524 | public function setAbortPref($abortPreference) |
||
| 525 | { |
||
| 526 | $this->abortpref = $abortPreference; |
||
| 527 | } |
||
| 528 | |||
| 529 | public function getConfirmationDiff() |
||
| 530 | { |
||
| 531 | return $this->confirmationdiff; |
||
| 532 | } |
||
| 533 | |||
| 534 | public function setConfirmationDiff($confirmationDiff) |
||
| 535 | { |
||
| 536 | $this->confirmationdiff = $confirmationDiff; |
||
| 537 | } |
||
| 538 | |||
| 539 | /** |
||
| 540 | * @return string |
||
| 541 | */ |
||
| 542 | public function getEmailSig() |
||
| 543 | { |
||
| 544 | return $this->emailsig; |
||
| 545 | } |
||
| 546 | |||
| 547 | public function setEmailSig($emailSignature) |
||
| 548 | { |
||
| 549 | $this->emailsig = $emailSignature; |
||
| 550 | } |
||
| 551 | |||
| 552 | public function getOAuthRequestToken() |
||
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a Loading history...
|
|||
| 553 | { |
||
| 554 | return $this->oauthrequesttoken; |
||
| 555 | } |
||
| 556 | |||
| 557 | public function setOAuthRequestToken($oAuthRequestToken) |
||
| 558 | { |
||
| 559 | $this->oauthrequesttoken = $oAuthRequestToken; |
||
| 560 | } |
||
| 561 | |||
| 562 | public function getOAuthRequestSecret() |
||
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a Loading history...
|
|||
| 563 | { |
||
| 564 | return $this->oauthrequestsecret; |
||
| 565 | } |
||
| 566 | |||
| 567 | public function setOAuthRequestSecret($oAuthRequestSecret) |
||
| 568 | { |
||
| 569 | $this->oauthrequestsecret = $oAuthRequestSecret; |
||
| 570 | } |
||
| 571 | |||
| 572 | public function getOAuthAccessToken() |
||
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a Loading history...
|
|||
| 573 | { |
||
| 574 | return $this->oauthaccesstoken; |
||
| 575 | } |
||
| 576 | |||
| 577 | public function setOAuthAccessToken($oAuthAccessToken) |
||
| 578 | { |
||
| 579 | $this->oauthaccesstoken = $oAuthAccessToken; |
||
| 580 | } |
||
| 581 | |||
| 582 | public function getOAuthAccessSecret() |
||
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a Loading history...
|
|||
| 583 | { |
||
| 584 | return $this->oauthaccesssecret; |
||
| 585 | } |
||
| 586 | |||
| 587 | public function setOAuthAccessSecret($oAuthAccessSecret) |
||
| 588 | { |
||
| 589 | $this->oauthaccesssecret = $oAuthAccessSecret; |
||
| 590 | } |
||
| 591 | |||
| 592 | #endregion |
||
| 593 | |||
| 594 | #region changing access level |
||
| 595 | |||
| 596 | public function approve() |
||
| 597 | { |
||
| 598 | $this->dbObject->transactionally(function() |
||
| 599 | { |
||
| 600 | $this->status = "User"; |
||
| 601 | $this->save(); |
||
| 602 | Logger::approvedUser($this->dbObject, $this); |
||
| 603 | }); |
||
| 604 | } |
||
| 605 | |||
| 606 | View Code Duplication | public function suspend($comment) |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 607 | { |
||
| 608 | $this->dbObject->transactionally(function() use ($comment) |
||
| 609 | { |
||
| 610 | $this->status = "Suspended"; |
||
| 611 | $this->save(); |
||
| 612 | Logger::suspendedUser($this->dbObject, $this, $comment); |
||
| 613 | }); |
||
| 614 | } |
||
| 615 | |||
| 616 | View Code Duplication | public function decline($comment) |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 617 | { |
||
| 618 | $this->dbObject->transactionally(function() use ($comment) |
||
| 619 | { |
||
| 620 | $this->status = "Declined"; |
||
| 621 | $this->save(); |
||
| 622 | Logger::declinedUser($this->dbObject, $this, $comment); |
||
| 623 | }); |
||
| 624 | } |
||
| 625 | |||
| 626 | public function promote() |
||
| 627 | { |
||
| 628 | $this->dbObject->transactionally(function() |
||
| 629 | { |
||
| 630 | $this->status = "Admin"; |
||
| 631 | $this->save(); |
||
| 632 | Logger::promotedUser($this->dbObject, $this); |
||
| 633 | }); |
||
| 634 | } |
||
| 635 | |||
| 636 | View Code Duplication | public function demote($comment) |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 637 | { |
||
| 638 | $this->dbObject->transactionally(function() use ($comment) |
||
| 639 | { |
||
| 640 | $this->status = "User"; |
||
| 641 | $this->save(); |
||
| 642 | Logger::demotedUser($this->dbObject, $this, $comment); |
||
| 643 | }); |
||
| 644 | } |
||
| 645 | |||
| 646 | #endregion |
||
| 647 | |||
| 648 | #region user access checks |
||
| 649 | |||
| 650 | public function isAdmin() |
||
| 651 | { |
||
| 652 | return $this->status == "Admin"; |
||
| 653 | } |
||
| 654 | |||
| 655 | public function isCheckuser() |
||
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a Loading history...
|
|||
| 656 | { |
||
| 657 | if($this->isCheckuserCache === null) { |
||
| 658 | $this->isCheckuserCache = $this->checkuser == 1 || $this->oauthCanCheckUser(); |
||
| 659 | } |
||
| 660 | |||
| 661 | return $this->isCheckuserCache; |
||
| 662 | } |
||
| 663 | |||
| 664 | public function isIdentified() |
||
| 665 | { |
||
| 666 | return $this->identified == 1; |
||
| 667 | } |
||
| 668 | |||
| 669 | public function isSuspended() |
||
| 670 | { |
||
| 671 | return $this->status == "Suspended"; |
||
| 672 | } |
||
| 673 | |||
| 674 | public function isNew() |
||
| 675 | { |
||
| 676 | return $this->status == "New"; |
||
| 677 | } |
||
| 678 | |||
| 679 | public function isUser() |
||
| 680 | { |
||
| 681 | return $this->status == "User"; |
||
| 682 | } |
||
| 683 | |||
| 684 | public function isDeclined() |
||
| 685 | { |
||
| 686 | return $this->status == "Declined"; |
||
| 687 | } |
||
| 688 | |||
| 689 | public function isCommunityUser() |
||
| 690 | { |
||
| 691 | return false; |
||
| 692 | } |
||
| 693 | |||
| 694 | #endregion |
||
| 695 | |||
| 696 | #region OAuth |
||
| 697 | |||
| 698 | public function getOAuthIdentity($useCached = false) |
||
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a Loading history...
|
|||
| 699 | { |
||
| 700 | if ($this->oauthaccesstoken == null) { |
||
| 701 | $this->clearOAuthData(); |
||
| 702 | } |
||
| 703 | |||
| 704 | global $oauthConsumerToken, $oauthMediaWikiCanonicalServer; |
||
| 705 | |||
| 706 | if ($this->oauthidentitycache == null) { |
||
| 707 | $this->identityCache = null; |
||
| 708 | } |
||
| 709 | else { |
||
| 710 | $this->identityCache = unserialize($this->oauthidentitycache); |
||
| 711 | } |
||
| 712 | |||
| 713 | // check the cache |
||
| 714 | if ( |
||
| 715 | $this->identityCache != null && |
||
| 716 | $this->identityCache->aud == $oauthConsumerToken && |
||
| 717 | $this->identityCache->iss == $oauthMediaWikiCanonicalServer |
||
| 718 | ) { |
||
| 719 | if ( |
||
| 720 | $useCached || ( |
||
| 721 | DateTime::createFromFormat("U", $this->identityCache->iat) < new DateTime() && |
||
| 722 | DateTime::createFromFormat("U", $this->identityCache->exp) > new DateTime() |
||
| 723 | ) |
||
| 724 | ) { |
||
| 725 | // Use cached value - it's either valid or we don't care. |
||
| 726 | return $this->identityCache; |
||
| 727 | } |
||
| 728 | else { |
||
| 729 | // Cache expired and not forcing use of cached value |
||
| 730 | $this->getIdentityCache(); |
||
| 731 | return $this->identityCache; |
||
| 732 | } |
||
| 733 | } |
||
| 734 | else { |
||
| 735 | // Cache isn't ours or doesn't exist |
||
| 736 | $this->getIdentityCache(); |
||
| 737 | return $this->identityCache; |
||
| 738 | } |
||
| 739 | } |
||
| 740 | |||
| 741 | /** |
||
| 742 | * Summary of getOAuthOnWikiName |
||
| 743 | * @param mixed $useCached Set to false for everything where up-to-date data is important. |
||
| 744 | * @return mixed |
||
| 745 | */ |
||
| 746 | private function getOAuthOnWikiName($useCached = false) |
||
| 747 | { |
||
| 748 | $identity = $this->getOAuthIdentity($useCached); |
||
| 749 | if ($identity !== null) { |
||
| 750 | return $identity->username; |
||
| 751 | } |
||
| 752 | |||
| 753 | return false; |
||
| 754 | } |
||
| 755 | |||
| 756 | /** |
||
| 757 | * @return bool |
||
| 758 | */ |
||
| 759 | public function isOAuthLinked() |
||
| 760 | { |
||
| 761 | if ($this->onwikiname === "##OAUTH##") { |
||
| 762 | return true; // special value. If an account must be oauth linked, this is true. |
||
| 763 | } |
||
| 764 | |||
| 765 | return $this->oauthaccesstoken !== null; |
||
| 766 | } |
||
| 767 | |||
| 768 | private function clearOAuthData() |
||
| 769 | { |
||
| 770 | $this->identityCache = null; |
||
| 771 | $this->oauthidentitycache = null; |
||
| 772 | $clearCacheQuery = "UPDATE user SET oauthidentitycache = null WHERE id = :id;"; |
||
| 773 | $this->dbObject->prepare($clearCacheQuery)->execute(array(":id" => $this->id)); |
||
| 774 | |||
| 775 | return null; |
||
| 776 | } |
||
| 777 | |||
| 778 | private function getIdentityCache() |
||
| 779 | { |
||
| 780 | global $oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal; |
||
| 781 | |||
| 782 | try { |
||
| 783 | $util = new OAuthUtility($oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal); |
||
| 784 | $this->identityCache = $util->getIdentity($this->oauthaccesstoken, $this->oauthaccesssecret); |
||
| 785 | $this->oauthidentitycache = serialize($this->identityCache); |
||
| 786 | $this->dbObject-> |
||
| 787 | prepare("UPDATE user SET oauthidentitycache = :identity WHERE id = :id;")-> |
||
| 788 | execute(array(":id" => $this->id, ":identity" => $this->oauthidentitycache)); |
||
| 789 | } |
||
| 790 | catch (UnexpectedValueException $ex) { |
||
| 791 | $this->identityCache = null; |
||
| 792 | $this->oauthidentitycache = null; |
||
| 793 | $this->dbObject-> |
||
| 794 | prepare("UPDATE user SET oauthidentitycache = null WHERE id = :id;")-> |
||
| 795 | execute(array(":id" => $this->id)); |
||
| 796 | |||
| 797 | SessionAlert::warning("OAuth error getting identity from MediaWiki: " . $ex->getMessage()); |
||
| 798 | } |
||
| 799 | } |
||
| 800 | |||
| 801 | public function detachAccount() |
||
| 802 | { |
||
| 803 | $this->setOnWikiName($this->getOAuthOnWikiName()); |
||
| 804 | $this->setOAuthAccessSecret(null); |
||
| 805 | $this->setOAuthAccessToken(null); |
||
| 806 | $this->setOAuthRequestSecret(null); |
||
| 807 | $this->setOAuthRequestToken(null); |
||
| 808 | |||
| 809 | $this->clearOAuthData(); |
||
| 810 | |||
| 811 | $this->save(); |
||
| 812 | } |
||
| 813 | |||
| 814 | public function oauthCanUse() |
||
| 815 | { |
||
| 816 | try { |
||
| 817 | return in_array('useoauth', $this->getOAuthIdentity()->grants); |
||
| 818 | } |
||
| 819 | catch (Exception $ex) { |
||
| 820 | return false; |
||
| 821 | } |
||
| 822 | } |
||
| 823 | |||
| 824 | View Code Duplication | public function oauthCanEdit() |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 825 | { |
||
| 826 | try { |
||
| 827 | return in_array('useoauth', $this->getOAuthIdentity()->grants) |
||
| 828 | && in_array('createeditmovepage', $this->getOAuthIdentity()->grants) |
||
| 829 | && in_array('createtalk', $this->getOAuthIdentity()->rights) |
||
| 830 | && in_array('edit', $this->getOAuthIdentity()->rights) |
||
| 831 | && in_array('writeapi', $this->getOAuthIdentity()->rights); } |
||
| 832 | catch (Exception $ex) { |
||
| 833 | return false; |
||
| 834 | } |
||
| 835 | } |
||
| 836 | |||
| 837 | View Code Duplication | public function oauthCanCreateAccount() |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 838 | { |
||
| 839 | try { |
||
| 840 | return in_array('useoauth', $this->getOAuthIdentity()->grants) |
||
| 841 | && in_array('createaccount', $this->getOAuthIdentity()->grants) |
||
| 842 | && in_array('createaccount', $this->getOAuthIdentity()->rights) |
||
| 843 | && in_array('writeapi', $this->getOAuthIdentity()->rights); |
||
| 844 | } |
||
| 845 | catch (Exception $ex) { |
||
| 846 | return false; |
||
| 847 | } |
||
| 848 | } |
||
| 849 | |||
| 850 | /** |
||
| 851 | * @return bool |
||
| 852 | */ |
||
| 853 | protected function oauthCanCheckUser() |
||
| 854 | { |
||
| 855 | if (!$this->isOAuthLinked()) { |
||
| 856 | return false; |
||
| 857 | } |
||
| 858 | |||
| 859 | try { |
||
| 860 | $identity = $this->getOAuthIdentity(); |
||
| 861 | return in_array('checkuser', $identity->rights); |
||
| 862 | } |
||
| 863 | catch (Exception $ex) { |
||
| 864 | return false; |
||
| 865 | } |
||
| 866 | } |
||
| 867 | |||
| 868 | #endregion |
||
| 869 | |||
| 870 | public function getForgottenPasswordHash() |
||
| 871 | { |
||
| 872 | return md5($this->username . $this->email . $this->welcome_template . $this->id . $this->password); |
||
| 873 | } |
||
| 874 | |||
| 875 | View Code Duplication | public function getApprovalDate() |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 876 | { |
||
| 877 | $query = $this->dbObject->prepare(<<<SQL |
||
| 878 | SELECT timestamp |
||
| 879 | FROM log |
||
| 880 | WHERE objectid = :userid |
||
| 881 | AND objecttype = 'User' |
||
| 882 | AND action = 'Approved' |
||
| 883 | ORDER BY id DESC |
||
| 884 | LIMIT 1; |
||
| 885 | SQL |
||
| 886 | ); |
||
| 887 | $query->execute(array(":userid" => $this->id)); |
||
| 888 | |||
| 889 | $data = DateTime::createFromFormat("Y-m-d H:i:s", $query->fetchColumn()); |
||
| 890 | $query->closeCursor(); |
||
| 891 | |||
| 892 | return $data; |
||
| 893 | } |
||
| 894 | |||
| 895 | public function getObjectDescription() |
||
| 896 | { |
||
| 897 | return '<a href="statistics.php?page=Users&user=' . $this->getId() . '">' . htmlentities($this->username) . "</a>"; |
||
| 898 | } |
||
| 899 | } |
||
| 900 |
Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a
@returnannotation as described here.