summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/class.jetpack-xmlrpc-server.php')
-rw-r--r--plugins/jetpack/class.jetpack-xmlrpc-server.php198
1 files changed, 167 insertions, 31 deletions
diff --git a/plugins/jetpack/class.jetpack-xmlrpc-server.php b/plugins/jetpack/class.jetpack-xmlrpc-server.php
index d4704892..e5bae9af 100644
--- a/plugins/jetpack/class.jetpack-xmlrpc-server.php
+++ b/plugins/jetpack/class.jetpack-xmlrpc-server.php
@@ -21,8 +21,10 @@ class Jetpack_XMLRPC_Server {
*/
function xmlrpc_methods( $core_methods ) {
$jetpack_methods = array(
- 'jetpack.jsonAPI' => array( $this, 'json_api' ),
- 'jetpack.verifyAction' => array( $this, 'verify_action' ),
+ 'jetpack.jsonAPI' => array( $this, 'json_api' ),
+ 'jetpack.verifyAction' => array( $this, 'verify_action' ),
+ 'jetpack.remoteRegister' => array( $this, 'remote_register' ),
+ 'jetpack.remoteProvision' => array( $this, 'remote_provision' ),
);
$this->user = $this->login();
@@ -74,14 +76,20 @@ class Jetpack_XMLRPC_Server {
return array(
'jetpack.verifyRegistration' => array( $this, 'verify_registration' ),
'jetpack.remoteAuthorize' => array( $this, 'remote_authorize' ),
- 'jetpack.remoteProvision' => array( $this, 'remote_provision' ),
+ 'jetpack.remoteRegister' => array( $this, 'remote_register' ),
);
}
function authorize_xmlrpc_methods() {
return array(
'jetpack.remoteAuthorize' => array( $this, 'remote_authorize' ),
- 'jetpack.remoteProvision' => array( $this, 'remote_provision' ),
+ );
+ }
+
+ function provision_xmlrpc_methods() {
+ return array(
+ 'jetpack.remoteRegister' => array( $this, 'remote_register' ),
+ 'jetpack.remoteProvision' => array( $this, 'remote_provision' ),
);
}
@@ -120,57 +128,185 @@ class Jetpack_XMLRPC_Server {
JetpackTracking::record_user_event( 'jpc_remote_authorize_success' );
- $response = array(
+ return array(
'result' => $result,
);
- return $response;
}
- function remote_provision( $request ) {
- if ( ! isset( $request['access_token'] ) ) {
- return $this->error( new Jetpack_Error( 'access_token_missing', sprintf( 'The required "%s" parameter is missing.', 'access_token' ), 400 ), 'jpc_remote_provision_fail' );
+ /**
+ * This XML-RPC method is called from the /jpphp/provision endpoint on WPCOM in order to
+ * register this site so that a plan can be provisioned.
+ *
+ * @param array $request An array containing at minimum nonce and local_user keys.
+ *
+ * @return WP_Error|array
+ */
+ public function remote_register( $request ) {
+ JetpackTracking::record_user_event( 'jpc_remote_register_begin', array() );
+
+ $user = $this->fetch_and_verify_local_user( $request );
+
+ if ( ! $user ) {
+ return $this->error( new WP_Error( 'input_error', __( 'Valid user is required', 'jetpack' ), 400 ), 'jpc_remote_register_fail' );
}
- if ( ! isset( $request['local_username'] ) ) {
- return $this->error( new Jetpack_Error( 'local_username_missing', sprintf( 'The required "%s" parameter is missing.', 'local_username' ), 400 ), 'jpc_remote_provision_fail' );
+ if ( is_wp_error( $user ) || is_a( $user, 'IXR_Error' ) ) {
+ return $this->error( $user, 'jpc_remote_register_fail' );
}
- $access_token = $request['access_token'];
- $local_username = $request['local_username'];
+ if ( empty( $request['nonce'] ) ) {
+ return $this->error(
+ new Jetpack_Error(
+ 'nonce_missing',
+ __( 'The required "nonce" parameter is missing.', 'jetpack' ),
+ 400
+ ),
+ 'jpc_remote_register_fail'
+ );
+ }
- $user = get_user_by( 'login', $local_username );
+ $nonce = sanitize_text_field( $request['nonce'] );
+ unset( $request['nonce'] );
- if ( ! $user ) {
- $user = get_user_by( 'email', $local_username );
+ $api_url = Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'partner_provision_nonce_check' ) );
+ $response = Jetpack_Client::_wp_remote_request(
+ esc_url_raw( add_query_arg( 'nonce', $nonce, $api_url ) ),
+ array( 'method' => 'GET' ),
+ true
+ );
+
+ if (
+ 200 !== wp_remote_retrieve_response_code( $response ) ||
+ 'OK' !== trim( wp_remote_retrieve_body( $response ) )
+ ) {
+ return $this->error(
+ new Jetpack_Error(
+ 'invalid_nonce',
+ __( 'There was an issue validating this request.', 'jetpack' ),
+ 400
+ ),
+ 'jpc_remote_register_fail'
+ );
+ }
+
+ if ( ! Jetpack_Options::get_option( 'id' ) || ! Jetpack_Options::get_option( 'blog_token' ) || ! empty( $request['force'] ) ) {
+ wp_set_current_user( $user->ID );
+
+ // This code mostly copied from Jetpack::admin_page_load.
+ Jetpack::maybe_set_version_option();
+ $registered = Jetpack::try_registration();
+ if ( is_wp_error( $registered ) ) {
+ return $this->error( $registered, 'jpc_remote_register_fail' );
+ } elseif ( ! $registered ) {
+ return $this->error(
+ new Jetpack_Error(
+ 'registration_error',
+ __( 'There was an unspecified error registering the site', 'jetpack' ),
+ 400
+ ),
+ 'jpc_remote_register_fail'
+ );
+ }
}
+ JetpackTracking::record_user_event( 'jpc_remote_register_success' );
+
+ return array(
+ 'client_id' => Jetpack_Options::get_option( 'id' )
+ );
+ }
+
+ /**
+ * This XML-RPC method is called from the /jpphp/provision endpoint on WPCOM in order to
+ * register this site so that a plan can be provisioned.
+ *
+ * @param array $request An array containing at minimum a nonce key and a local_username key.
+ *
+ * @return WP_Error|array
+ */
+ public function remote_provision( $request ) {
+ $user = $this->fetch_and_verify_local_user( $request );
+
if ( ! $user ) {
- return $this->error( new Jetpack_Error( 'user_unknown', 'User not found.', 404 ) );
+ return $this->error( new WP_Error( 'input_error', __( 'Valid user is required', 'jetpack' ), 400 ), 'jpc_remote_register_fail' );
}
- require_once JETPACK__PLUGIN_DIR . '_inc/class.jetpack-provision.php';
+ if ( is_wp_error( $user ) || is_a( $user, 'IXR_Error' ) ) {
+ return $this->error( $user, 'jpc_remote_register_fail' );
+ }
+
+ $site_icon = ( function_exists( 'has_site_icon' ) && has_site_icon() )
+ ? get_site_icon_url()
+ : false;
- wp_set_current_user( $user->ID );
+ $auto_enable_sso = ( ! Jetpack::is_active() || Jetpack::is_module_active( 'sso' ) );
- // filter allowed parameters
- $allowed_provision_args = array( 'access_token', 'wpcom_user_id', 'wpcom_user_email', 'local_username', 'plan', 'force_register', 'force_connect', 'onboarding', 'partner_tracking_id' );
- $args = array_intersect_key(
- $request,
- array_flip( $allowed_provision_args )
+ /** This filter is documented in class.jetpack-cli.php */
+ if ( apply_filters( 'jetpack_start_enable_sso', $auto_enable_sso ) ) {
+ $redirect_uri = add_query_arg(
+ array(
+ 'action' => 'jetpack-sso',
+ 'redirect_to' => rawurlencode( admin_url() ),
+ ),
+ wp_login_url() // TODO: come back to Jetpack dashboard?
+ );
+ } else {
+ $redirect_uri = admin_url();
+ }
+
+ // Generate secrets.
+ $role = Jetpack::translate_user_to_role( $user );
+ $secrets = Jetpack::init()->generate_secrets( 'authorize', $user->ID );
+
+ $response = array(
+ 'jp_version' => JETPACK__VERSION,
+ 'redirect_uri' => $redirect_uri,
+ 'user_id' => $user->ID,
+ 'user_email' => $user->user_email,
+ 'user_login' => $user->user_login,
+ 'scope' => Jetpack::sign_role( $role, $user->ID ),
+ 'secret' => $secrets['secret_1'],
+ 'is_active' => Jetpack::is_active(),
);
- $result = Jetpack_Provision::partner_provision( $access_token, $args );
+ if ( $site_icon ) {
+ $response['site_icon'] = $site_icon;
+ }
- if ( is_wp_error( $result ) ) {
- return $this->error( $result, 'jpc_remote_provision_fail' );
+ if ( ! empty( $request['onboarding'] ) ) {
+ Jetpack::create_onboarding_token();
+ $response['onboarding_token'] = Jetpack_Options::get_option( 'onboarding' );
}
- // this is to prevent us from returning the access_token secret via a potentially unsecured channel.
- if ( isset( $result->access_token ) && ! empty( $result->access_token ) ) {
- unset( $result->access_token );
+ return $response;
+ }
+
+ private function fetch_and_verify_local_user( $request ) {
+ if ( empty( $request['local_user'] ) ) {
+ return $this->error(
+ new Jetpack_Error(
+ 'local_user_missing',
+ __( 'The required "local_user" parameter is missing.', 'jetpack' ),
+ 400
+ ),
+ 'jpc_remote_provision_fail'
+ );
+ }
+
+ // local user is used to look up by login, email or ID
+ $local_user_info = $request['local_user'];
+
+ $user = get_user_by( 'login', $local_user_info );
+
+ if ( ! $user ) {
+ $user = get_user_by( 'email', $local_user_info );
+ }
+
+ if ( ! $user ) {
+ $user = get_user_by( 'ID', $local_user_info );
}
- return $result;
+ return $user;
}
private function tracks_record_error( $name, $error, $user = null ) {