UserInfo.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <?php
  2. /**
  3. * MediaWiki session user info
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. * http://www.gnu.org/copyleft/gpl.html
  19. *
  20. * @file
  21. * @ingroup Session
  22. */
  23. namespace MediaWiki\Session;
  24. use User;
  25. /**
  26. * Object holding data about a session's user
  27. *
  28. * In general, this class exists for two purposes:
  29. * - User doesn't distinguish between "anonymous user" and "non-anonymous user
  30. * that doesn't exist locally", while we do need to.
  31. * - We also need the "verified" property described below; tracking it via
  32. * another data item to SessionInfo's constructor makes things much more
  33. * confusing.
  34. *
  35. * A UserInfo may be "verified". This indicates that the creator knows that the
  36. * request really comes from that user, whether that's by validating OAuth
  37. * credentials, SSL client certificates, or by having both the user ID and
  38. * token available from cookies.
  39. *
  40. * An "unverified" UserInfo should be used when it's not possible to
  41. * authenticate the user, e.g. the user ID cookie is set but the user Token
  42. * cookie isn't. If the Token is available but doesn't match, don't return a
  43. * UserInfo at all.
  44. *
  45. * @ingroup Session
  46. * @since 1.27
  47. */
  48. final class UserInfo {
  49. /** @var bool */
  50. private $verified = false;
  51. /** @var User|null */
  52. private $user = null;
  53. private function __construct( User $user = null, $verified ) {
  54. if ( $user && $user->isAnon() && !User::isUsableName( $user->getName() ) ) {
  55. $this->verified = true;
  56. $this->user = null;
  57. } else {
  58. $this->verified = $verified;
  59. $this->user = $user;
  60. }
  61. }
  62. /**
  63. * Create an instance for an anonymous (i.e. not logged in) user
  64. *
  65. * Logged-out users are always "verified".
  66. *
  67. * @return UserInfo
  68. */
  69. public static function newAnonymous() {
  70. return new self( null, true );
  71. }
  72. /**
  73. * Create an instance for a logged-in user by ID
  74. * @param int $id User ID
  75. * @param bool $verified True if the user is verified
  76. * @return UserInfo
  77. */
  78. public static function newFromId( $id, $verified = false ) {
  79. $user = User::newFromId( $id );
  80. // Ensure the ID actually exists
  81. $user->load();
  82. if ( $user->isAnon() ) {
  83. throw new \InvalidArgumentException( 'Invalid ID' );
  84. }
  85. return new self( $user, $verified );
  86. }
  87. /**
  88. * Create an instance for a logged-in user by name
  89. * @param string $name User name (need not exist locally)
  90. * @param bool $verified True if the user is verified
  91. * @return UserInfo
  92. */
  93. public static function newFromName( $name, $verified = false ) {
  94. $user = User::newFromName( $name, 'usable' );
  95. if ( !$user ) {
  96. throw new \InvalidArgumentException( 'Invalid user name' );
  97. }
  98. return new self( $user, $verified );
  99. }
  100. /**
  101. * Create an instance from an existing User object
  102. * @param User $user (need not exist locally)
  103. * @param bool $verified True if the user is verified
  104. * @return UserInfo
  105. */
  106. public static function newFromUser( User $user, $verified = false ) {
  107. return new self( $user, $verified );
  108. }
  109. /**
  110. * Return whether this is an anonymous user
  111. * @return bool
  112. */
  113. public function isAnon() {
  114. return $this->user === null;
  115. }
  116. /**
  117. * Return whether this represents a verified user
  118. * @return bool
  119. */
  120. public function isVerified() {
  121. return $this->verified;
  122. }
  123. /**
  124. * Return the user ID
  125. * @note Do not use this to test for anonymous users!
  126. * @return int
  127. */
  128. public function getId() {
  129. return $this->user === null ? 0 : $this->user->getId();
  130. }
  131. /**
  132. * Return the user name
  133. * @return string|null
  134. */
  135. public function getName() {
  136. return $this->user === null ? null : $this->user->getName();
  137. }
  138. /**
  139. * Return the user token
  140. * @return string
  141. */
  142. public function getToken() {
  143. return $this->user === null || $this->user->getId() === 0 ? '' : $this->user->getToken( false );
  144. }
  145. /**
  146. * Return a User object
  147. * @return User
  148. */
  149. public function getUser() {
  150. return $this->user === null ? new User : $this->user;
  151. }
  152. /**
  153. * Return a verified version of this object
  154. * @return UserInfo
  155. */
  156. public function verified() {
  157. return $this->verified ? $this : new self( $this->user, true );
  158. }
  159. public function __toString() {
  160. if ( $this->user === null ) {
  161. return '<anon>';
  162. }
  163. return '<' .
  164. ( $this->verified ? '+' : '-' ) . ':' .
  165. $this->getId() . ':' . $this->getName() .
  166. '>';
  167. }
  168. }