PATH:
home
/
lab2454c
/
sothebankuab.com
/
wp-content
/
plugins
/
jetpack
/
vendor
/
automattic
/
jetpack-connection
/
src
<?php /** * Sets up the Connection REST API endpoints. * * @package automattic/jetpack-connection */ namespace Automattic\Jetpack\Connection; use Automattic\Jetpack\Redirect; use Automattic\Jetpack\Status; use Jetpack_XMLRPC_Server; use WP_Error; use WP_REST_Request; use WP_REST_Response; use WP_REST_Server; /** * Registers the REST routes for Connections. */ class REST_Connector { /** * The Connection Manager. * * @var Manager */ private $connection; /** * This property stores the localized "Insufficient Permissions" error message. * * @var string Generic error message when user is not allowed to perform an action. */ private static $user_permissions_error_msg; const JETPACK__DEBUGGER_PUBLIC_KEY = "\r\n" . '-----BEGIN PUBLIC KEY-----' . "\r\n" . 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm+uLLVoxGCY71LS6KFc6' . "\r\n" . '1UnF6QGBAsi5XF8ty9kR3/voqfOkpW+gRerM2Kyjy6DPCOmzhZj7BFGtxSV2ZoMX' . "\r\n" . '9ZwWxzXhl/Q/6k8jg8BoY1QL6L2K76icXJu80b+RDIqvOfJruaAeBg1Q9NyeYqLY' . "\r\n" . 'lEVzN2vIwcFYl+MrP/g6Bc2co7Jcbli+tpNIxg4Z+Hnhbs7OJ3STQLmEryLpAxQO' . "\r\n" . 'q8cbhQkMx+FyQhxzSwtXYI/ClCUmTnzcKk7SgGvEjoKGAmngILiVuEJ4bm7Q1yok' . "\r\n" . 'xl9+wcfW6JAituNhml9dlHCWnn9D3+j8pxStHihKy2gVMwiFRjLEeD8K/7JVGkb/' . "\r\n" . 'EwIDAQAB' . "\r\n" . '-----END PUBLIC KEY-----' . "\r\n"; /** * Constructor. * * @param Manager $connection The Connection Manager. */ public function __construct( Manager $connection ) { $this->connection = $connection; self::$user_permissions_error_msg = esc_html__( 'You do not have the correct user permissions to perform this action. Please contact your site admin if you think this is a mistake.', 'jetpack' ); if ( ! $this->connection->has_connected_owner() ) { // Register a site. register_rest_route( 'jetpack/v4', '/verify_registration', array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'verify_registration' ), 'permission_callback' => '__return_true', ) ); } // Authorize a remote user. register_rest_route( 'jetpack/v4', '/remote_authorize', array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::remote_authorize', 'permission_callback' => '__return_true', ) ); // Get current connection status of Jetpack. register_rest_route( 'jetpack/v4', '/connection', array( 'methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::connection_status', 'permission_callback' => '__return_true', ) ); // Get list of plugins that use the Jetpack connection. register_rest_route( 'jetpack/v4', '/connection/plugins', array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_connection_plugins' ), 'permission_callback' => __CLASS__ . '::connection_plugins_permission_check', ) ); // Full or partial reconnect in case of connection issues. register_rest_route( 'jetpack/v4', '/connection/reconnect', array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'connection_reconnect' ), 'permission_callback' => __CLASS__ . '::jetpack_reconnect_permission_check', ) ); // Register the site (get `blog_token`). register_rest_route( 'jetpack/v4', '/connection/register', array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'connection_register' ), 'permission_callback' => __CLASS__ . '::jetpack_register_permission_check', 'args' => array( 'from' => array( 'description' => __( 'Indicates where the registration action was triggered for tracking/segmentation purposes', 'jetpack' ), 'type' => 'string', ), 'registration_nonce' => array( 'description' => __( 'The registration nonce', 'jetpack' ), 'type' => 'string', 'required' => true, ), 'no_iframe' => array( 'description' => __( 'Disable In-Place connection flow and go straight to Calypso', 'jetpack' ), 'type' => 'boolean', ), 'redirect_uri' => array( 'description' => __( 'URI of the admin page where the user should be redirected after connection flow', 'jetpack' ), 'type' => 'string', ), ), ) ); // Get authorization URL. register_rest_route( 'jetpack/v4', '/connection/authorize_url', array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'connection_authorize_url' ), 'permission_callback' => __CLASS__ . '::jetpack_register_permission_check', 'args' => array( 'no_iframe' => array( 'description' => __( 'Disable In-Place connection flow and go straight to Calypso', 'jetpack' ), 'type' => 'boolean', ), 'redirect_uri' => array( 'description' => __( 'URI of the admin page where the user should be redirected after connection flow', 'jetpack' ), 'type' => 'string', ), ), ) ); register_rest_route( 'jetpack/v4', '/user-token', array( array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( static::class, 'update_user_token' ), 'permission_callback' => array( static::class, 'update_user_token_permission_check' ), 'args' => array( 'user_token' => array( 'description' => __( 'New user token', 'jetpack' ), 'type' => 'string', 'required' => true, ), 'is_connection_owner' => array( 'description' => __( 'Is connection owner', 'jetpack' ), 'type' => 'boolean', ), ), ), ) ); // Set the connection owner. register_rest_route( 'jetpack/v4', '/connection/owner', array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( static::class, 'set_connection_owner' ), 'permission_callback' => array( static::class, 'set_connection_owner_permission_check' ), 'args' => array( 'owner' => array( 'description' => __( 'New owner', 'jetpack' ), 'type' => 'integer', 'required' => true, ), ), ) ); } /** * Handles verification that a site is registered. * * @since 5.4.0 * * @param WP_REST_Request $request The request sent to the WP REST API. * * @return string|WP_Error */ public function verify_registration( WP_REST_Request $request ) { $registration_data = array( $request['secret_1'], $request['state'] ); return $this->connection->handle_registration( $registration_data ); } /** * Handles verification that a site is registered * * @since 5.4.0 * * @param WP_REST_Request $request The request sent to the WP REST API. * * @return array|wp-error */ public static function remote_authorize( $request ) { $xmlrpc_server = new Jetpack_XMLRPC_Server(); $result = $xmlrpc_server->remote_authorize( $request ); if ( is_a( $result, 'IXR_Error' ) ) { $result = new WP_Error( $result->code, $result->message ); } return $result; } /** * Get connection status for this Jetpack site. * * @since 4.3.0 * * @param bool $rest_response Should we return a rest response or a simple array. Default to rest response. * * @return WP_REST_Response|array Connection information. */ public static function connection_status( $rest_response = true ) { $status = new Status(); $connection = new Manager(); $connection_status = array( 'isActive' => $connection->is_active(), // TODO deprecate this. 'isStaging' => $status->is_staging_site(), 'isRegistered' => $connection->is_connected(), 'isUserConnected' => $connection->is_user_connected(), 'hasConnectedOwner' => $connection->has_connected_owner(), 'offlineMode' => array( 'isActive' => $status->is_offline_mode(), 'constant' => defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG, 'url' => $status->is_local_site(), /** This filter is documented in packages/status/src/class-status.php */ 'filter' => ( apply_filters( 'jetpack_development_mode', false ) || apply_filters( 'jetpack_offline_mode', false ) ), // jetpack_development_mode is deprecated. 'wpLocalConstant' => defined( 'WP_LOCAL_DEV' ) && WP_LOCAL_DEV, ), 'isPublic' => '1' == get_option( 'blog_public' ), // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison ); /** * Filters the connection status data. * * @since 9.6.0 * * @param array An array containing the connection status data. */ $connection_status = apply_filters( 'jetpack_connection_status', $connection_status ); if ( $rest_response ) { return rest_ensure_response( $connection_status ); } else { return $connection_status; } } /** * Get plugins connected to the Jetpack. * * @since 8.6.0 * * @return WP_REST_Response|WP_Error Response or error object, depending on the request result. */ public function get_connection_plugins() { $plugins = $this->connection->get_connected_plugins(); if ( is_wp_error( $plugins ) ) { return $plugins; } array_walk( $plugins, function ( &$data, $slug ) { $data['slug'] = $slug; } ); return rest_ensure_response( array_values( $plugins ) ); } /** * Verify that user can view Jetpack admin page and can activate plugins. * * @since 8.8.0 * * @return bool|WP_Error Whether user has the capability 'activate_plugins'. */ public static function activate_plugins_permission_check() { if ( current_user_can( 'activate_plugins' ) ) { return true; } return new WP_Error( 'invalid_user_permission_activate_plugins', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) ); } /** * Permission check for the connection_plugins endpoint * * @return bool|WP_Error */ public static function connection_plugins_permission_check() { if ( true === static::activate_plugins_permission_check() ) { return true; } if ( true === static::is_request_signed_by_jetpack_debugger() ) { return true; } return new WP_Error( 'invalid_user_permission_activate_plugins', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) ); } /** * Verifies if the request was signed with the Jetpack Debugger key * * @param string|null $pub_key The public key used to verify the signature. Default is the Jetpack Debugger key. This is used for testing purposes. * * @return bool */ public static function is_request_signed_by_jetpack_debugger( $pub_key = null ) { // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( ! isset( $_GET['signature'], $_GET['timestamp'], $_GET['url'], $_GET['rest_route'] ) ) { return false; } // signature timestamp must be within 5min of current time. if ( abs( time() - (int) $_GET['timestamp'] ) > 300 ) { return false; } $signature = base64_decode( $_GET['signature'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode $signature_data = wp_json_encode( array( 'rest_route' => $_GET['rest_route'], 'timestamp' => (int) $_GET['timestamp'], 'url' => wp_unslash( $_GET['url'] ), ) ); if ( ! function_exists( 'openssl_verify' ) || 1 !== openssl_verify( $signature_data, $signature, $pub_key ? $pub_key : static::JETPACK__DEBUGGER_PUBLIC_KEY ) ) { return false; } // phpcs:enable WordPress.Security.NonceVerification.Recommended return true; } /** * Verify that user is allowed to disconnect Jetpack. * * @since 8.8.0 * * @return bool|WP_Error Whether user has the capability 'jetpack_disconnect'. */ public static function jetpack_reconnect_permission_check() { if ( current_user_can( 'jetpack_reconnect' ) ) { return true; } return new WP_Error( 'invalid_user_permission_jetpack_disconnect', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) ); } /** * Returns generic error message when user is not allowed to perform an action. * * @return string The error message. */ public static function get_user_permissions_error_msg() { return self::$user_permissions_error_msg; } /** * The endpoint tried to partially or fully reconnect the website to WP.com. * * @since 8.8.0 * * @return \WP_REST_Response|WP_Error */ public function connection_reconnect() { $response = array(); $next = null; $result = $this->connection->restore(); if ( is_wp_error( $result ) ) { $response = $result; } elseif ( is_string( $result ) ) { $next = $result; } else { $next = true === $result ? 'completed' : 'failed'; } switch ( $next ) { case 'authorize': $response['status'] = 'in_progress'; $response['authorizeUrl'] = $this->connection->get_authorization_url(); break; case 'completed': $response['status'] = 'completed'; /** * Action fired when reconnection has completed successfully. * * @since 9.0.0 */ do_action( 'jetpack_reconnection_completed' ); break; case 'failed': $response = new WP_Error( 'Reconnect failed' ); break; } return rest_ensure_response( $response ); } /** * Verify that user is allowed to connect Jetpack. * * @since 9.7.0 * * @return bool|WP_Error Whether user has the capability 'jetpack_connect'. */ public static function jetpack_register_permission_check() { if ( current_user_can( 'jetpack_connect' ) ) { return true; } return new WP_Error( 'invalid_user_permission_jetpack_connect', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) ); } /** * The endpoint tried to partially or fully reconnect the website to WP.com. * * @since 7.7.0 * * @param \WP_REST_Request $request The request sent to the WP REST API. * * @return \WP_REST_Response|WP_Error */ public function connection_register( $request ) { if ( ! wp_verify_nonce( $request->get_param( 'registration_nonce' ), 'jetpack-registration-nonce' ) ) { return new WP_Error( 'invalid_nonce', __( 'Unable to verify your request.', 'jetpack' ), array( 'status' => 403 ) ); } if ( isset( $request['from'] ) ) { $this->connection->add_register_request_param( 'from', (string) $request['from'] ); } $result = $this->connection->try_registration(); if ( is_wp_error( $result ) ) { return $result; } $redirect_uri = $request->get_param( 'redirect_uri' ) ? admin_url( $request->get_param( 'redirect_uri' ) ) : null; if ( class_exists( 'Jetpack' ) ) { $authorize_url = \Jetpack::build_authorize_url( $redirect_uri, ! $request->get_param( 'no_iframe' ) ); } else { if ( ! $request->get_param( 'no_iframe' ) ) { add_filter( 'jetpack_use_iframe_authorization_flow', '__return_true' ); } $authorize_url = $this->connection->get_authorization_url( null, $redirect_uri ); if ( ! $request->get_param( 'no_iframe' ) ) { remove_filter( 'jetpack_use_iframe_authorization_flow', '__return_true' ); } } /** * Filters the response of jetpack/v4/connection/register endpoint * * @param array $response Array response * @since 9.8.0 */ $response_body = apply_filters( 'jetpack_register_site_rest_response', array() ); // We manipulate the alternate URLs after the filter is applied, so they can not be overwritten. $response_body['authorizeUrl'] = $authorize_url; if ( ! empty( $response_body['alternateAuthorizeUrl'] ) ) { $response_body['alternateAuthorizeUrl'] = Redirect::get_url( $response_body['alternateAuthorizeUrl'] ); } return rest_ensure_response( $response_body ); } /** * Get the authorization URL. * * @since 9.8.0 * * @param \WP_REST_Request $request The request sent to the WP REST API. * * @return \WP_REST_Response|WP_Error */ public function connection_authorize_url( $request ) { $redirect_uri = $request->get_param( 'redirect_uri' ) ? admin_url( $request->get_param( 'redirect_uri' ) ) : null; if ( ! $request->get_param( 'no_iframe' ) ) { add_filter( 'jetpack_use_iframe_authorization_flow', '__return_true' ); } $authorize_url = $this->connection->get_authorization_url( null, $redirect_uri ); if ( ! $request->get_param( 'no_iframe' ) ) { remove_filter( 'jetpack_use_iframe_authorization_flow', '__return_true' ); } return rest_ensure_response( array( 'authorizeUrl' => $authorize_url, ) ); } /** * The endpoint tried to partially or fully reconnect the website to WP.com. * * @since 9.9.0 * * @param \WP_REST_Request $request The request sent to the WP REST API. * * @return \WP_REST_Response|WP_Error */ public static function update_user_token( $request ) { $token_parts = explode( '.', $request['user_token'] ); if ( count( $token_parts ) !== 3 || ! (int) $token_parts[2] || ! ctype_digit( $token_parts[2] ) ) { return new WP_Error( 'invalid_argument_user_token', esc_html__( 'Invalid user token is provided', 'jetpack' ) ); } $user_id = (int) $token_parts[2]; if ( false === get_userdata( $user_id ) ) { return new WP_Error( 'invalid_argument_user_id', esc_html__( 'Invalid user id is provided', 'jetpack' ) ); } $connection = new Manager(); if ( ! $connection->is_connected() ) { return new WP_Error( 'site_not_connected', esc_html__( 'Site is not connected', 'jetpack' ) ); } $is_connection_owner = isset( $request['is_connection_owner'] ) ? (bool) $request['is_connection_owner'] : ( new Manager() )->get_connection_owner_id() === $user_id; ( new Tokens() )->update_user_token( $user_id, $request['user_token'], $is_connection_owner ); /** * Fires when the user token gets successfully replaced. * * @since 9.9.0 * * @param int $user_id User ID. * @param string $token New user token. */ do_action( 'jetpack_updated_user_token', $user_id, $request['user_token'] ); return rest_ensure_response( array( 'success' => true, ) ); } /** * Verify that the API client is allowed to replace user token. * * @since 9.9.0 * * @return bool|WP_Error. */ public static function update_user_token_permission_check() { return Rest_Authentication::is_signed_with_blog_token() ? true : new WP_Error( 'invalid_permission_update_user_token', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) ); } /** * Change the connection owner. * * @since 9.9.0 * * @param WP_REST_Request $request The request sent to the WP REST API. * * @return \WP_REST_Response|WP_Error */ public static function set_connection_owner( $request ) { $new_owner_id = $request['owner']; $owner_set = ( new Manager() )->update_connection_owner( $new_owner_id ); if ( is_wp_error( $owner_set ) ) { return $owner_set; } return rest_ensure_response( array( 'code' => 'success', ) ); } /** * Check that user has permission to change the master user. * * @since 6.2.0 * @since 7.7.0 Update so that any user with jetpack_disconnect privs can set owner. * * @return bool|WP_Error True if user is able to change master user. */ public static function set_connection_owner_permission_check() { if ( current_user_can( 'jetpack_disconnect' ) ) { return true; } return new WP_Error( 'invalid_user_permission_set_connection_owner', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) ); } }
[-] class-client.php
[edit]
[-] class-xmlrpc-connector.php
[edit]
[-] class-rest-authentication.php
[edit]
[-] class-rest-connector.php
[edit]
[+]
..
[-] class-urls.php
[edit]
[-] class-xmlrpc-async-call.php
[edit]
[-] class-plugin-storage.php
[edit]
[-] class-utils.php
[edit]
[-] class-plugin.php
[edit]
[-] class-webhooks.php
[edit]
[-] class-secrets.php
[edit]
[-] class-nonce-handler.php
[edit]
[-] class-error-handler.php
[edit]
[-] interface-manager.php
[edit]
[-] class-tokens.php
[edit]
[-] class-manager.php
[edit]