wikimedia /
mediawiki
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * MediaWiki session provider base class |
||
| 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 | |||
| 24 | namespace MediaWiki\Session; |
||
| 25 | |||
| 26 | use Psr\Log\LoggerAwareInterface; |
||
| 27 | use Psr\Log\LoggerInterface; |
||
| 28 | use Config; |
||
| 29 | use Language; |
||
| 30 | use User; |
||
| 31 | use WebRequest; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * A SessionProvider provides SessionInfo and support for Session |
||
| 35 | * |
||
| 36 | * A SessionProvider is responsible for taking a WebRequest and determining |
||
| 37 | * the authenticated session that it's a part of. It does this by returning an |
||
| 38 | * SessionInfo object with basic information about the session it thinks is |
||
| 39 | * associated with the request, namely the session ID and possibly the |
||
| 40 | * authenticated user the session belongs to. |
||
| 41 | * |
||
| 42 | * The SessionProvider also provides for updating the WebResponse with |
||
| 43 | * information necessary to provide the client with data that the client will |
||
| 44 | * send with later requests, and for populating the Vary and Key headers with |
||
| 45 | * the data necessary to correctly vary the cache on these client requests. |
||
| 46 | * |
||
| 47 | * An important part of the latter is indicating whether it even *can* tell the |
||
| 48 | * client to include such data in future requests, via the persistsSessionId() |
||
| 49 | * and canChangeUser() methods. The cases are (in order of decreasing |
||
| 50 | * commonness): |
||
| 51 | * - Cannot persist ID, no changing User: The request identifies and |
||
| 52 | * authenticates a particular local user, and the client cannot be |
||
| 53 | * instructed to include an arbitrary session ID with future requests. For |
||
| 54 | * example, OAuth or SSL certificate auth. |
||
| 55 | * - Can persist ID and can change User: The client can be instructed to |
||
| 56 | * return at least one piece of arbitrary data, that being the session ID. |
||
| 57 | * The user identity might also be given to the client, otherwise it's saved |
||
| 58 | * in the session data. For example, cookie-based sessions. |
||
| 59 | * - Can persist ID but no changing User: The request uniquely identifies and |
||
| 60 | * authenticates a local user, and the client can be instructed to return an |
||
| 61 | * arbitrary session ID with future requests. For example, HTTP Digest |
||
| 62 | * authentication might somehow use the 'opaque' field as a session ID |
||
| 63 | * (although getting MediaWiki to return 401 responses without breaking |
||
| 64 | * other stuff might be a challenge). |
||
| 65 | * - Cannot persist ID but can change User: I can't think of a way this |
||
| 66 | * would make sense. |
||
| 67 | * |
||
| 68 | * Note that many methods that are technically "cannot persist ID" could be |
||
| 69 | * turned into "can persist ID but not change User" using a session cookie, |
||
| 70 | * as implemented by ImmutableSessionProviderWithCookie. If doing so, different |
||
| 71 | * session cookie names should be used for different providers to avoid |
||
| 72 | * collisions. |
||
| 73 | * |
||
| 74 | * @ingroup Session |
||
| 75 | * @since 1.27 |
||
| 76 | * @see https://www.mediawiki.org/wiki/Manual:SessionManager_and_AuthManager |
||
| 77 | */ |
||
| 78 | abstract class SessionProvider implements SessionProviderInterface, LoggerAwareInterface { |
||
| 79 | |||
| 80 | /** @var LoggerInterface */ |
||
| 81 | protected $logger; |
||
| 82 | |||
| 83 | /** @var Config */ |
||
| 84 | protected $config; |
||
| 85 | |||
| 86 | /** @var SessionManager */ |
||
| 87 | protected $manager; |
||
| 88 | |||
| 89 | /** @var int Session priority. Used for the default newSessionInfo(), but |
||
| 90 | * could be used by subclasses too. |
||
| 91 | */ |
||
| 92 | protected $priority; |
||
| 93 | |||
| 94 | /** |
||
| 95 | * @note To fully initialize a SessionProvider, the setLogger(), |
||
| 96 | * setConfig(), and setManager() methods must be called (and should be |
||
| 97 | * called in that order). Failure to do so is liable to cause things to |
||
| 98 | * fail unexpectedly. |
||
| 99 | */ |
||
| 100 | public function __construct() { |
||
| 101 | $this->priority = SessionInfo::MIN_PRIORITY + 10; |
||
| 102 | } |
||
| 103 | |||
| 104 | public function setLogger( LoggerInterface $logger ) { |
||
| 105 | $this->logger = $logger; |
||
| 106 | } |
||
| 107 | |||
| 108 | /** |
||
| 109 | * Set configuration |
||
| 110 | * @param Config $config |
||
| 111 | */ |
||
| 112 | public function setConfig( Config $config ) { |
||
| 113 | $this->config = $config; |
||
| 114 | } |
||
| 115 | |||
| 116 | /** |
||
| 117 | * Set the session manager |
||
| 118 | * @param SessionManager $manager |
||
| 119 | */ |
||
| 120 | public function setManager( SessionManager $manager ) { |
||
| 121 | $this->manager = $manager; |
||
| 122 | } |
||
| 123 | |||
| 124 | /** |
||
| 125 | * Get the session manager |
||
| 126 | * @return SessionManager |
||
| 127 | */ |
||
| 128 | public function getManager() { |
||
| 129 | return $this->manager; |
||
| 130 | } |
||
| 131 | |||
| 132 | /** |
||
| 133 | * Provide session info for a request |
||
| 134 | * |
||
| 135 | * If no session exists for the request, return null. Otherwise return an |
||
| 136 | * SessionInfo object identifying the session. |
||
| 137 | * |
||
| 138 | * If multiple SessionProviders provide sessions, the one with highest |
||
| 139 | * priority wins. In case of a tie, an exception is thrown. |
||
| 140 | * SessionProviders are encouraged to make priorities user-configurable |
||
| 141 | * unless only max-priority makes sense. |
||
| 142 | * |
||
| 143 | * @warning This will be called early in the MediaWiki setup process, |
||
| 144 | * before $wgUser, $wgLang, $wgOut, $wgParser, $wgTitle, and corresponding |
||
| 145 | * pieces of the main RequestContext are set up! If you try to use these, |
||
| 146 | * things *will* break. |
||
| 147 | * @note The SessionProvider must not attempt to auto-create users. |
||
| 148 | * MediaWiki will do this later (when it's safe) if the chosen session has |
||
| 149 | * a user with a valid name but no ID. |
||
| 150 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 151 | * @param WebRequest $request |
||
| 152 | * @return SessionInfo|null |
||
| 153 | */ |
||
| 154 | abstract public function provideSessionInfo( WebRequest $request ); |
||
| 155 | |||
| 156 | /** |
||
| 157 | * Provide session info for a new, empty session |
||
| 158 | * |
||
| 159 | * Return null if such a session cannot be created. This base |
||
| 160 | * implementation assumes that it only makes sense if a session ID can be |
||
| 161 | * persisted and changing users is allowed. |
||
| 162 | * |
||
| 163 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 164 | * @param string|null $id ID to force for the new session |
||
| 165 | * @return SessionInfo|null |
||
| 166 | * If non-null, must return true for $info->isIdSafe(); pass true for |
||
| 167 | * $data['idIsSafe'] to ensure this. |
||
| 168 | */ |
||
| 169 | public function newSessionInfo( $id = null ) { |
||
| 170 | if ( $this->canChangeUser() && $this->persistsSessionId() ) { |
||
| 171 | return new SessionInfo( $this->priority, [ |
||
| 172 | 'id' => $id, |
||
| 173 | 'provider' => $this, |
||
| 174 | 'persisted' => false, |
||
| 175 | 'idIsSafe' => true, |
||
| 176 | ] ); |
||
| 177 | } |
||
| 178 | return null; |
||
| 179 | } |
||
| 180 | |||
| 181 | /** |
||
| 182 | * Merge saved session provider metadata |
||
| 183 | * |
||
| 184 | * This method will be used to compare the metadata returned by |
||
| 185 | * provideSessionInfo() with the saved metadata (which has been returned by |
||
| 186 | * provideSessionInfo() the last time the session was saved), and merge the two |
||
| 187 | * into the new saved metadata, or abort if the current request is not a valid |
||
| 188 | * continuation of the session. |
||
| 189 | * |
||
| 190 | * The default implementation checks that anything in both arrays is |
||
| 191 | * identical, then returns $providedMetadata. |
||
| 192 | * |
||
| 193 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 194 | * @param array $savedMetadata Saved provider metadata |
||
| 195 | * @param array $providedMetadata Provided provider metadata (from the SessionInfo) |
||
| 196 | * @return array Resulting metadata |
||
| 197 | * @throws MetadataMergeException If the metadata cannot be merged. |
||
| 198 | * Such exceptions will be handled by SessionManager and are a safe way of rejecting |
||
| 199 | * a suspicious or incompatible session. The provider is expected to write an |
||
| 200 | * appropriate message to its logger. |
||
| 201 | */ |
||
| 202 | public function mergeMetadata( array $savedMetadata, array $providedMetadata ) { |
||
| 203 | foreach ( $providedMetadata as $k => $v ) { |
||
| 204 | if ( array_key_exists( $k, $savedMetadata ) && $savedMetadata[$k] !== $v ) { |
||
| 205 | $e = new MetadataMergeException( "Key \"$k\" changed" ); |
||
| 206 | $e->setContext( [ |
||
| 207 | 'old_value' => $savedMetadata[$k], |
||
| 208 | 'new_value' => $v, |
||
| 209 | ] ); |
||
| 210 | throw $e; |
||
| 211 | } |
||
| 212 | } |
||
| 213 | return $providedMetadata; |
||
| 214 | } |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Validate a loaded SessionInfo and refresh provider metadata |
||
| 218 | * |
||
| 219 | * This is similar in purpose to the 'SessionCheckInfo' hook, and also |
||
| 220 | * allows for updating the provider metadata. On failure, the provider is |
||
| 221 | * expected to write an appropriate message to its logger. |
||
| 222 | * |
||
| 223 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 224 | * @param SessionInfo $info Any changes by mergeMetadata() will already be reflected here. |
||
| 225 | * @param WebRequest $request |
||
| 226 | * @param array|null &$metadata Provider metadata, may be altered. |
||
| 227 | * @return bool Return false to reject the SessionInfo after all. |
||
| 228 | */ |
||
| 229 | public function refreshSessionInfo( SessionInfo $info, WebRequest $request, &$metadata ) { |
||
| 230 | return true; |
||
| 231 | } |
||
| 232 | |||
| 233 | /** |
||
| 234 | * Indicate whether self::persistSession() can save arbitrary session IDs |
||
| 235 | * |
||
| 236 | * If false, any session passed to self::persistSession() will have an ID |
||
| 237 | * that was originally provided by self::provideSessionInfo(). |
||
| 238 | * |
||
| 239 | * If true, the provider may be passed sessions with arbitrary session IDs, |
||
| 240 | * and will be expected to manipulate the request in such a way that future |
||
| 241 | * requests will cause self::provideSessionInfo() to provide a SessionInfo |
||
| 242 | * with that ID. |
||
| 243 | * |
||
| 244 | * For example, a session provider for OAuth would function by matching the |
||
| 245 | * OAuth headers to a particular user, and then would use self::hashToSessionId() |
||
| 246 | * to turn the user and OAuth client ID (and maybe also the user token and |
||
| 247 | * client secret) into a session ID, and therefore can't easily assign that |
||
| 248 | * user+client a different ID. Similarly, a session provider for SSL client |
||
| 249 | * certificates would function by matching the certificate to a particular |
||
| 250 | * user, and then would use self::hashToSessionId() to turn the user and |
||
| 251 | * certificate fingerprint into a session ID, and therefore can't easily |
||
| 252 | * assign a different ID either. On the other hand, a provider that saves |
||
| 253 | * the session ID into a cookie can easily just set the cookie to a |
||
| 254 | * different value. |
||
| 255 | * |
||
| 256 | * @protected For use by \MediaWiki\Session\SessionBackend only |
||
| 257 | * @return bool |
||
| 258 | */ |
||
| 259 | abstract public function persistsSessionId(); |
||
| 260 | |||
| 261 | /** |
||
| 262 | * Indicate whether the user associated with the request can be changed |
||
| 263 | * |
||
| 264 | * If false, any session passed to self::persistSession() will have a user |
||
| 265 | * that was originally provided by self::provideSessionInfo(). Further, |
||
| 266 | * self::provideSessionInfo() may only provide sessions that have a user |
||
| 267 | * already set. |
||
| 268 | * |
||
| 269 | * If true, the provider may be passed sessions with arbitrary users, and |
||
| 270 | * will be expected to manipulate the request in such a way that future |
||
| 271 | * requests will cause self::provideSessionInfo() to provide a SessionInfo |
||
| 272 | * with that ID. This can be as simple as not passing any 'userInfo' into |
||
| 273 | * SessionInfo's constructor, in which case SessionInfo will load the user |
||
| 274 | * from the saved session's metadata. |
||
| 275 | * |
||
| 276 | * For example, a session provider for OAuth or SSL client certificates |
||
| 277 | * would function by matching the OAuth headers or certificate to a |
||
| 278 | * particular user, and thus would return false here since it can't |
||
| 279 | * arbitrarily assign those OAuth credentials or that certificate to a |
||
| 280 | * different user. A session provider that shoves information into cookies, |
||
| 281 | * on the other hand, could easily do so. |
||
| 282 | * |
||
| 283 | * @protected For use by \MediaWiki\Session\SessionBackend only |
||
| 284 | * @return bool |
||
| 285 | */ |
||
| 286 | abstract public function canChangeUser(); |
||
| 287 | |||
| 288 | /** |
||
| 289 | * Returns the duration (in seconds) for which users will be remembered when |
||
| 290 | * Session::setRememberUser() is set. Null means setting the remember flag will |
||
| 291 | * have no effect (and endpoints should not offer that option). |
||
| 292 | * @return int|null |
||
| 293 | */ |
||
| 294 | public function getRememberUserDuration() { |
||
| 295 | return null; |
||
| 296 | } |
||
| 297 | |||
| 298 | /** |
||
| 299 | * Notification that the session ID was reset |
||
| 300 | * |
||
| 301 | * No need to persist here, persistSession() will be called if appropriate. |
||
| 302 | * |
||
| 303 | * @protected For use by \MediaWiki\Session\SessionBackend only |
||
| 304 | * @param SessionBackend $session Session to persist |
||
| 305 | * @param string $oldId Old session ID |
||
| 306 | * @codeCoverageIgnore |
||
| 307 | */ |
||
| 308 | public function sessionIdWasReset( SessionBackend $session, $oldId ) { |
||
| 309 | } |
||
| 310 | |||
| 311 | /** |
||
| 312 | * Persist a session into a request/response |
||
| 313 | * |
||
| 314 | * For example, you might set cookies for the session's ID, user ID, user |
||
| 315 | * name, and user token on the passed request. |
||
| 316 | * |
||
| 317 | * To correctly persist a user independently of the session ID, the |
||
| 318 | * provider should persist both the user ID (or name, but preferably the |
||
| 319 | * ID) and the user token. When reading the data from the request, it |
||
| 320 | * should construct a User object from the ID/name and then verify that the |
||
| 321 | * User object's token matches the token included in the request. Should |
||
| 322 | * the tokens not match, an anonymous user *must* be passed to |
||
| 323 | * SessionInfo::__construct(). |
||
| 324 | * |
||
| 325 | * When persisting a user independently of the session ID, |
||
| 326 | * $session->shouldRememberUser() should be checked first. If this returns |
||
| 327 | * false, the user token *must not* be saved to cookies. The user name |
||
| 328 | * and/or ID may be persisted, and should be used to construct an |
||
| 329 | * unverified UserInfo to pass to SessionInfo::__construct(). |
||
| 330 | * |
||
| 331 | * A backend that cannot persist sesison ID or user info should implement |
||
| 332 | * this as a no-op. |
||
| 333 | * |
||
| 334 | * @protected For use by \MediaWiki\Session\SessionBackend only |
||
| 335 | * @param SessionBackend $session Session to persist |
||
| 336 | * @param WebRequest $request Request into which to persist the session |
||
| 337 | */ |
||
| 338 | abstract public function persistSession( SessionBackend $session, WebRequest $request ); |
||
| 339 | |||
| 340 | /** |
||
| 341 | * Remove any persisted session from a request/response |
||
| 342 | * |
||
| 343 | * For example, blank and expire any cookies set by self::persistSession(). |
||
| 344 | * |
||
| 345 | * A backend that cannot persist sesison ID or user info should implement |
||
| 346 | * this as a no-op. |
||
| 347 | * |
||
| 348 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 349 | * @param WebRequest $request Request from which to remove any session data |
||
| 350 | */ |
||
| 351 | abstract public function unpersistSession( WebRequest $request ); |
||
| 352 | |||
| 353 | /** |
||
| 354 | * Prevent future sessions for the user |
||
| 355 | * |
||
| 356 | * If the provider is capable of returning a SessionInfo with a verified |
||
| 357 | * UserInfo for the named user in some manner other than by validating |
||
| 358 | * against $user->getToken(), steps must be taken to prevent that from |
||
| 359 | * occurring in the future. This might add the username to a blacklist, or |
||
| 360 | * it might just delete whatever authentication credentials would allow |
||
| 361 | * such a session in the first place (e.g. remove all OAuth grants or |
||
| 362 | * delete record of the SSL client certificate). |
||
| 363 | * |
||
| 364 | * The intention is that the named account will never again be usable for |
||
| 365 | * normal login (i.e. there is no way to undo the prevention of access). |
||
| 366 | * |
||
| 367 | * Note that the passed user name might not exist locally (i.e. |
||
| 368 | * User::idFromName( $username ) === 0); the name should still be |
||
| 369 | * prevented, if applicable. |
||
| 370 | * |
||
| 371 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 372 | * @param string $username |
||
| 373 | */ |
||
| 374 | public function preventSessionsForUser( $username ) { |
||
| 375 | if ( !$this->canChangeUser() ) { |
||
| 376 | throw new \BadMethodCallException( |
||
| 377 | __METHOD__ . ' must be implmented when canChangeUser() is false' |
||
| 378 | ); |
||
| 379 | } |
||
| 380 | } |
||
| 381 | |||
| 382 | /** |
||
| 383 | * Invalidate existing sessions for a user |
||
| 384 | * |
||
| 385 | * If the provider has its own equivalent of CookieSessionProvider's Token |
||
| 386 | * cookie (and doesn't use User::getToken() to implement it), it should |
||
| 387 | * reset whatever token it does use here. |
||
| 388 | * |
||
| 389 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 390 | * @param User $user; |
||
|
0 ignored issues
–
show
|
|||
| 391 | */ |
||
| 392 | public function invalidateSessionsForUser( User $user ) { |
||
| 393 | } |
||
| 394 | |||
| 395 | /** |
||
| 396 | * Return the HTTP headers that need varying on. |
||
| 397 | * |
||
| 398 | * The return value is such that someone could theoretically do this: |
||
| 399 | * @code |
||
| 400 | * foreach ( $provider->getVaryHeaders() as $header => $options ) { |
||
| 401 | * $outputPage->addVaryHeader( $header, $options ); |
||
| 402 | * } |
||
| 403 | * @endcode |
||
| 404 | * |
||
| 405 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 406 | * @return array |
||
| 407 | */ |
||
| 408 | public function getVaryHeaders() { |
||
| 409 | return []; |
||
| 410 | } |
||
| 411 | |||
| 412 | /** |
||
| 413 | * Return the list of cookies that need varying on. |
||
| 414 | * @protected For use by \MediaWiki\Session\SessionManager only |
||
| 415 | * @return string[] |
||
| 416 | */ |
||
| 417 | public function getVaryCookies() { |
||
| 418 | return []; |
||
| 419 | } |
||
| 420 | |||
| 421 | /** |
||
| 422 | * Get a suggested username for the login form |
||
| 423 | * @protected For use by \MediaWiki\Session\SessionBackend only |
||
| 424 | * @param WebRequest $request |
||
| 425 | * @return string|null |
||
| 426 | */ |
||
| 427 | public function suggestLoginUsername( WebRequest $request ) { |
||
| 428 | return null; |
||
| 429 | } |
||
| 430 | |||
| 431 | /** |
||
| 432 | * Fetch the rights allowed the user when the specified session is active. |
||
| 433 | * |
||
| 434 | * This is mainly meant for allowing the user to restrict access to the account |
||
| 435 | * by certain methods; you probably want to use this with MWGrants. The returned |
||
| 436 | * rights will be intersected with the user's actual rights. |
||
| 437 | * |
||
| 438 | * @param SessionBackend $backend |
||
| 439 | * @return null|string[] Allowed user rights, or null to allow all. |
||
| 440 | */ |
||
| 441 | public function getAllowedUserRights( SessionBackend $backend ) { |
||
| 442 | if ( $backend->getProvider() !== $this ) { |
||
| 443 | // Not that this should ever happen... |
||
| 444 | throw new \InvalidArgumentException( 'Backend\'s provider isn\'t $this' ); |
||
| 445 | } |
||
| 446 | |||
| 447 | return null; |
||
| 448 | } |
||
| 449 | |||
| 450 | /** |
||
| 451 | * @note Only override this if it makes sense to instantiate multiple |
||
| 452 | * instances of the provider. Value returned must be unique across |
||
| 453 | * configured providers. If you override this, you'll likely need to |
||
| 454 | * override self::describeMessage() as well. |
||
| 455 | * @return string |
||
| 456 | */ |
||
| 457 | public function __toString() { |
||
| 458 | return get_class( $this ); |
||
| 459 | } |
||
| 460 | |||
| 461 | /** |
||
| 462 | * Return a Message identifying this session type |
||
| 463 | * |
||
| 464 | * This default implementation takes the class name, lowercases it, |
||
| 465 | * replaces backslashes with dashes, and prefixes 'sessionprovider-' to |
||
| 466 | * determine the message key. For example, MediaWiki\Session\CookieSessionProvider |
||
| 467 | * produces 'sessionprovider-mediawiki-session-cookiesessionprovider'. |
||
| 468 | * |
||
| 469 | * @note If self::__toString() is overridden, this will likely need to be |
||
| 470 | * overridden as well. |
||
| 471 | * @warning This will be called early during MediaWiki startup. Do not |
||
| 472 | * use $wgUser, $wgLang, $wgOut, $wgParser, or their equivalents via |
||
| 473 | * RequestContext from this method! |
||
| 474 | * @return \Message |
||
| 475 | */ |
||
| 476 | protected function describeMessage() { |
||
| 477 | return wfMessage( |
||
| 478 | 'sessionprovider-' . str_replace( '\\', '-', strtolower( get_class( $this ) ) ) |
||
| 479 | ); |
||
| 480 | } |
||
| 481 | |||
| 482 | public function describe( Language $lang ) { |
||
| 483 | $msg = $this->describeMessage(); |
||
| 484 | $msg->inLanguage( $lang ); |
||
| 485 | if ( $msg->isDisabled() ) { |
||
| 486 | $msg = wfMessage( 'sessionprovider-generic', (string)$this )->inLanguage( $lang ); |
||
| 487 | } |
||
| 488 | return $msg->plain(); |
||
| 489 | } |
||
| 490 | |||
| 491 | public function whyNoSession() { |
||
| 492 | return null; |
||
| 493 | } |
||
| 494 | |||
| 495 | /** |
||
| 496 | * Hash data as a session ID |
||
| 497 | * |
||
| 498 | * Generally this will only be used when self::persistsSessionId() is false and |
||
| 499 | * the provider has to base the session ID on the verified user's identity |
||
| 500 | * or other static data. The SessionInfo should then typically have the |
||
| 501 | * 'forceUse' flag set to avoid persistent session failure if validation of |
||
| 502 | * the stored data fails. |
||
| 503 | * |
||
| 504 | * @param string $data |
||
| 505 | * @param string|null $key Defaults to $this->config->get( 'SecretKey' ) |
||
| 506 | * @return string |
||
| 507 | */ |
||
| 508 | final protected function hashToSessionId( $data, $key = null ) { |
||
| 509 | if ( !is_string( $data ) ) { |
||
| 510 | throw new \InvalidArgumentException( |
||
| 511 | '$data must be a string, ' . gettype( $data ) . ' was passed' |
||
| 512 | ); |
||
| 513 | } |
||
| 514 | if ( $key !== null && !is_string( $key ) ) { |
||
| 515 | throw new \InvalidArgumentException( |
||
| 516 | '$key must be a string or null, ' . gettype( $key ) . ' was passed' |
||
| 517 | ); |
||
| 518 | } |
||
| 519 | |||
| 520 | $hash = \MWCryptHash::hmac( "$this\n$data", $key ?: $this->config->get( 'SecretKey' ), false ); |
||
| 521 | if ( strlen( $hash ) < 32 ) { |
||
| 522 | // Should never happen, even md5 is 128 bits |
||
| 523 | // @codeCoverageIgnoreStart |
||
| 524 | throw new \UnexpectedValueException( 'Hash fuction returned less than 128 bits' ); |
||
| 525 | // @codeCoverageIgnoreEnd |
||
| 526 | } |
||
| 527 | if ( strlen( $hash ) >= 40 ) { |
||
| 528 | $hash = \Wikimedia\base_convert( $hash, 16, 32, 32 ); |
||
| 529 | } |
||
| 530 | return substr( $hash, -32 ); |
||
| 531 | } |
||
| 532 | |||
| 533 | } |
||
| 534 |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italyis not defined by the methodfinale(...).The most likely cause is that the parameter was removed, but the annotation was not.