| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Session API: WP_Session_Tokens class | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package WordPress | 
					
						
							|  |  |  |  * @subpackage Session | 
					
						
							|  |  |  |  * @since 4.7.0 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Abstract class for managing user session tokens. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @since 4.0.0 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | abstract class WP_Session_Tokens { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * User ID. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * @var int User ID. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	protected $user_id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Protected constructor. Use the `get_instance()` method to get the instance. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param int $user_id User whose session to manage. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	protected function __construct( $user_id ) { | 
					
						
							|  |  |  | 		$this->user_id = $user_id; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Retrieves a session manager instance for a user. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * This method contains a {@see 'session_token_manager'} filter, allowing a plugin to swap out | 
					
						
							|  |  |  | 	 * the session manager for a subclass of `WP_Session_Tokens`. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param int $user_id User whose session to manage. | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * @return WP_Session_Tokens The session object, which is by default an instance of | 
					
						
							|  |  |  | 	 *                           the `WP_User_Meta_Session_Tokens` class. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	final public static function get_instance( $user_id ) { | 
					
						
							|  |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * Filters the class name for the session token manager. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 * | 
					
						
							|  |  |  | 		 * @since 4.0.0 | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * @param string $session Name of class to use as the manager. | 
					
						
							|  |  |  | 		 *                        Default 'WP_User_Meta_Session_Tokens'. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		$manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' ); | 
					
						
							|  |  |  | 		return new $manager( $user_id ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Hashes the given session token for storage. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param string $token Session token to hash. | 
					
						
							|  |  |  | 	 * @return string A hash of the session token (a verifier). | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final private function hash_token( $token ) { | 
					
						
							|  |  |  | 		// If ext/hash is not present, use sha1() instead.
 | 
					
						
							|  |  |  | 		if ( function_exists( 'hash' ) ) { | 
					
						
							|  |  |  | 			return hash( 'sha256', $token ); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			return sha1( $token ); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Retrieves a user's session for the given token. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * @param string $token Session token. | 
					
						
							|  |  |  | 	 * @return array|null The session, or null if it does not exist. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	final public function get( $token ) { | 
					
						
							|  |  |  | 		$verifier = $this->hash_token( $token ); | 
					
						
							|  |  |  | 		return $this->get_session( $verifier ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Validates the given session token for authenticity and validity. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * Checks that the given token is present and hasn't expired. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param string $token Token to verify. | 
					
						
							|  |  |  | 	 * @return bool Whether the token is valid for the user. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final public function verify( $token ) { | 
					
						
							|  |  |  | 		$verifier = $this->hash_token( $token ); | 
					
						
							|  |  |  | 		return (bool) $this->get_session( $verifier ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Generates a session token and attaches session information to it. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * A session token is a long, random string. It is used in a cookie | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * to link that cookie to an expiration time and to ensure the cookie | 
					
						
							|  |  |  | 	 * becomes invalidated when the user logs out. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * This function generates a token and stores it with the associated | 
					
						
							|  |  |  | 	 * expiration time (and potentially other session information via the | 
					
						
							|  |  |  | 	 * {@see 'attach_session_information'} filter). | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param int $expiration Session expiration timestamp. | 
					
						
							|  |  |  | 	 * @return string Session token. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final public function create( $expiration ) { | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * Filters the information attached to the newly created session. | 
					
						
							|  |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		 * Can be used to attach further information to a session. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		 * | 
					
						
							|  |  |  | 		 * @since 4.0.0 | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * @param array $session Array of extra data. | 
					
						
							|  |  |  | 		 * @param int   $user_id User ID. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		$session               = apply_filters( 'attach_session_information', array(), $this->user_id ); | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		$session['expiration'] = $expiration; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// IP address.
 | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		if ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) { | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 			$session['ip'] = $_SERVER['REMOTE_ADDR']; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// User-agent.
 | 
					
						
							|  |  |  | 		if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) { | 
					
						
							|  |  |  | 			$session['ua'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] ); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Timestamp
 | 
					
						
							|  |  |  | 		$session['login'] = time(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$token = wp_generate_password( 43, false, false ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->update( $token, $session ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $token; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Updates the data for the session with the given token. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param string $token Session token to update. | 
					
						
							|  |  |  | 	 * @param array  $session Session information. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final public function update( $token, $session ) { | 
					
						
							|  |  |  | 		$verifier = $this->hash_token( $token ); | 
					
						
							|  |  |  | 		$this->update_session( $verifier, $session ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Destroys the session with the given token. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param string $token Session token to destroy. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final public function destroy( $token ) { | 
					
						
							|  |  |  | 		$verifier = $this->hash_token( $token ); | 
					
						
							|  |  |  | 		$this->update_session( $verifier, null ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Destroys all sessions for this user except the one with the given token (presumably the one in use). | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param string $token_to_keep Session token to keep. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final public function destroy_others( $token_to_keep ) { | 
					
						
							|  |  |  | 		$verifier = $this->hash_token( $token_to_keep ); | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 		$session  = $this->get_session( $verifier ); | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 		if ( $session ) { | 
					
						
							|  |  |  | 			$this->destroy_other_sessions( $verifier ); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			$this->destroy_all_sessions(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Determines whether a session is still valid, based on its expiration timestamp. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param array $session Session to check. | 
					
						
							|  |  |  | 	 * @return bool Whether session is valid. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final protected function is_still_valid( $session ) { | 
					
						
							|  |  |  | 		return $session['expiration'] >= time(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Destroys all sessions for a user. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final public function destroy_all() { | 
					
						
							|  |  |  | 		$this->destroy_all_sessions(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Destroys all sessions for all users. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	final public static function destroy_all_for_all_users() { | 
					
						
							|  |  |  | 		/** This filter is documented in wp-includes/class-wp-session-tokens.php */ | 
					
						
							|  |  |  | 		$manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' ); | 
					
						
							|  |  |  | 		call_user_func( array( $manager, 'drop_sessions' ) ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Retrieves all sessions for a user. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * @return array Sessions for a user. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	final public function get_all() { | 
					
						
							|  |  |  | 		return array_values( $this->get_sessions() ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Retrieves all sessions of the user. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * @return array Sessions of the user. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	abstract protected function get_sessions(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Retrieves a session based on its verifier (token hash). | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * @param string $verifier Verifier for the session to retrieve. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * @return array|null The session, or null if it does not exist. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	abstract protected function get_session( $verifier ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Updates a session based on its verifier (token hash). | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Omitting the second argument destroys the session. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * @param string $verifier Verifier for the session to update. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * @param array  $session  Optional. Session. Omitting this argument destroys the session. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	abstract protected function update_session( $verifier, $session = null ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Destroys all sessions for this user, except the single session with the given verifier. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @param string $verifier Verifier of the session to keep. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	abstract protected function destroy_other_sessions( $verifier ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Destroys all sessions for the user. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	abstract protected function destroy_all_sessions(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-04-16 20:56:22 +01:00
										 |  |  | 	 * Destroys all sessions for all users. | 
					
						
							| 
									
										
										
										
											2019-03-12 09:27:46 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @since 4.0.0 | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public static function drop_sessions() {} | 
					
						
							|  |  |  | } |