diff options
Diffstat (limited to 'plugins/jetpack/class.jetpack-xmlrpc-server.php')
-rw-r--r-- | plugins/jetpack/class.jetpack-xmlrpc-server.php | 67 |
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; |