/**
* String Some punctuation to prevent editing from broken text-mangling proxies.
+ * @deprecated since 1.27, use \\MediaWiki\\Session\\Token::SUFFIX
* @ingroup Constants
*/
-define( 'EDIT_TOKEN_SUFFIX', '+\\' );
+define( 'EDIT_TOKEN_SUFFIX', MediaWiki\Session\Token::SUFFIX );
/**
* The User object encapsulates all of the user-specific settings (user_id,
/**
* Global constant made accessible as class constants so that autoloader
* magic can be used.
+ * @deprecated since 1.27, use \\MediaWiki\\Session\\Token::SUFFIX
*/
const EDIT_TOKEN_SUFFIX = EDIT_TOKEN_SUFFIX;
// If this is called too early, things are likely to break.
if ( $this->mFrom === 'session' && empty( $wgFullyInitialised ) ) {
\MediaWiki\Logger\LoggerFactory::getInstance( 'session' )
- ->warning( 'User::loadFromSession called before the end of Setup.php' );
+ ->warning( 'User::loadFromSession called before the end of Setup.php', array(
+ 'exception' => new Exception( 'User::loadFromSession called before the end of Setup.php' ),
+ ) );
$this->loadDefaults();
$this->mLoadedItems = $oldLoadedItems;
return;
$this->mOptionOverrides = null;
$this->mOptionsLoaded = false;
- $request = $this->getRequest();
- $loggedOut = $request ? $request->getSession()->getLoggedOutTimestamp() : 0;
+ $loggedOut = $this->mRequest ? $this->mRequest->getSession()->getLoggedOutTimestamp() : 0;
if ( $loggedOut !== 0 ) {
$this->mTouched = wfTimestamp( TS_MW, $loggedOut );
} else {
$all = false;
}
- if ( isset( $row->user_email ) ) {
- $this->mEmail = $row->user_email;
+ if ( isset( $row->user_touched ) ) {
$this->mTouched = wfTimestamp( TS_MW, $row->user_touched );
- $this->mToken = $row->user_token;
- if ( $this->mToken == '' ) {
+ } else {
+ $all = false;
+ }
+
+ if ( isset( $row->user_token ) ) {
+ // The definition for the column is binary(32), so trim the NULs
+ // that appends. The previous definition was char(32), so trim
+ // spaces too.
+ $this->mToken = rtrim( $row->user_token, " \0" );
+ if ( $this->mToken === '' ) {
$this->mToken = null;
}
+ } else {
+ $all = false;
+ }
+
+ if ( isset( $row->user_email ) ) {
+ $this->mEmail = $row->user_email;
$this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $row->user_email_authenticated );
$this->mEmailToken = $row->user_email_token;
$this->mEmailTokenExpires = wfTimestampOrNull( TS_MW, $row->user_email_token_expires );
}
$this->getWatchedItem( $title )->resetNotificationTimestamp(
- $force, $oldid, WatchedItem::DEFERRED
+ $force, $oldid
);
}
}
/**
- * Internal implementation for self::getEditToken() and
- * self::matchEditToken().
+ * Initialize (if necessary) and return a session token value
+ * which can be used in edit forms to show that the user's
+ * login credentials aren't being hijacked with a foreign form
+ * submission.
*
- * @param string|array $salt
- * @param WebRequest $request
- * @param string|int $timestamp
- * @return string
+ * @since 1.27
+ * @param string|array $salt Array of Strings Optional function-specific data for hashing
+ * @param WebRequest|null $request WebRequest object to use or null to use $wgRequest
+ * @return MediaWiki\\Session\\Token The new edit token
*/
- private function getEditTokenAtTimestamp( $salt, $request, $timestamp ) {
+ public function getEditTokenObject( $salt = '', $request = null ) {
if ( $this->isAnon() ) {
- return self::EDIT_TOKEN_SUFFIX;
- } else {
- $token = $request->getSessionData( 'wsEditToken' );
- if ( $token === null ) {
- $token = MWCryptRand::generateHex( 32 );
- $request->setSessionData( 'wsEditToken', $token );
- }
- if ( is_array( $salt ) ) {
- $salt = implode( '|', $salt );
- }
- return hash_hmac( 'md5', $timestamp . $salt, $token, false ) .
- dechex( $timestamp ) .
- self::EDIT_TOKEN_SUFFIX;
+ return new LoggedOutEditToken();
+ }
+
+ if ( !$request ) {
+ $request = $this->getRequest();
}
+ return $request->getSession()->getToken( $salt );
}
/**
* submission.
*
* @since 1.19
- *
* @param string|array $salt Array of Strings Optional function-specific data for hashing
* @param WebRequest|null $request WebRequest object to use or null to use $wgRequest
* @return string The new edit token
*/
public function getEditToken( $salt = '', $request = null ) {
- return $this->getEditTokenAtTimestamp(
- $salt, $request ?: $this->getRequest(), wfTimestamp()
- );
+ return $this->getEditTokenObject( $salt, $request )->toString();
}
/**
* Get the embedded timestamp from a token.
+ * @deprecated since 1.27, use \\MediaWiki\\Session\\Token::getTimestamp instead.
* @param string $val Input token
* @return int|null
*/
public static function getEditTokenTimestamp( $val ) {
- $suffixLen = strlen( self::EDIT_TOKEN_SUFFIX );
- if ( strlen( $val ) <= 32 + $suffixLen ) {
- return null;
- }
-
- return hexdec( substr( $val, 32, -$suffixLen ) );
+ wfDeprecated( __METHOD__, '1.27' );
+ return MediaWiki\Session\Token::getTimestamp( $val );
}
/**
* @return bool Whether the token matches
*/
public function matchEditToken( $val, $salt = '', $request = null, $maxage = null ) {
- if ( $this->isAnon() ) {
- return $val === self::EDIT_TOKEN_SUFFIX;
- }
-
- $timestamp = self::getEditTokenTimestamp( $val );
- if ( $timestamp === null ) {
- return false;
- }
- if ( $maxage !== null && $timestamp < wfTimestamp() - $maxage ) {
- // Expired token
- return false;
- }
-
- $sessionToken = $this->getEditTokenAtTimestamp(
- $salt, $request ?: $this->getRequest(), $timestamp
- );
-
- if ( !hash_equals( $sessionToken, $val ) ) {
- wfDebug( "User::matchEditToken: broken session data\n" );
- }
-
- return hash_equals( $sessionToken, $val );
+ return $this->getEditTokenObject( $salt, $request )->match( $val, $maxage );
}
/**