Revert "Fix link prefix/suffixes around Category and Language links."
[lhc/web/wiklou.git] / includes / session / CookieSessionProvider.php
index 8d7830b..79fc720 100644 (file)
@@ -35,8 +35,8 @@ use WebRequest;
  */
 class CookieSessionProvider extends SessionProvider {
 
-       protected $params = array();
-       protected $cookieOptions = array();
+       protected $params = [];
+       protected $cookieOptions = [];
 
        /**
         * @param array $params Keys include:
@@ -51,13 +51,13 @@ class CookieSessionProvider extends SessionProvider {
         *    - secure: Cookie secure flag, defaults to $wgCookieSecure
         *    - httpOnly: Cookie httpOnly flag, defaults to $wgCookieHttpOnly
         */
-       public function __construct( $params = array() ) {
+       public function __construct( $params = [] ) {
                parent::__construct();
 
-               $params += array(
-                       'cookieOptions' => array(),
+               $params += [
+                       'cookieOptions' => [],
                        // @codeCoverageIgnoreStart
-               );
+               ];
                // @codeCoverageIgnoreEnd
 
                if ( !isset( $params['priority'] ) ) {
@@ -84,30 +84,30 @@ class CookieSessionProvider extends SessionProvider {
                parent::setConfig( $config );
 
                // @codeCoverageIgnoreStart
-               $this->params += array(
+               $this->params += [
                        // @codeCoverageIgnoreEnd
                        'callUserSetCookiesHook' => false,
                        'sessionName' =>
                                $config->get( 'SessionName' ) ?: $config->get( 'CookiePrefix' ) . '_session',
-               );
+               ];
 
                // @codeCoverageIgnoreStart
-               $this->cookieOptions += array(
+               $this->cookieOptions += [
                        // @codeCoverageIgnoreEnd
                        'prefix' => $config->get( 'CookiePrefix' ),
                        'path' => $config->get( 'CookiePath' ),
                        'domain' => $config->get( 'CookieDomain' ),
                        'secure' => $config->get( 'CookieSecure' ),
                        'httpOnly' => $config->get( 'CookieHttpOnly' ),
-               );
+               ];
        }
 
        public function provideSessionInfo( WebRequest $request ) {
                $sessionId = $this->getCookie( $request, $this->params['sessionName'], '' );
-               $info = array(
+               $info = [
                        'provider' => $this,
                        'forceHTTPS' => $this->getCookie( $request, 'forceHTTPS', '', false )
-               );
+               ];
                if ( SessionManager::validateSessionId( $sessionId ) ) {
                        $info['id'] = $sessionId;
                        $info['persisted'] = true;
@@ -125,14 +125,14 @@ class CookieSessionProvider extends SessionProvider {
                        if ( $userName !== null && $userInfo->getName() !== $userName ) {
                                $this->logger->warning(
                                        'Session "{session}" requested with mismatched UserID and UserName cookies.',
-                                       array(
+                                       [
                                                'session' => $sessionId,
-                                               'mismatch' => array(
+                                               'mismatch' => [
                                                        'userid' => $userId,
                                                        'cookie_username' => $userName,
                                                        'username' => $userInfo->getName(),
-                                               ),
-                               ) );
+                                               ],
+                               ] );
                                return null;
                        }
 
@@ -140,11 +140,11 @@ class CookieSessionProvider extends SessionProvider {
                                if ( !hash_equals( $userInfo->getToken(), $token ) ) {
                                        $this->logger->warning(
                                                'Session "{session}" requested with invalid Token cookie.',
-                                               array(
+                                               [
                                                        'session' => $sessionId,
                                                        'userid' => $userId,
                                                        'username' => $userInfo->getName(),
-                                        ) );
+                                        ] );
                                        return null;
                                }
                                $info['userInfo'] = $userInfo->verified();
@@ -164,9 +164,9 @@ class CookieSessionProvider extends SessionProvider {
                        // * anon browsing after edit or preview
                        $this->logger->debug(
                                'Session "{session}" requested without UserID cookie',
-                               array(
+                               [
                                        'session' => $info['id'],
-                       ) );
+                       ] );
                        $info['userInfo'] = UserInfo::newAnonymous();
                } else {
                        // No session ID and no user is the same as an empty session, so
@@ -200,7 +200,7 @@ class CookieSessionProvider extends SessionProvider {
 
                // Legacy hook
                if ( $this->params['callUserSetCookiesHook'] && !$user->isAnon() ) {
-                       \Hooks::run( 'UserSetCookies', array( $user, &$sessionData, &$cookies ) );
+                       \Hooks::run( 'UserSetCookies', [ $user, &$sessionData, &$cookies ] );
                }
 
                $options = $this->cookieOptions;
@@ -214,22 +214,16 @@ class CookieSessionProvider extends SessionProvider {
                }
 
                $response->setCookie( $this->params['sessionName'], $session->getId(), null,
-                       array( 'prefix' => '' ) + $options
+                       [ 'prefix' => '' ] + $options
                );
 
-               $extendedCookies = $this->config->get( 'ExtendedLoginCookies' );
-               $extendedExpiry = $this->config->get( 'ExtendedLoginCookieExpiration' );
-
                foreach ( $cookies as $key => $value ) {
                        if ( $value === false ) {
                                $response->clearCookie( $key, $options );
                        } else {
-                               if ( $extendedExpiry !== null && in_array( $key, $extendedCookies ) ) {
-                                       $expiry = time() + (int)$extendedExpiry;
-                               } else {
-                                       $expiry = 0; // Default cookie expiration
-                               }
-                               $response->setCookie( $key, (string)$value, $expiry, $options );
+                               $expirationDuration = $this->getLoginCookieExpiration( $key, $session->shouldRememberUser() );
+                               $expiration = $expirationDuration ? $expirationDuration + time() : null;
+                               $response->setCookie( $key, (string)$value, $expiration, $options );
                        }
                }
 
@@ -249,13 +243,13 @@ class CookieSessionProvider extends SessionProvider {
                        return;
                }
 
-               $cookies = array(
+               $cookies = [
                        'UserID' => false,
                        'Token' => false,
-               );
+               ];
 
                $response->clearCookie(
-                       $this->params['sessionName'], array( 'prefix' => '' ) + $this->cookieOptions
+                       $this->params['sessionName'], [ 'prefix' => '' ] + $this->cookieOptions
                );
 
                foreach ( $cookies as $key => $value ) {
@@ -276,11 +270,20 @@ class CookieSessionProvider extends SessionProvider {
        ) {
                $response = $request->response();
                if ( $set ) {
-                       $response->setCookie( 'forceHTTPS', 'true', $backend->shouldRememberUser() ? 0 : null,
-                               array( 'prefix' => '', 'secure' => false ) + $this->cookieOptions );
+                       if ( $backend->shouldRememberUser() ) {
+                               $expirationDuration = $this->getLoginCookieExpiration(
+                                       'forceHTTPS',
+                                       true
+                               );
+                               $expiration = $expirationDuration ? $expirationDuration + time() : null;
+                       } else {
+                               $expiration = null;
+                       }
+                       $response->setCookie( 'forceHTTPS', 'true', $expiration,
+                               [ 'prefix' => '', 'secure' => false ] + $this->cookieOptions );
                } else {
                        $response->clearCookie( 'forceHTTPS',
-                               array( 'prefix' => '', 'secure' => false ) + $this->cookieOptions );
+                               [ 'prefix' => '', 'secure' => false ] + $this->cookieOptions );
                }
        }
 
@@ -299,14 +302,14 @@ class CookieSessionProvider extends SessionProvider {
        }
 
        public function getVaryCookies() {
-               return array(
+               return [
                        // Vary on token and session because those are the real authn
                        // determiners. UserID and UserName don't matter without those.
                        $this->cookieOptions['prefix'] . 'Token',
                        $this->cookieOptions['prefix'] . 'LoggedOut',
                        $this->params['sessionName'],
                        'forceHTTPS',
-               );
+               ];
        }
 
        public function suggestLoginUsername( WebRequest $request ) {
@@ -324,11 +327,11 @@ class CookieSessionProvider extends SessionProvider {
         */
        protected function getUserInfoFromCookies( $request ) {
                $prefix = $this->cookieOptions['prefix'];
-               return array(
+               return [
                        $this->getCookie( $request, 'UserID', $prefix ),
                        $this->getCookie( $request, 'UserName', $prefix ),
                        $this->getCookie( $request, 'Token', $prefix ),
-               );
+               ];
        }
 
        /**
@@ -360,16 +363,16 @@ class CookieSessionProvider extends SessionProvider {
         */
        protected function cookieDataToExport( $user, $remember ) {
                if ( $user->isAnon() ) {
-                       return array(
+                       return [
                                'UserID' => false,
                                'Token' => false,
-                       );
+                       ];
                } else {
-                       return array(
+                       return [
                                'UserID' => $user->getId(),
                                'UserName' => $user->getName(),
                                'Token' => $remember ? (string)$user->getToken() : false,
-                       );
+                       ];
                }
        }
 
@@ -382,18 +385,55 @@ class CookieSessionProvider extends SessionProvider {
                // If we're calling the legacy hook, we should populate $session
                // like User::setCookies() did.
                if ( !$user->isAnon() && $this->params['callUserSetCookiesHook'] ) {
-                       return array(
+                       return [
                                'wsUserID' => $user->getId(),
                                'wsToken' => $user->getToken(),
                                'wsUserName' => $user->getName(),
-                       );
+                       ];
                }
 
-               return array();
+               return [];
        }
 
        public function whyNoSession() {
                return wfMessage( 'sessionprovider-nocookies' );
        }
 
+       public function getRememberUserDuration() {
+               return min( $this->getLoginCookieExpiration( 'UserID', true ),
+                       $this->getLoginCookieExpiration( 'Token', true ) ) ?: null;
+       }
+
+       /**
+        * Gets the list of cookies that must be set to the 'remember me' duration,
+        * if $wgExtendedLoginCookieExpiration is in use.
+        *
+        * @return string[] Array of unprefixed cookie keys
+        */
+       protected function getExtendedLoginCookies() {
+               return [ 'UserID', 'UserName', 'Token' ];
+       }
+
+       /**
+        * Returns the lifespan of the login cookies, in seconds. 0 means until the end of the session.
+        *
+        * Cookies that are session-length do not call this function.
+        *
+        * @param string $cookieName
+        * @param boolean $shouldRememberUser Whether the user should be remembered
+        *   long-term
+        * @return int Cookie expiration time in seconds; 0 for session cookies
+        */
+       protected function getLoginCookieExpiration( $cookieName, $shouldRememberUser ) {
+               $extendedCookies = $this->getExtendedLoginCookies();
+               $normalExpiration = $this->config->get( 'CookieExpiration' );
+
+               if ( $shouldRememberUser && in_array( $cookieName, $extendedCookies, true ) ) {
+                       $extendedExpiration = $this->config->get( 'ExtendedLoginCookieExpiration' );
+
+                       return ( $extendedExpiration !== null ) ? (int)$extendedExpiration : (int)$normalExpiration;
+               } else {
+                       return (int)$normalExpiration;
+               }
+       }
 }