PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | class-jetpack-xmlrpc-methods.php +251 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,251 @@
1 +<?php
2 +/**
3 + * Jetpack XMLRPC Methods.
4 + *
5 + * Registers the Jetpack specific XMLRPC methods
6 + *
7 + * @package jetpack
8 + */
9 +
10 +use Automattic\Jetpack\Connection\Manager as Connection_Manager;
11 +use Automattic\Jetpack\Connection\Tokens;
12 +
13 +/**
14 + * XMLRPC Methods registration and callbacks
15 + */
16 +class Jetpack_XMLRPC_Methods {
17 +
18 + /**
19 + * Initialize the main hooks.
20 + */
21 + public static function init() {
22 + add_filter( 'jetpack_xmlrpc_unauthenticated_methods', array( __CLASS__, 'xmlrpc_methods' ) );
23 + add_filter( 'jetpack_xmlrpc_test_connection_response', array( __CLASS__, 'test_connection' ) );
24 + add_action( 'jetpack_xmlrpc_server_event', array( __CLASS__, 'jetpack_xmlrpc_server_event' ), 10, 4 );
25 + add_action( 'jetpack_remote_connect_end', array( __CLASS__, 'remote_connect_end' ) );
26 + add_filter( 'jetpack_xmlrpc_remote_register_redirect_uri', array( __CLASS__, 'remote_register_redirect_uri' ) );
27 + }
28 +
29 + /**
30 + * Adds Jetpack specific methods to the methods added by the Connection package.
31 + *
32 + * @param array $methods Methods added by the Connection package.
33 + */
34 + public static function xmlrpc_methods( $methods ) {
35 +
36 + $methods['jetpack.featuresAvailable'] = array( __CLASS__, 'features_available' );
37 + $methods['jetpack.featuresEnabled'] = array( __CLASS__, 'features_enabled' );
38 + $methods['jetpack.disconnectBlog'] = array( __CLASS__, 'disconnect_blog' );
39 + $methods['jetpack.jsonAPI'] = array( __CLASS__, 'json_api' );
40 +
41 + return $methods;
42 + }
43 +
44 + /**
45 + * Returns what features are available. Uses the slug of the module files.
46 + *
47 + * @deprecated 13.9
48 + * @see Jetpack_Core_Json_Api_Endpoints::get_features_available()
49 + * @return array
50 + */
51 + public static function features_available() {
52 + $raw_modules = Jetpack::get_available_modules();
53 + $modules = array();
54 + foreach ( $raw_modules as $module ) {
55 + $modules[] = Jetpack::get_module_slug( $module );
56 + }
57 +
58 + return $modules;
59 + }
60 +
61 + /**
62 + * Returns what features are enabled. Uses the slug of the modules files.
63 + *
64 + * @deprecated 13.9
65 + * @see Jetpack_Core_Json_Api_Endpoints::get_features_enabled()
66 + * @return array
67 + */
68 + public static function features_enabled() {
69 + $raw_modules = Jetpack::get_active_modules();
70 + $modules = array();
71 + foreach ( $raw_modules as $module ) {
72 + $modules[] = Jetpack::get_module_slug( $module );
73 + }
74 +
75 + return $modules;
76 + }
77 +
78 + /**
79 + * Filters the result of test_connection XMLRPC method
80 + *
81 + * @return string The current Jetpack version number
82 + */
83 + public static function test_connection() {
84 + return JETPACK__VERSION;
85 + }
86 +
87 + /**
88 + * Disconnect this blog from the connected wordpress.com account
89 + *
90 + * @return boolean
91 + */
92 + public static function disconnect_blog() {
93 +
94 + /**
95 + * Fired when we want to log an event to the Jetpack event log.
96 + *
97 + * @since 7.7.0
98 + *
99 + * @param string $code Unique name for the event.
100 + * @param string $data Optional data about the event.
101 + */
102 + do_action( 'jetpack_event_log', 'disconnect' );
103 + ( new Connection_Manager( 'jetpack' ) )->disconnect_site();
104 +
105 + return true;
106 + }
107 +
108 + /**
109 + * Serve a JSON API request.
110 + *
111 + * @param array $args request arguments.
112 + */
113 + public static function json_api( $args = array() ) {
114 + $json_api_args = $args[0];
115 + $verify_api_user_args = $args[1];
116 +
117 + $method = (string) $json_api_args[0];
118 + $url = (string) $json_api_args[1];
119 + $post_body = is_scalar( $json_api_args[2] ) ? (string) $json_api_args[2] : null;
120 + $user_details = (array) $json_api_args[4];
121 + $locale = (string) $json_api_args[5];
122 +
123 + if ( ! $verify_api_user_args ) {
124 + $user_id = 0;
125 + } elseif ( 'internal' === $verify_api_user_args[0] ) {
126 + $user_id = (int) $verify_api_user_args[1];
127 + if ( $user_id ) {
128 + $user = get_user_by( 'id', $user_id );
129 + if ( ! $user || is_wp_error( $user ) ) {
130 + return false;
131 + }
132 + }
133 + } else {
134 + $user_id = call_user_func( array( new Jetpack_XMLRPC_Server(), 'test_api_user_code' ), $verify_api_user_args );
135 + if ( ! $user_id ) {
136 + return false;
137 + }
138 + }
139 +
140 + $old_user = wp_get_current_user();
141 + wp_set_current_user( $user_id );
142 +
143 + if ( $user_id ) {
144 + $token_key = false;
145 + } else {
146 + $verified = ( new Connection_Manager() )->verify_xml_rpc_signature();
147 + $token_key = $verified['token_key'] ?? false;
148 + }
149 +
150 + $token = ( new Tokens() )->get_access_token( $user_id, $token_key );
151 + if ( ! $token || is_wp_error( $token ) ) {
152 + return false;
153 + }
154 +
155 + define( 'REST_API_REQUEST', true );
156 + define( 'WPCOM_JSON_API__BASE', 'public-api.wordpress.com/rest/v1' );
157 +
158 + require_once JETPACK__PLUGIN_DIR . 'class.json-api.php';
159 + $api = WPCOM_JSON_API::init( $method, $url, $post_body );
160 + $api->token_details['user'] = $user_details;
161 +
162 + $api->init_locale( $locale );
163 +
164 + require_once JETPACK__PLUGIN_DIR . 'class.json-api-endpoints.php';
165 +
166 + $display_errors = ini_set( 'display_errors', 0 ); // phpcs:ignore WordPress.PHP.IniSet
167 + ob_start();
168 + $api->serve( false );
169 + $output = ob_get_clean();
170 + ini_set( 'display_errors', $display_errors ); // phpcs:ignore WordPress.PHP.IniSet
171 +
172 + $nonce = wp_generate_password( 10, false );
173 + $hmac = hash_hmac( 'md5', $nonce . $output, $token->secret );
174 +
175 + wp_set_current_user( $old_user->ID ?? 0 );
176 +
177 + return array(
178 + (string) $output,
179 + (string) $nonce,
180 + $hmac,
181 + );
182 + }
183 +
184 + /**
185 + * Filters the response of the remote_provision XMLRPC method
186 + *
187 + * @param array $response The response.
188 + * @param array $request An array containing at minimum a nonce key and a local_username key.
189 + *
190 + * @since 9.8.0
191 + * @deprecated since 13.9
192 + *
193 + * @return array
194 + */
195 + public static function remote_provision_response( $response, $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
196 + _deprecated_function( __METHOD__, '13.9' );
197 + return $response;
198 + }
199 +
200 + /**
201 + * Runs Jetpack specific action in xmlrpc server events
202 + *
203 + * @param String $action the action name, i.e., 'remote_authorize'.
204 + * @param String $stage the execution stage, can be 'begin', 'success', 'error', etc.
205 + * @param array $parameters extra parameters from the event.
206 + * @param WP_User $user the acting user.
207 + * @return void
208 + */
209 + public static function jetpack_xmlrpc_server_event( $action, $stage, $parameters = array(), $user = null ) { //phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
210 + if ( 'remote_register' === $action && 'begin' === $stage ) {
211 + Jetpack::maybe_set_version_option();
212 + }
213 + }
214 +
215 + /**
216 + * Hooks into the remote_connect XMLRPC endpoint and triggers Jetpack::handle_post_authorization_actions
217 + *
218 + * @since 9.8.0
219 + * @return void
220 + */
221 + public static function remote_connect_end() {
222 + /** This filter is documented in class.jetpack-cli.php */
223 + $enable_sso = apply_filters( 'jetpack_start_enable_sso', true );
224 + Jetpack::handle_post_authorization_actions( $enable_sso, false, false );
225 + }
226 +
227 + /**
228 + * Filters the Redirect URI returned by the remote_register XMLRPC method
229 + *
230 + * @since 9.8.0
231 + *
232 + * @param string $redirect_uri The Redirect URI.
233 + * @return string
234 + */
235 + public static function remote_register_redirect_uri( $redirect_uri ) {
236 + $auto_enable_sso = ( ! ( new Connection_Manager() )->has_connected_owner() || Jetpack::is_module_active( 'sso' ) );
237 +
238 + /** This filter is documented in class.jetpack-cli.php */
239 + if ( apply_filters( 'jetpack_start_enable_sso', $auto_enable_sso ) ) {
240 + $redirect_uri = add_query_arg(
241 + array(
242 + 'action' => 'jetpack-sso',
243 + 'redirect_to' => rawurlencode( admin_url() ),
244 + ),
245 + wp_login_url() // TODO: come back to Jetpack dashboard?
246 + );
247 + }
248 +
249 + return $redirect_uri;
250 + }
251 +}