diff options
Diffstat (limited to 'plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php')
-rw-r--r-- | plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php | 297 |
1 files changed, 147 insertions, 150 deletions
diff --git a/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php b/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php index 6af6a1ef..ba57e923 100644 --- a/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php +++ b/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php @@ -112,6 +112,13 @@ class Jetpack_Core_Json_Api_Endpoints { 'permission_callback' => __CLASS__ . '::manage_modules_permission_check', ) ); + // Endpoint specific for privileged servers to request detailed debug information. + register_rest_route( 'jetpack/v4', '/connection/test-wpcom/', array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => __CLASS__ . '::jetpack_connection_test_for_external', + 'permission_callback' => __CLASS__ . '::view_jetpack_connection_test_check', + ) ); + register_rest_route( 'jetpack/v4', '/rewind', array( 'methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::get_rewind_data', @@ -184,13 +191,6 @@ class Jetpack_Core_Json_Api_Endpoints { 'permission_callback' => array( $site_endpoint , 'can_request' ), ) ); - // Get related posts of a certain site post - register_rest_route( 'jetpack/v4', '/site/posts/related', array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $site_endpoint, 'get_related_posts' ), - 'permission_callback' => array( $site_endpoint , 'can_request' ), - ) ); - // Confirm that a site in identity crisis should be in staging mode register_rest_route( 'jetpack/v4', '/identity-crisis/confirm-safe-mode', array( 'methods' => WP_REST_Server::EDITABLE, @@ -437,7 +437,7 @@ class Jetpack_Core_Json_Api_Endpoints { array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::update_service_api_key', - 'permission_callback' => __CLASS__ . '::edit_others_posts_check', + 'permission_callback' => array( 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys','edit_others_posts_check' ), 'args' => array( 'service_api_key' => array( 'required' => true, @@ -448,7 +448,7 @@ class Jetpack_Core_Json_Api_Endpoints { array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => __CLASS__ . '::delete_service_api_key', - 'permission_callback' => __CLASS__ . '::edit_others_posts_check', + 'permission_callback' => array( 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys','edit_others_posts_check' ), ), ) ); @@ -916,40 +916,131 @@ class Jetpack_Core_Json_Api_Endpoints { } /** - * Test connection status for this Jetpack site. It uses the /jetpack-blogs/%d/test-connection wpcom endpoint. + * Test connection status for this Jetpack site. * * @since 6.8.0 * * @return array|WP_Error WP_Error returned if connection test does not succeed. */ public static function jetpack_connection_test() { - $response = Jetpack_Client::wpcom_json_api_request_as_blog( - sprintf( '/jetpack-blogs/%d/test-connection', Jetpack_Options::get_option( 'id' ) ), - Jetpack_Client::WPCOM_JSON_API_VERSION + jetpack_require_lib( 'debugger' ); + $cxntests = new Jetpack_Cxn_Tests(); + + if ( $cxntests->pass() ) { + return rest_ensure_response( + array( + 'code' => 'success', + 'message' => __( 'All connection tests passed.', 'jetpack' ), + ) + ); + } else { + return $cxntests->output_fails_as_wp_error(); + } + } + + /** + * Test connection permission check method. + * + * @since 7.1.0 + * + * @return bool + */ + public static function view_jetpack_connection_test_check() { + if ( ! isset( $_GET['signature'], $_GET['timestamp'], $_GET['url'] ) ) { + return false; + } + $signature = base64_decode( $_GET['signature'] ); + + $signature_data = wp_json_encode( + array( + 'rest_route' => $_GET['rest_route'], + 'timestamp' => intval( $_GET['timestamp'] ), + 'url' => wp_unslash( $_GET['url'] ), + ) ); - if ( is_wp_error( $response ) ) { - /* translators: %1$s is the error code, %2$s is the error message */ - return new WP_Error( 'connection_test_failed', sprintf( __( 'Connection test failed (#%1$s: %2$s)', 'jetpack' ), $response->get_error_code(), $response->get_error_message() ), array( 'status' => $response->get_error_code() ) ); + if ( + ! function_exists( 'openssl_verify' ) + || ! openssl_verify( + $signature_data, + $signature, + JETPACK__DEBUGGER_PUBLIC_KEY + ) + ) { + return false; } - $body = wp_remote_retrieve_body( $response ); - if ( ! $body ) { - return new WP_Error( 'connection_test_failed', __( 'Connection test failed (empty response body)', 'jetpack' ), array( 'status' => $response->get_error_code() ) ); + // signature timestamp must be within 5min of current time + if ( abs( time() - intval( $_GET['timestamp'] ) ) > 300 ) { + return false; } - $result = json_decode( $body ); - $is_connected = (bool) $result->connected; - $message = $result->message; + return true; + } - if ( $is_connected ) { - return rest_ensure_response( array( - 'code' => 'success', - 'message' => $message, - ) ); + /** + * Test connection status for this Jetpack site, encrypt the results for decryption by a third-party. + * + * @since 7.1.0 + * + * @return array|mixed|object|WP_Error + */ + public static function jetpack_connection_test_for_external() { + // Since we are running this test for inclusion in the WP.com testing suite, let's not try to run them as part of these results. + add_filter( 'jetpack_debugger_run_self_test', '__return_false' ); + jetpack_require_lib( 'debugger' ); + $cxntests = new Jetpack_Cxn_Tests(); + + if ( $cxntests->pass() ) { + $result = array( + 'code' => 'success', + 'message' => __( 'All connection tests passed.', 'jetpack' ), + ); } else { - return new WP_Error( 'connection_test_failed', $message, array( 'status' => $response->get_error_code() ) ); + $error = $cxntests->output_fails_as_wp_error(); // Using this so the output is similar both ways. + $errors = array(); + + // Borrowed from WP_REST_Server::error_to_response(). + foreach ( (array) $error->errors as $code => $messages ) { + foreach ( (array) $messages as $message ) { + $errors[] = array( + 'code' => $code, + 'message' => $message, + 'data' => $error->get_error_data( $code ), + ); + } + } + + $result = $errors[0]; + if ( count( $errors ) > 1 ) { + // Remove the primary error. + array_shift( $errors ); + $result['additional_errors'] = $errors; + } + } + + $result = wp_json_encode( $result ); + + $encrypted = $cxntests->encrypt_string_for_wpcom( $result ); + + if ( ! $encrypted || ! is_array( $encrypted ) ) { + return rest_ensure_response( + array( + 'code' => 'action_required', + 'message' => 'Please request results from the in-plugin debugger', + ) + ); } + + return rest_ensure_response( + array( + 'code' => 'response', + 'debug' => array( + 'data' => $encrypted['data'], + 'key' => $encrypted['key'], + ), + ) + ); } public static function rewind_data() { @@ -1252,19 +1343,8 @@ class Jetpack_Core_Json_Api_Endpoints { return new WP_Error( 'site_data_fetch_failed' ); } - // Save plan details in the database for future use without API calls - $results = json_decode( $response['body'], true ); - - if ( is_array( $results ) && isset( $results['plan'] ) ) { + Jetpack_Plan::update_from_sites_response( $response ); - // Set flag for newly purchased plan - $current_plan = Jetpack::get_active_plan(); - if ( $current_plan['product_slug'] !== $results['plan']['product_slug'] && 'jetpack_free' !== $results['plan']['product_slug'] ) { - update_option( 'show_welcome_for_new_plan', true ) ; - } - - update_option( 'jetpack_active_plan', $results['plan'] ); - } $body = wp_remote_retrieve_body( $response ); return json_decode( $body ); @@ -1510,7 +1590,6 @@ class Jetpack_Core_Json_Api_Endpoints { $visible = array( 'twitter', 'facebook', - 'google-plus-1', ); $hidden = array(); @@ -3080,9 +3159,9 @@ class Jetpack_Core_Json_Api_Endpoints { return array(); } - /** - * Get third party plugin API keys. + * Deprecated - Get third party plugin API keys. + * @deprecated * * @param WP_REST_Request $request { * Array of parameters received by request. @@ -3091,22 +3170,13 @@ class Jetpack_Core_Json_Api_Endpoints { * } */ public static function get_service_api_key( $request ) { - $service = self::validate_service_api_service( $request['service'] ); - if ( ! $service ) { - return self::service_api_invalid_service_response(); - } - $option = self::key_for_api_service( $service ); - $message = esc_html__( 'API key retrieved successfully.', 'jetpack' ); - return array( - 'code' => 'success', - 'service' => $service, - 'service_api_key' => Jetpack_Options::get_option( $option, '' ), - 'message' => $message, - ); + _deprecated_function( __METHOD__, 'jetpack-6.9.0', 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys::get_service_api_key' ); + return WPCOM_REST_API_V2_Endpoint_Service_API_Keys::get_service_api_key( $request ); } /** - * Update third party plugin API keys. + * Deprecated - Update third party plugin API keys. + * @deprecated * * @param WP_REST_Request $request { * Array of parameters received by request. @@ -3115,29 +3185,13 @@ class Jetpack_Core_Json_Api_Endpoints { * } */ public static function update_service_api_key( $request ) { - $service = self::validate_service_api_service( $request['service'] ); - if ( ! $service ) { - return self::service_api_invalid_service_response(); - } - $params = $request->get_json_params(); - $service_api_key = trim( $params['service_api_key'] ); - $option = self::key_for_api_service( $service ); - $validation = self::validate_service_api_key( $service_api_key, $service ); - if ( ! $validation['status'] ) { - return new WP_Error( 'invalid_key', esc_html__( 'Invalid API Key', 'jetpack' ), array( 'status' => 404 ) ); - } - $message = esc_html__( 'API key updated successfully.', 'jetpack' ); - Jetpack_Options::update_option( $option, $service_api_key ); - return array( - 'code' => 'success', - 'service' => $service, - 'service_api_key' => Jetpack_Options::get_option( $option, '' ), - 'message' => $message, - ); + _deprecated_function( __METHOD__, 'jetpack-6.9.0', 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys::update_service_api_key' ); + return WPCOM_REST_API_V2_Endpoint_Service_API_Keys::update_service_api_key( $request ) ; } /** - * Delete a third party plugin API key. + * Deprecated - Delete a third party plugin API key. + * @deprecated * * @param WP_REST_Request $request { * Array of parameters received by request. @@ -3146,114 +3200,57 @@ class Jetpack_Core_Json_Api_Endpoints { * } */ public static function delete_service_api_key( $request ) { - $service = self::validate_service_api_service( $request['service'] ); - if ( ! $service ) { - return self::service_api_invalid_service_response(); - } - $option = self::key_for_api_service( $service ); - Jetpack_Options::delete_option( $option ); - $message = esc_html__( 'API key deleted successfully.', 'jetpack' ); - return array( - 'code' => 'success', - 'service' => $service, - 'service_api_key' => Jetpack_Options::get_option( $option, '' ), - 'message' => $message, - ); + _deprecated_function( __METHOD__, 'jetpack-6.9.0', 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys::delete_service_api_key' ); + return WPCOM_REST_API_V2_Endpoint_Service_API_Keys::delete_service_api_key( $request ); } /** - * Validate the service provided in /service-api-keys/ endpoints. + * Deprecated - Validate the service provided in /service-api-keys/ endpoints. * To add a service to these endpoints, add the service name to $valid_services * and add '{service name}_api_key' to the non-compact return array in get_option_names(), * in class-jetpack-options.php + * @deprecated * * @param string $service The service the API key is for. * @return string Returns the service name if valid, null if invalid. */ public static function validate_service_api_service( $service = null ) { - $valid_services = array( - 'mapbox', - ); - return in_array( $service, $valid_services, true ) ? $service : null; + _deprecated_function( __METHOD__, 'jetpack-6.9.0', 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys::validate_service_api_service' ); + return WPCOM_REST_API_V2_Endpoint_Service_API_Keys::validate_service_api_service( $service ); } /** * Error response for invalid service API key requests with an invalid service. */ public static function service_api_invalid_service_response() { - return new WP_Error( - 'invalid_service', - esc_html__( 'Invalid Service', 'jetpack' ), - array( 'status' => 404 ) - ); + _deprecated_function( __METHOD__, 'jetpack-6.9.0', 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys::service_api_invalid_service_response' ); + return WPCOM_REST_API_V2_Endpoint_Service_API_Keys::service_api_invalid_service_response(); } /** - * Validate API Key + * Deprecated - Validate API Key + * @deprecated * * @param string $key The API key to be validated. * @param string $service The service the API key is for. + * */ public static function validate_service_api_key( $key = null, $service = null ) { - $validation = false; - switch ( $service ) { - case 'mapbox': - $validation = self::validate_service_api_key_mapbox( $key ); - break; - } - return $validation; + _deprecated_function( __METHOD__, 'jetpack-6.9.0', 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys::validate_service_api_key' ); + return WPCOM_REST_API_V2_Endpoint_Service_API_Keys::validate_service_api_key( $key , $service ); } /** - * Validate Mapbox API key + * Deprecated - Validate Mapbox API key * Based loosely on https://github.com/mapbox/geocoding-example/blob/master/php/MapboxTest.php + * @deprecated * * @param string $key The API key to be validated. */ public static function validate_service_api_key_mapbox( $key ) { - $status = true; - $msg = null; - $mapbox_url = sprintf( - 'https://api.mapbox.com?%s', - $key - ); - $mapbox_response = wp_safe_remote_get( esc_url_raw( $mapbox_url ) ); - $mapbox_body = wp_remote_retrieve_body( $mapbox_response ); - if ( '{"api":"mapbox"}' !== $mapbox_body ) { - $status = false; - $msg = esc_html__( 'Can\'t connect to Mapbox', 'jetpack' ); - return array( - 'status' => $status, - 'error_message' => $msg, - ); - } - $mapbox_geocode_url = esc_url_raw( - sprintf( - 'https://api.mapbox.com/geocoding/v5/mapbox.places/%s.json?access_token=%s', - '1+broadway+new+york+ny+usa', - $key - ) - ); - $mapbox_geocode_response = wp_safe_remote_get( esc_url_raw( $mapbox_geocode_url ) ); - $mapbox_geocode_body = wp_remote_retrieve_body( $mapbox_geocode_response ); - $mapbox_geocode_json = json_decode( $mapbox_geocode_body ); - if ( isset( $mapbox_geocode_json->message ) && ! isset( $mapbox_geocode_json->query ) ) { - $status = false; - $msg = $mapbox_geocode_json->message; - } - return array( - 'status' => $status, - 'error_message' => $msg, - ); - } + _deprecated_function( __METHOD__, 'jetpack-6.9.0', 'WPCOM_REST_API_V2_Endpoint_Service_API_Keys::validate_service_api_key' ); + return WPCOM_REST_API_V2_Endpoint_Service_API_Keys::validate_service_api_key_mapbox( $key ); - /** - * Create site option key for service - * - * @param string $service The service to create key for. - */ - private static function key_for_api_service( $service ) { - return $service . '_api_key'; } /** |