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.php67
1 files changed, 63 insertions, 4 deletions
diff --git a/plugins/jetpack/class.jetpack-xmlrpc-server.php b/plugins/jetpack/class.jetpack-xmlrpc-server.php
index c775dd7e..d7b22547 100644
--- a/plugins/jetpack/class.jetpack-xmlrpc-server.php
+++ b/plugins/jetpack/class.jetpack-xmlrpc-server.php
@@ -70,14 +70,52 @@ class Jetpack_XMLRPC_Server {
function bootstrap_xmlrpc_methods() {
return array(
'jetpack.verifyRegistration' => array( $this, 'verify_registration' ),
+ 'jetpack.remoteAuthorize' => array( $this, 'remote_authorize' ),
);
}
+ function authorize_xmlrpc_methods() {
+ return array( 'jetpack.remoteAuthorize' => array( $this, 'remote_authorize' ) );
+ }
+
+ function remote_authorize( $request ) {
+ foreach( array( 'secret', 'state', 'redirect_uri', 'code' ) as $required ) {
+ if ( ! isset( $request[ $required ] ) || empty( $request[ $required ] ) ) {
+ return $this->error( new Jetpack_Error( 'missing_parameter', 'One or more parameters is missing from the request.', 400 ) );
+ }
+ }
+
+ if ( ! get_user_by( 'id', $request['state'] ) ) {
+ return $this->error( new Jetpack_Error( 'user_unknown', 'User not found.', 404 ) );
+ }
+
+ if ( Jetpack::is_active() && Jetpack::is_user_connected( $request['state'] ) ) {
+ return $this->error( new Jetpack_Error( 'already_connected', 'User already connected.', 400 ) );
+ }
+
+ $verified = $this->verify_action( array( 'authorize', $request['secret'], $request['state'] ) );
+
+ if ( is_a( $verified, 'IXR_Error' ) ) {
+ return $verified;
+ }
+
+ wp_set_current_user( $request['state'] );
+
+ $client_server = new Jetpack_Client_Server;
+ $result = $client_server->authorize( $request );
+
+ if ( is_wp_error( $result ) ) {
+ return $this->error( $result );
+ }
+
+ return $result;
+ }
+
/**
* Verifies that Jetpack.WordPress.com received a registration request from this site
*/
- function verify_registration( $verify_secret ) {
- return $this->verify_action( array( 'register', $verify_secret ) );
+ function verify_registration( $data ) {
+ return $this->verify_action( array( 'register', $data[0], $data[1] ) );
}
/**
@@ -89,14 +127,21 @@ class Jetpack_XMLRPC_Server {
* verify_secret_1_malformed
* verify_secrets_missing: No longer have verification secrets stored
* verify_secrets_mismatch: stored secret_1 does not match secret_1 sent by Jetpack.WordPress.com
+ *
+ * The 'authorize' and 'register' actions have additional error codes
+ *
+ * state_missing: a state ( user id ) was not supplied
+ * state_malformed: state is not the correct data type
+ * invalid_state: supplied state does not match the stored state
*/
function verify_action( $params ) {
$action = $params[0];
$verify_secret = $params[1];
+ $state = isset( $params[2] ) ? $params[2] : '';
if ( empty( $verify_secret ) ) {
return $this->error( new Jetpack_Error( 'verify_secret_1_missing', sprintf( 'The required "%s" parameter is missing.', 'secret_1' ), 400 ) );
- } else if ( !is_string( $verify_secret ) ) {
+ } else if ( ! is_string( $verify_secret ) ) {
return $this->error( new Jetpack_Error( 'verify_secret_1_malformed', sprintf( 'The required "%s" parameter is malformed.', 'secret_1' ), 400 ) );
}
@@ -106,7 +151,8 @@ class Jetpack_XMLRPC_Server {
return $this->error( new Jetpack_Error( 'verify_secrets_missing', 'Verification took too long', 400 ) );
}
- @list( $secret_1, $secret_2, $secret_eol ) = explode( ':', $secrets );
+ @list( $secret_1, $secret_2, $secret_eol, $user_id ) = explode( ':', $secrets );
+
if ( empty( $secret_1 ) || empty( $secret_2 ) || empty( $secret_eol ) || $secret_eol < time() ) {
Jetpack_Options::delete_option( $action );
return $this->error( new Jetpack_Error( 'verify_secrets_missing', 'Verification took too long', 400 ) );
@@ -117,6 +163,19 @@ class Jetpack_XMLRPC_Server {
return $this->error( new Jetpack_Error( 'verify_secrets_mismatch', 'Secret mismatch', 400 ) );
}
+ if ( in_array( $action, array( 'authorize', 'register' ) ) ) {
+ // 'authorize' and 'register' actions require further testing
+ if ( empty( $state ) ) {
+ return $this->error( new Jetpack_Error( 'state_missing', sprintf( 'The required "%s" parameter is missing.', 'state' ), 400 ) );
+ } else if ( ! ctype_digit( $state ) ) {
+ return $this->error( new Jetpack_Error( 'state_malformed', sprintf( 'The required "%s" parameter is malformed.', 'state' ), 400 ) );
+ }
+ if ( empty( $user_id ) || $user_id !== $state ) {
+ Jetpack_Options::delete_option( $action );
+ return $this->error( new Jetpack_Error( 'invalid_state', 'State is invalid', 400 ) );
+ }
+ }
+
Jetpack_Options::delete_option( $action );
return $secret_2;