home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress2 / wp-includes / class-wp-session-tokens.php < prev    next >
Encoding:
PHP Script  |  2017-07-26  |  7.2 KB  |  301 lines

  1. <?php
  2. /**
  3.  * Session API: WP_Session_Tokens class
  4.  *
  5.  * @package WordPress
  6.  * @subpackage Session
  7.  * @since 4.7.0
  8.  */
  9.  
  10. /**
  11.  * Abstract class for managing user session tokens.
  12.  *
  13.  * @since 4.0.0
  14.  */
  15. abstract class WP_Session_Tokens {
  16.  
  17.     /**
  18.      * User ID.
  19.      *
  20.      * @since 4.0.0
  21.      * @var int User ID.
  22.      */
  23.     protected $user_id;
  24.  
  25.     /**
  26.      * Protected constructor.
  27.      *
  28.      * @since 4.0.0
  29.      *
  30.      * @param int $user_id User whose session to manage.
  31.      */
  32.     protected function __construct( $user_id ) {
  33.         $this->user_id = $user_id;
  34.     }
  35.  
  36.     /**
  37.      * Retrieves a session token manager instance for a user.
  38.      *
  39.      * This method contains a {@see 'session_token_manager'} filter, allowing a plugin to swap out
  40.      * the session manager for a subclass of `WP_Session_Tokens`.
  41.      *
  42.      * @since 4.0.0
  43.      * @static
  44.      *
  45.      * @param int $user_id User whose session to manage.
  46.      * @return WP_User_Meta_Session_Tokens WP_User_Meta_Session_Tokens class instance by default.
  47.      */
  48.     final public static function get_instance( $user_id ) {
  49.         /**
  50.          * Filters the session token manager used.
  51.          *
  52.          * @since 4.0.0
  53.          *
  54.          * @param string $session Name of class to use as the manager.
  55.          *                        Default 'WP_User_Meta_Session_Tokens'.
  56.          */
  57.         $manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' );
  58.         return new $manager( $user_id );
  59.     }
  60.  
  61.     /**
  62.      * Hashes a session token for storage.
  63.      *
  64.      * @since 4.0.0
  65.      *
  66.      * @param string $token Session token to hash.
  67.      * @return string A hash of the session token (a verifier).
  68.      */
  69.     final private function hash_token( $token ) {
  70.         // If ext/hash is not present, use sha1() instead.
  71.         if ( function_exists( 'hash' ) ) {
  72.             return hash( 'sha256', $token );
  73.         } else {
  74.             return sha1( $token );
  75.         }
  76.     }
  77.  
  78.     /**
  79.      * Get a user's session.
  80.      *
  81.      * @since 4.0.0
  82.      *
  83.      * @param string $token Session token
  84.      * @return array User session
  85.      */
  86.     final public function get( $token ) {
  87.         $verifier = $this->hash_token( $token );
  88.         return $this->get_session( $verifier );
  89.     }
  90.  
  91.     /**
  92.      * Validate a user's session token as authentic.
  93.      *
  94.      * Checks that the given token is present and hasn't expired.
  95.      *
  96.      * @since 4.0.0
  97.      *
  98.      * @param string $token Token to verify.
  99.      * @return bool Whether the token is valid for the user.
  100.      */
  101.     final public function verify( $token ) {
  102.         $verifier = $this->hash_token( $token );
  103.         return (bool) $this->get_session( $verifier );
  104.     }
  105.  
  106.     /**
  107.      * Generate a session token and attach session information to it.
  108.      *
  109.      * A session token is a long, random string. It is used in a cookie
  110.      * link that cookie to an expiration time and to ensure the cookie
  111.      * becomes invalidated upon logout.
  112.      *
  113.      * This function generates a token and stores it with the associated
  114.      * expiration time (and potentially other session information via the
  115.      * {@see 'attach_session_information'} filter).
  116.      *
  117.      * @since 4.0.0
  118.      *
  119.      * @param int $expiration Session expiration timestamp.
  120.      * @return string Session token.
  121.      */
  122.     final public function create( $expiration ) {
  123.         /**
  124.          * Filters the information attached to the newly created session.
  125.          *
  126.          * Could be used in the future to attach information such as
  127.          * IP address or user agent to a session.
  128.          *
  129.          * @since 4.0.0
  130.          *
  131.          * @param array $session Array of extra data.
  132.          * @param int   $user_id User ID.
  133.          */
  134.         $session = apply_filters( 'attach_session_information', array(), $this->user_id );
  135.         $session['expiration'] = $expiration;
  136.  
  137.         // IP address.
  138.         if ( !empty( $_SERVER['REMOTE_ADDR'] ) ) {
  139.             $session['ip'] = $_SERVER['REMOTE_ADDR'];
  140.         }
  141.  
  142.         // User-agent.
  143.         if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
  144.             $session['ua'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] );
  145.         }
  146.  
  147.         // Timestamp
  148.         $session['login'] = time();
  149.  
  150.         $token = wp_generate_password( 43, false, false );
  151.  
  152.         $this->update( $token, $session );
  153.  
  154.         return $token;
  155.     }
  156.  
  157.     /**
  158.      * Update a session token.
  159.      *
  160.      * @since 4.0.0
  161.      *
  162.      * @param string $token Session token to update.
  163.      * @param array  $session Session information.
  164.      */
  165.     final public function update( $token, $session ) {
  166.         $verifier = $this->hash_token( $token );
  167.         $this->update_session( $verifier, $session );
  168.     }
  169.  
  170.     /**
  171.      * Destroy a session token.
  172.      *
  173.      * @since 4.0.0
  174.      *
  175.      * @param string $token Session token to destroy.
  176.      */
  177.     final public function destroy( $token ) {
  178.         $verifier = $this->hash_token( $token );
  179.         $this->update_session( $verifier, null );
  180.     }
  181.  
  182.     /**
  183.      * Destroy all session tokens for this user,
  184.      * except a single token, presumably the one in use.
  185.      *
  186.      * @since 4.0.0
  187.      *
  188.      * @param string $token_to_keep Session token to keep.
  189.      */
  190.     final public function destroy_others( $token_to_keep ) {
  191.         $verifier = $this->hash_token( $token_to_keep );
  192.         $session = $this->get_session( $verifier );
  193.         if ( $session ) {
  194.             $this->destroy_other_sessions( $verifier );
  195.         } else {
  196.             $this->destroy_all_sessions();
  197.         }
  198.     }
  199.  
  200.     /**
  201.      * Determine whether a session token is still valid,
  202.      * based on expiration.
  203.      *
  204.      * @since 4.0.0
  205.      *
  206.      * @param array $session Session to check.
  207.      * @return bool Whether session is valid.
  208.      */
  209.     final protected function is_still_valid( $session ) {
  210.         return $session['expiration'] >= time();
  211.     }
  212.  
  213.     /**
  214.      * Destroy all session tokens for a user.
  215.      *
  216.      * @since 4.0.0
  217.      */
  218.     final public function destroy_all() {
  219.         $this->destroy_all_sessions();
  220.     }
  221.  
  222.     /**
  223.      * Destroy all session tokens for all users.
  224.      *
  225.      * @since 4.0.0
  226.      * @static
  227.      */
  228.     final public static function destroy_all_for_all_users() {
  229.         /** This filter is documented in wp-includes/class-wp-session-tokens.php */
  230.         $manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' );
  231.         call_user_func( array( $manager, 'drop_sessions' ) );
  232.     }
  233.  
  234.     /**
  235.      * Retrieve all sessions of a user.
  236.      *
  237.      * @since 4.0.0
  238.      *
  239.      * @return array Sessions of a user.
  240.      */
  241.     final public function get_all() {
  242.         return array_values( $this->get_sessions() );
  243.     }
  244.  
  245.     /**
  246.      * This method should retrieve all sessions of a user, keyed by verifier.
  247.      *
  248.      * @since 4.0.0
  249.      *
  250.      * @return array Sessions of a user, keyed by verifier.
  251.      */
  252.     abstract protected function get_sessions();
  253.  
  254.     /**
  255.      * This method should look up a session by its verifier (token hash).
  256.      *
  257.      * @since 4.0.0
  258.      *
  259.      * @param string $verifier Verifier of the session to retrieve.
  260.      * @return array|null The session, or null if it does not exist.
  261.      */
  262.     abstract protected function get_session( $verifier );
  263.  
  264.     /**
  265.      * This method should update a session by its verifier.
  266.      *
  267.      * Omitting the second argument should destroy the session.
  268.      *
  269.      * @since 4.0.0
  270.      *
  271.      * @param string $verifier Verifier of the session to update.
  272.      * @param array  $session  Optional. Session. Omitting this argument destroys the session.
  273.      */
  274.     abstract protected function update_session( $verifier, $session = null );
  275.  
  276.     /**
  277.      * This method should destroy all session tokens for this user,
  278.      * except a single session passed.
  279.      *
  280.      * @since 4.0.0
  281.      *
  282.      * @param string $verifier Verifier of the session to keep.
  283.      */
  284.     abstract protected function destroy_other_sessions( $verifier );
  285.  
  286.     /**
  287.      * This method should destroy all sessions for a user.
  288.      *
  289.      * @since 4.0.0
  290.      */
  291.     abstract protected function destroy_all_sessions();
  292.  
  293.     /**
  294.      * This static method should destroy all session tokens for all users.
  295.      *
  296.      * @since 4.0.0
  297.      * @static
  298.      */
  299.     public static function drop_sessions() {}
  300. }
  301.