|
1 <?php |
|
2 /** |
|
3 * Error Protection API: WP_Recovery_Mode_Link_Handler class |
|
4 * |
|
5 * @package WordPress |
|
6 * @since 5.2.0 |
|
7 */ |
|
8 |
|
9 /** |
|
10 * Core class used to generate and handle recovery mode links. |
|
11 * |
|
12 * @since 5.2.0 |
|
13 */ |
|
14 class WP_Recovery_Mode_Link_Service { |
|
15 const LOGIN_ACTION_ENTER = 'enter_recovery_mode'; |
|
16 const LOGIN_ACTION_ENTERED = 'entered_recovery_mode'; |
|
17 |
|
18 /** |
|
19 * Service to generate and validate recovery mode keys. |
|
20 * |
|
21 * @since 5.2.0 |
|
22 * @var WP_Recovery_Mode_Key_Service |
|
23 */ |
|
24 private $key_service; |
|
25 |
|
26 /** |
|
27 * Service to handle cookies. |
|
28 * |
|
29 * @since 5.2.0 |
|
30 * @var WP_Recovery_Mode_Cookie_Service |
|
31 */ |
|
32 private $cookie_service; |
|
33 |
|
34 /** |
|
35 * WP_Recovery_Mode_Link_Service constructor. |
|
36 * |
|
37 * @since 5.2.0 |
|
38 * |
|
39 * @param WP_Recovery_Mode_Cookie_Service $cookie_service Service to handle setting the recovery mode cookie. |
|
40 * @param WP_Recovery_Mode_Key_Service $key_service Service to handle generating recovery mode keys. |
|
41 */ |
|
42 public function __construct( WP_Recovery_Mode_Cookie_Service $cookie_service, WP_Recovery_Mode_Key_Service $key_service ) { |
|
43 $this->cookie_service = $cookie_service; |
|
44 $this->key_service = $key_service; |
|
45 } |
|
46 |
|
47 /** |
|
48 * Generates a URL to begin recovery mode. |
|
49 * |
|
50 * Only one recovery mode URL can may be valid at the same time. |
|
51 * |
|
52 * @since 5.2.0 |
|
53 * |
|
54 * @return string Generated URL. |
|
55 */ |
|
56 public function generate_url() { |
|
57 $token = $this->key_service->generate_recovery_mode_token(); |
|
58 $key = $this->key_service->generate_and_store_recovery_mode_key( $token ); |
|
59 |
|
60 return $this->get_recovery_mode_begin_url( $token, $key ); |
|
61 } |
|
62 |
|
63 /** |
|
64 * Enters recovery mode when the user hits wp-login.php with a valid recovery mode link. |
|
65 * |
|
66 * @since 5.2.0 |
|
67 * |
|
68 * @param int $ttl Number of seconds the link should be valid for. |
|
69 */ |
|
70 public function handle_begin_link( $ttl ) { |
|
71 if ( ! isset( $GLOBALS['pagenow'] ) || 'wp-login.php' !== $GLOBALS['pagenow'] ) { |
|
72 return; |
|
73 } |
|
74 |
|
75 if ( ! isset( $_GET['action'], $_GET['rm_token'], $_GET['rm_key'] ) || self::LOGIN_ACTION_ENTER !== $_GET['action'] ) { |
|
76 return; |
|
77 } |
|
78 |
|
79 if ( ! function_exists( 'wp_generate_password' ) ) { |
|
80 require_once ABSPATH . WPINC . '/pluggable.php'; |
|
81 } |
|
82 |
|
83 $validated = $this->key_service->validate_recovery_mode_key( $_GET['rm_token'], $_GET['rm_key'], $ttl ); |
|
84 |
|
85 if ( is_wp_error( $validated ) ) { |
|
86 wp_die( $validated, '' ); |
|
87 } |
|
88 |
|
89 $this->cookie_service->set_cookie(); |
|
90 |
|
91 $url = add_query_arg( 'action', self::LOGIN_ACTION_ENTERED, wp_login_url() ); |
|
92 wp_redirect( $url ); |
|
93 die; |
|
94 } |
|
95 |
|
96 /** |
|
97 * Gets a URL to begin recovery mode. |
|
98 * |
|
99 * @since 5.2.0 |
|
100 * |
|
101 * @param string $token Recovery Mode token created by {@see generate_recovery_mode_token()}. |
|
102 * @param string $key Recovery Mode key created by {@see generate_and_store_recovery_mode_key()}. |
|
103 * @return string Recovery mode begin URL. |
|
104 */ |
|
105 private function get_recovery_mode_begin_url( $token, $key ) { |
|
106 |
|
107 $url = add_query_arg( |
|
108 array( |
|
109 'action' => self::LOGIN_ACTION_ENTER, |
|
110 'rm_token' => $token, |
|
111 'rm_key' => $key, |
|
112 ), |
|
113 wp_login_url() |
|
114 ); |
|
115 |
|
116 /** |
|
117 * Filter the URL to begin recovery mode. |
|
118 * |
|
119 * @since 5.2.0 |
|
120 * |
|
121 * @param string $url The generated recovery mode begin URL. |
|
122 * @param string $token The token used to identify the key. |
|
123 * @param string $key The recovery mode key. |
|
124 */ |
|
125 return apply_filters( 'recovery_mode_begin_url', $url, $token, $key ); |
|
126 } |
|
127 } |