author | ymh <ymh.work@gmail.com> |
Mon, 14 Oct 2019 17:39:30 +0200 | |
changeset 7 | cf61fcea0001 |
child 9 | 177826044cd9 |
permissions | -rw-r--r-- |
7
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
1 |
<?php |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
2 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
3 |
* Session API: WP_User_Meta_Session_Tokens class |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
4 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
5 |
* @package WordPress |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
6 |
* @subpackage Session |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
7 |
* @since 4.7.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
8 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
9 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
10 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
11 |
* Meta-based user sessions token manager. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
12 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
13 |
* @since 4.0.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
14 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
15 |
class WP_User_Meta_Session_Tokens extends WP_Session_Tokens { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
16 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
17 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
18 |
* Get all sessions of a user. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
19 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
20 |
* @since 4.0.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
21 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
22 |
* @return array Sessions of a user. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
23 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
24 |
protected function get_sessions() { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
25 |
$sessions = get_user_meta( $this->user_id, 'session_tokens', true ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
26 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
27 |
if ( ! is_array( $sessions ) ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
28 |
return array(); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
29 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
30 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
31 |
$sessions = array_map( array( $this, 'prepare_session' ), $sessions ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
32 |
return array_filter( $sessions, array( $this, 'is_still_valid' ) ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
33 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
34 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
35 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
36 |
* Converts an expiration to an array of session information. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
37 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
38 |
* @param mixed $session Session or expiration. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
39 |
* @return array Session. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
40 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
41 |
protected function prepare_session( $session ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
42 |
if ( is_int( $session ) ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
43 |
return array( 'expiration' => $session ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
44 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
45 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
46 |
return $session; |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
47 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
48 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
49 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
50 |
* Retrieve a session by its verifier (token hash). |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
51 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
52 |
* @since 4.0.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
53 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
54 |
* @param string $verifier Verifier of the session to retrieve. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
55 |
* @return array|null The session, or null if it does not exist |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
56 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
57 |
protected function get_session( $verifier ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
58 |
$sessions = $this->get_sessions(); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
59 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
60 |
if ( isset( $sessions[ $verifier ] ) ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
61 |
return $sessions[ $verifier ]; |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
62 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
63 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
64 |
return null; |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
65 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
66 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
67 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
68 |
* Update a session by its verifier. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
69 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
70 |
* @since 4.0.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
71 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
72 |
* @param string $verifier Verifier of the session to update. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
73 |
* @param array $session Optional. Session. Omitting this argument destroys the session. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
74 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
75 |
protected function update_session( $verifier, $session = null ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
76 |
$sessions = $this->get_sessions(); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
77 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
78 |
if ( $session ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
79 |
$sessions[ $verifier ] = $session; |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
80 |
} else { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
81 |
unset( $sessions[ $verifier ] ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
82 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
83 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
84 |
$this->update_sessions( $sessions ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
85 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
86 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
87 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
88 |
* Update a user's sessions in the usermeta table. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
89 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
90 |
* @since 4.0.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
91 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
92 |
* @param array $sessions Sessions. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
93 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
94 |
protected function update_sessions( $sessions ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
95 |
if ( $sessions ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
96 |
update_user_meta( $this->user_id, 'session_tokens', $sessions ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
97 |
} else { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
98 |
delete_user_meta( $this->user_id, 'session_tokens' ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
99 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
100 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
101 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
102 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
103 |
* Destroy all session tokens for a user, except a single session passed. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
104 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
105 |
* @since 4.0.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
106 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
107 |
* @param string $verifier Verifier of the session to keep. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
108 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
109 |
protected function destroy_other_sessions( $verifier ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
110 |
$session = $this->get_session( $verifier ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
111 |
$this->update_sessions( array( $verifier => $session ) ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
112 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
113 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
114 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
115 |
* Destroy all session tokens for a user. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
116 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
117 |
* @since 4.0.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
118 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
119 |
protected function destroy_all_sessions() { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
120 |
$this->update_sessions( array() ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
121 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
122 |
|
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
123 |
/** |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
124 |
* Destroy all session tokens for all users. |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
125 |
* |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
126 |
* @since 4.0.0 |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
127 |
* @static |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
128 |
*/ |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
129 |
public static function drop_sessions() { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
130 |
delete_metadata( 'user', 0, 'session_tokens', false, true ); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
131 |
} |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
132 |
} |