diff --git a/admin.php b/admin.php index 0a2b2e2..d8be5ff 100644 --- a/admin.php +++ b/admin.php @@ -22,7 +22,7 @@ function rest_oauth1_profile_section( $user ) { global $wpdb; - $results = $wpdb->get_col( "SELECT option_value FROM {$wpdb->options} WHERE option_name LIKE 'oauth1_access_%'", 0 ); + $results = $wpdb->get_col( "SELECT option_value FROM $wpdb->options WHERE option_name LIKE 'oauth1_access_%'" ); $approved = array(); foreach ( $results as $result ) { $row = unserialize( $result ); @@ -31,8 +31,6 @@ function rest_oauth1_profile_section( $user ) { } } - $authenticator = new WP_REST_OAuth1(); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - ?> @@ -51,6 +49,9 @@ function rest_oauth1_profile_section( $user ) { diff --git a/lib/class-wp-rest-client.php b/lib/class-wp-rest-client.php index 26a848a..b3459e0 100644 --- a/lib/class-wp-rest-client.php +++ b/lib/class-wp-rest-client.php @@ -10,12 +10,20 @@ * REST Client. */ abstract class WP_REST_Client { + + /** + * Post object. + * + * @var WP_Post + */ + protected $post; + /** * Get the client type. * * Must be overridden in subclass. * - * @return string + * @return string | WP_Error */ protected static function get_type() { return new WP_Error( 'rest_client_missing_type', __( 'Overridden class must implement get_type', 'rest_oauth1' ) ); @@ -126,7 +134,8 @@ public static function get( $id ) { return new WP_Error( 'rest_oauth1_invalid_id', __( 'Client ID is not valid.', 'rest_oauth1' ), array( 'status' => 404 ) ); } - $class = function_exists( 'get_called_class' ) ? get_called_class() : self::get_called_class(); + $class = get_called_class(); + return new $class( $post ); } @@ -137,8 +146,7 @@ public static function get( $id ) { * @return WP_Post|WP_Error */ public static function get_by_key( $key ) { - $class = function_exists( 'get_called_class' ) ? get_called_class() : self::get_called_class(); - $type = call_user_func( array( $class, 'get_type' ) ); + $type = call_user_func( array( get_called_class(), 'get_type' ) ); $query = new WP_Query(); $consumers = $query->query( @@ -159,8 +167,7 @@ public static function get_by_key( $key ) { ); if ( empty( $consumers ) || empty( $consumers[0] ) ) { - $code = is_user_logged_in() ? 403 : 401; - return new WP_Error( 'json_consumer_notfound', __( 'Consumer Key is invalid', 'rest_oauth1' ), array( 'status' => $code ) ); + return new WP_Error( 'json_consumer_notfound', __( 'Consumer Key is invalid', 'rest_oauth1' ), array( 'status' => 401 ) ); } return $consumers[0]; @@ -170,11 +177,11 @@ public static function get_by_key( $key ) { * Create a new client. * * @param array $params { . - * @type string $name Client name - * @type string $description Client description - * @type array $meta Metadata for the client (map of key => value) + * @type string $name Client name + * @type string $description Client description + * @type array $meta Metadata for the client (map of key => value) * } - * @return WP_Post|WP_Error + * @return WP_REST_Client|WP_Error */ public static function create( $params ) { $default = array( @@ -194,12 +201,12 @@ public static function create( $params ) { return $id; } - $class = function_exists( 'get_called_class' ) ? get_called_class() : self::get_called_class(); $meta = $params['meta']; + $class = get_called_class(); $meta['type'] = call_user_func( array( $class, 'get_type' ) ); // Allow types to add their own meta too. - $meta = $class::add_extra_meta( $meta, $params ); + $meta = call_user_func( array( $class, 'add_extra_meta' ), $meta, $params ); /** * Add extra meta to the consumer on creation. @@ -235,9 +242,15 @@ protected static function add_extra_meta( $meta, $params ) { //phpcs:ignore Vari /** * Shim for get_called_class() for PHP 5.2 * + * @deprecated 0.4.0 * @return string Class name. */ protected static function get_called_class() { + _deprecated_function( __METHOD__, '0.4.0', 'get_called_class()' ); + if ( function_exists( 'get_called_class' ) ) { + return get_called_class(); + } + // PHP 5.2 only. $backtrace = debug_backtrace(); // [0] WP_REST_Client::get_called_class() diff --git a/lib/class-wp-rest-oauth1-admin.php b/lib/class-wp-rest-oauth1-admin.php index 33db347..ece6651 100644 --- a/lib/class-wp-rest-oauth1-admin.php +++ b/lib/class-wp-rest-oauth1-admin.php @@ -24,6 +24,8 @@ public static function register() { */ include_once __DIR__ . '/class-wp-rest-oauth1-listtable.php'; + $class = get_class(); + $hook = add_users_page( // Page title. __( 'Registered OAuth Applications', 'rest_oauth1' ), @@ -34,10 +36,10 @@ public static function register() { // Menu slug. self::BASE_SLUG, // Callback. - array( get_class(), 'dispatch' ) + array( $class, 'dispatch' ) ); - add_action( 'load-' . $hook, array( get_class(), 'load' ) ); + add_action( 'load-' . $hook, array( $class, 'load' ) ); } /** @@ -68,22 +70,19 @@ public static function load() { switch ( self::current_action() ) { case 'add': case 'edit': - return self::render_edit_page(); - + self::render_edit_page(); + break; case 'delete': - return self::handle_delete(); - + self::handle_delete(); + break; case 'regenerate': - return self::handle_regenerate(); - + self::handle_regenerate(); + break; default: global $wp_list_table; $wp_list_table = new WP_REST_OAuth1_ListTable(); - $wp_list_table->prepare_items(); - - return; } } @@ -91,14 +90,11 @@ public static function load() { * Render callback. */ public static function dispatch() { - switch ( self::current_action() ) { - case 'add': - case 'edit': - case 'delete': - break; - default: - self::render(); + if ( in_array( self::current_action(), array( 'add', 'edit', 'delete' ), true ) ) { + return; } + + self::render(); } /** @@ -163,19 +159,18 @@ protected static function validate_parameters( $params ) { $valid['description'] = wp_filter_post_kses( $params['description'] ); if ( empty( $params['callback'] ) ) { - return new WP_Error( 'rest_oauth1_missing_description', __( 'Consumer callback is required and must be a valid URL.', 'rest_oauth1' ) ); - } - if ( ! empty( $params['callback'] ) ) { - $valid['callback'] = $params['callback']; + return new WP_Error( 'rest_oauth1_missing_callback', __( 'Consumer callback is required and must be a valid URL.', 'rest_oauth1' ) ); } + $valid['callback'] = $params['callback']; + return $valid; } /** * Handle submission of the add page - * @param WP_User $consumer Consumer user. + * @param WP_REST_Client $consumer Consumer user. * * @return array|null List of errors. Issues a redirect and exits on success. */ @@ -197,8 +192,6 @@ protected static function handle_edit_submit( $consumer ) { } if ( empty( $consumer ) ) { - new WP_REST_OAuth1(); - // Create the consumer. $data = array( 'name' => $params['name'], @@ -248,8 +241,9 @@ public static function render_edit_page() { } // Are we editing? - $consumer = null; - $form_action = self::get_url( 'action=add' ); + $consumer = null; + $regenerate_action = ''; + $form_action = self::get_url( 'action=add' ); if ( ! empty( $_REQUEST['id'] ) ) { $id = absint( $_REQUEST['id'] ); $consumer = WP_REST_OAuth1_Client::get( $id ); @@ -430,13 +424,15 @@ public static function handle_delete() { $client = WP_REST_OAuth1_Client::get( $id ); if ( is_wp_error( $client ) ) { wp_die( $client ); - return; } if ( ! $client->delete() ) { - $message = 'Invalid consumer ID'; - wp_die( $message ); - return; + $code = is_user_logged_in() ? 403 : 401; + wp_die( + '

' . __( 'An error has occurred.', 'rest_oauth1' ) . '

' . + '

' . __( 'Invalid consumer ID', 'rest_oauth1' ) . '

', + $code + ); } wp_safe_redirect( self::get_url( 'deleted=1' ) ); @@ -464,7 +460,13 @@ public static function handle_regenerate() { } $client = WP_REST_OAuth1_Client::get( $id ); - $client->regenerate_secret(); + if ( is_wp_error( $client ) ) { + wp_die( $client ); + } + $result = $client->regenerate_secret(); + if ( is_wp_error( $result ) ) { + wp_die( $result ); + } wp_safe_redirect( self::get_url( diff --git a/lib/class-wp-rest-oauth1-cli.php b/lib/class-wp-rest-oauth1-cli.php index 9ef2834..80a3e5b 100644 --- a/lib/class-wp-rest-oauth1-cli.php +++ b/lib/class-wp-rest-oauth1-cli.php @@ -6,6 +6,8 @@ class WP_REST_OAuth1_CLI extends WP_CLI_Command { /** + * Creates a new OAuth1 Client. + * * ## OPTIONS * * [--name=] @@ -13,11 +15,68 @@ class WP_REST_OAuth1_CLI extends WP_CLI_Command { * * [--description=] * : Consumer description + * + * [--callback=] + * : Consumer callback */ - public function add( $_, $args ) { - $consumer = WP_REST_OAuth1_Client::create( $args ); - WP_CLI::line( sprintf( 'ID: %d', $consumer->ID ) ); - WP_CLI::line( sprintf( 'Key: %s', $consumer->key ) ); - WP_CLI::line( sprintf( 'Secret: %s', $consumer->secret ) ); + public function add( $args, $assoc_args ) { + $consumer = WP_REST_OAuth1_Client::create( $assoc_args ); + if ( is_wp_error( $consumer ) ) { + WP_CLI::error( $consumer ); + } + + WP_CLI::line( + sprintf( + /* translators: %d: client ID **/ + __( 'ID: %d', 'rest_oauth1' ), + $consumer->ID + ) + ); + WP_CLI::line( + sprintf( + /* translators: %d: client key **/ + __( 'Key: %s', 'rest_oauth1' ), + $consumer->key + ) + ); + WP_CLI::line( + sprintf( + /* translators: %d: client secret **/ + __( 'Secret: %s', 'rest_oauth1' ), + $consumer->secret + ) + ); + } + + /** + * Delete a new OAuth1 Client. + * + * ## OPTIONS + * + * + * : Database ID for the client. + */ + public function delete( $args ) { + $consumer = WP_REST_OAuth1_Client::get( $args[0] ); + if ( is_wp_error( $consumer ) ) { + WP_CLI::error( $consumer ); + } + if ( ! $consumer->delete() ) { + WP_CLI::error( + sprintf( + /* translators: %d: client ID **/ + __( 'Unable to delete client with ID: %d', 'rest_oauth1' ), + $consumer->ID + ) + ); + } + + WP_CLI::success( + sprintf( + /* translators: %d: client ID **/ + __( 'Client deleted with ID: %d', 'rest_oauth1' ), + $consumer->ID + ) + ); } } diff --git a/lib/class-wp-rest-oauth1-client.php b/lib/class-wp-rest-oauth1-client.php index c6e58cd..698ed6a 100644 --- a/lib/class-wp-rest-oauth1-client.php +++ b/lib/class-wp-rest-oauth1-client.php @@ -43,6 +43,32 @@ protected static function get_type() { return 'oauth1'; } + /** + * Delete a client. + * + * @since 0.4.0 + * + * @return bool True if delete, false otherwise. + */ + public function delete() { + global $wpdb; + $results = $wpdb->get_results( "SELECT * FROM $wpdb->options WHERE option_name LIKE 'oauth1_access_%' OR option_name LIKE 'oauth1_request_%'", ARRAY_A ); + $delete_option = array(); + foreach ( $results as $result ) { + $row = unserialize( $result['option_value'] ); + if ( $this->post->ID === $row['consumer'] ) { + $delete_option[] = $result['option_name']; + } + } + + if ( (bool) wp_delete_post( $this->post->ID, true ) ) { + array_map( 'delete_option', $delete_option ); + return true; + } + + return false; + } + /** * Add extra meta to a post. * diff --git a/lib/class-wp-rest-oauth1-listtable.php b/lib/class-wp-rest-oauth1-listtable.php index 3d9b76f..f95db3e 100644 --- a/lib/class-wp-rest-oauth1-listtable.php +++ b/lib/class-wp-rest-oauth1-listtable.php @@ -43,13 +43,11 @@ public function prepare_items() { * and the value is the description. */ public function get_columns() { - $c = array( + return array( 'cb' => '', 'name' => __( 'Name', 'rest_oauth1' ), 'description' => __( 'Description', 'rest_oauth1' ), ); - - return $c; } /** diff --git a/lib/class-wp-rest-oauth1-ui.php b/lib/class-wp-rest-oauth1-ui.php index 06c56f1..b74798f 100644 --- a/lib/class-wp-rest-oauth1-ui.php +++ b/lib/class-wp-rest-oauth1-ui.php @@ -127,6 +127,8 @@ public function render_page() { } include $file; + + return null; } /** diff --git a/lib/class-wp-rest-oauth1.php b/lib/class-wp-rest-oauth1.php index 0d2e5c6..1226731 100644 --- a/lib/class-wp-rest-oauth1.php +++ b/lib/class-wp-rest-oauth1.php @@ -170,7 +170,7 @@ public function get_parameters( $require_token = true, $extra = array() ) { ), implode( ', ', $errors ) ); - return new WP_Error( 'json_oauth1_missing_parameter', $message, array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_missing_parameter', $message, array( 'status' => 401 ) ); } return $params; @@ -205,8 +205,9 @@ public function authenticate( $user ) { // Fetch user by token key. $token = $this->get_access_token( $params['oauth_token'] ); - if ( is_wp_error( $token ) ) { - $this->auth_status = $token; + if ( empty( $token ) ) { + $this->auth_status = new WP_Error( 'json_oauth1_invalid_token', __( 'Access token does not exist', 'rest_oauth1' ), array( 'status' => 401 ) ); + return null; } @@ -235,7 +236,7 @@ public function authenticate( $user ) { } /** - * Report authentication errors to the JSON API + * Report authentication errors to the JSON API. * * @param WP_Error|mixed $value Error from another authentication handler, null if we should handle it, or another value if not. * @return WP_Error|boolean|null {@see WP_JSON_Server::check_authentication} @@ -249,7 +250,7 @@ public function get_authentication_errors( $value ) { } /** - * Serve an OAuth request + * Serve an OAuth request. * * Either returns data to be served, or redirects and exits. Non-reentrant * for the `authorize` route. @@ -297,9 +298,9 @@ public function dispatch( $route ) { /** * Check a token against the database. * - * @param string $token Token object. + * @param array $token Token object. * @param string $consumer_key Consumer ID. - * @return array Array of consumer object, user object + * @return array|WP_Error Array of consumer object, user object or WP_Error on error. */ public function check_token( $token, $consumer_key ) { $this->should_attempt = false; @@ -311,7 +312,7 @@ public function check_token( $token, $consumer_key ) { } if ( ! hash_equals( (string) $token['consumer'], (string) $consumer->ID ) ) { - return new WP_Error( 'json_oauth1_consumer_mismatch', __( 'Token is not registered for the given consumer', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_consumer_mismatch', __( 'Token is not registered for the given consumer', 'rest_oauth1' ), array( 'status' => 401 ) ); } return array( $consumer, new WP_User( $token['user'] ) ); @@ -333,7 +334,7 @@ public function get_request_token( $key ) { // Check expiration. if ( $data['expiration'] < time() ) { $this->remove_request_token( $key ); - return new WP_Error( 'json_oauth1_expired_token', __( 'OAuth request token has expired', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_expired_token', __( 'OAuth request token has expired', 'rest_oauth1' ), array( 'status' => 401 ) ); } return $data; @@ -363,32 +364,32 @@ public function generate_request_token( $params ) { } // Generate token. - $key = apply_filters( 'json_oauth1_request_token_key', wp_generate_password( self::TOKEN_KEY_LENGTH, false ) ); - $data = array( + $key = apply_filters( 'json_oauth1_request_token_key', wp_generate_password( self::TOKEN_KEY_LENGTH, false ) ); + $callback = ! empty( $params['oauth_callback'] ) ? $params['oauth_callback'] : null; + $data = array( 'key' => $key, 'secret' => wp_generate_password( self::TOKEN_SECRET_LENGTH, false ), 'consumer' => $consumer->ID, 'authorized' => false, 'expiration' => time() + 24 * HOUR_IN_SECONDS, - 'callback' => null, + 'callback' => $callback, 'verifier' => null, 'user' => null, ); - $data = apply_filters( 'json_oauth1_request_token_data', $data ); + $data = apply_filters( 'json_oauth1_request_token_data', $data ); add_option( 'oauth1_request_' . $key, $data, null, 'no' ); - if ( ! empty( $params['oauth_callback'] ) ) { - $error = $this->set_request_token_callback( $key, $params['oauth_callback'] ); + if ( ! empty( $callback ) ) { + $error = $this->set_request_token_callback( $key, $callback ); if ( $error ) { return $error; } } - $data = array( + return array( 'oauth_token' => self::urlencode_rfc3986( $key ), 'oauth_token_secret' => self::urlencode_rfc3986( $data['secret'] ), 'oauth_callback_confirmed' => 'true', ); - return $data; } /** @@ -601,7 +602,7 @@ public function generate_access_token( $params ) { // Check verification. if ( true !== $token['authorized'] ) { - return new WP_Error( 'json_oauth1_unauthorized_token', __( 'OAuth token has not been authorized', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_unauthorized_token', __( 'OAuth token has not been authorized', 'rest_oauth1' ), array( 'status' => 401 ) ); } if ( ! hash_equals( (string) $params['oauth_verifier'], (string) $token['verifier'] ) ) { @@ -631,11 +632,10 @@ public function generate_access_token( $params ) { $this->remove_request_token( $params['oauth_token'] ); // Return the new token's data. - $data = array( + return array( 'oauth_token' => self::urlencode_rfc3986( $key ), 'oauth_token_secret' => self::urlencode_rfc3986( $data['secret'] ), ); - return $data; } /** @@ -647,7 +647,7 @@ public function generate_access_token( $params ) { public function revoke_access_token( $key ) { $data = $this->get_access_token( $key ); if ( empty( $data ) ) { - return new WP_Error( 'json_oauth1_invalid_token', __( 'Access token does not exist', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_invalid_token', __( 'Access token does not exist', 'rest_oauth1' ), array( 'status' => 401 ) ); } delete_option( 'oauth1_access_' . $key ); @@ -658,11 +658,11 @@ public function revoke_access_token( $key ) { /** * Verify that the consumer-provided request signature matches our generated signature, this ensures the consumer - * has a valid key/secret + * has a valid key/secret. * - * @param WP_User $consumer Consumer user. + * @param WP_Post $consumer REST Client. * @param array $oauth_params the request parameters. - * @param string $token Token object. + * @param array $token Token. * @return boolean|WP_Error True on success, error otherwise */ public function check_oauth_signature( $consumer, $oauth_params, $token = null ) { @@ -688,7 +688,7 @@ public function check_oauth_signature( $consumer, $oauth_params, $token = null ) __( 'Unknown http method: %s', 'rest_oauth1' ), $http_method ), - array( 'status' => $this->get_authorization_required_code() ) + array( 'status' => 401 ) ); } @@ -706,11 +706,11 @@ public function check_oauth_signature( $consumer, $oauth_params, $token = null ) unset( $params['oauth_signature'] ); // normalize parameter key/values. - array_walk_recursive( $params, array( $this, 'normalize_parameters' ) ); + $params = $this->normalize_parameter( $params ); // sort parameters. if ( ! uksort( $params, 'strcmp' ) ) { - return new WP_Error( 'json_oauth1_failed_parameter_sort', __( 'Invalid Signature - failed to sort parameters', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_failed_parameter_sort', __( 'Invalid Signature - failed to sort parameters', 'rest_oauth1' ), array( 'status' => 401 ) ); } $query_string = $this->create_signature_string( $params ); @@ -733,13 +733,13 @@ public function check_oauth_signature( $consumer, $oauth_params, $token = null ) break; default: - return new WP_Error( 'json_oauth1_invalid_signature_method', __( 'Signature method is invalid', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_invalid_signature_method', __( 'Signature method is invalid', 'rest_oauth1' ), array( 'status' => 401 ) ); } $signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $key, true ) ); if ( ! hash_equals( $signature, $consumer_signature ) ) { - return new WP_Error( 'json_oauth1_signature_mismatch', __( 'OAuth signature does not match', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_signature_mismatch', __( 'OAuth signature does not match', 'rest_oauth1' ), array( 'status' => 401 ) ); } return true; @@ -780,6 +780,30 @@ public function join_with_equals_sign( $params, $query_params = array(), $key = return $query_params; } + /** + * Normalize each parameter by assuming each parameter may have already been encoded, so attempt to decode, and then + * re-encode according to RFC 3986 + * + * @since 0.4.0 + * + * @see rawurlencode() + * @param array $params Parameters to normalize. + */ + protected function normalize_parameter( array $params ) { + $new_params = array(); + foreach ( $params as $key => $value ) { + $new_key = self::urlencode_rfc3986( rawurldecode( $key ) ); + if ( is_array( $value ) ) { + $new_value = $this->normalize_parameter( $value ); + } else { + $new_value = self::urlencode_rfc3986( rawurldecode( $value ) ); + } + $new_params[ $new_key ] = $new_value; + } + + return $new_params; + } + /** * Normalize each parameter by assuming each parameter may have already been encoded, so attempt to decode, and then * re-encode according to RFC 3986 @@ -790,6 +814,7 @@ public function join_with_equals_sign( $params, $query_params = array(), $key = * @param string $value Value, passed by reference. */ protected function normalize_parameters( &$key, &$value ) { + _deprecated_function( __METHOD__, '0.4.0', 'WP_REST_OAuth1::normalize_parameter()' ); $key = self::urlencode_rfc3986( rawurldecode( $key ) ); $value = self::urlencode_rfc3986( rawurldecode( $value ) ); } @@ -801,7 +826,7 @@ protected function normalize_parameters( &$key, &$value ) { * valid within 15 minutes of the current time, and a nonce is valid if it * has not been used within the last 15 minutes. * - * @param WP_User $consumer Consumer user. + * @param WP_Post $consumer Post client. * @param int $timestamp the unix timestamp for when the request was made. * @param string $nonce a unique (for the given user) 32 alphanumeric string, consumer-generated. * @return boolean|WP_Error True on success, error otherwise @@ -810,7 +835,7 @@ public function check_oauth_timestamp_and_nonce( $consumer, $timestamp, $nonce ) $valid_window = apply_filters( 'json_oauth1_timestamp_window', 15 * MINUTE_IN_SECONDS ); if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) ) { - return new WP_Error( 'json_oauth1_invalid_timestamp', __( 'Invalid timestamp', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_invalid_timestamp', __( 'Invalid timestamp', 'rest_oauth1' ), array( 'status' => 401 ) ); } $used_nonces = $consumer->nonces; @@ -820,7 +845,7 @@ public function check_oauth_timestamp_and_nonce( $consumer, $timestamp, $nonce ) } if ( in_array( $nonce, $used_nonces, true ) ) { - return new WP_Error( 'json_oauth1_nonce_already_used', __( 'Invalid nonce - nonce has already been used', 'rest_oauth1' ), array( 'status' => $this->get_authorization_required_code() ) ); + return new WP_Error( 'json_oauth1_nonce_already_used', __( 'Invalid nonce - nonce has already been used', 'rest_oauth1' ), array( 'status' => 401 ) ); } $used_nonces[ $timestamp ] = $nonce; @@ -852,13 +877,4 @@ public function check_oauth_timestamp_and_nonce( $consumer, $timestamp, $nonce ) protected static function urlencode_rfc3986( $value ) { return str_replace( array( '+', '%7E' ), array( ' ', '~' ), rawurlencode( $value ) ); } - - /** - * Returns a contextual HTTP error code for authorization failure. - * - * @return int 401 if the user is not logged in, 403 if the user is logged in. - */ - protected function get_authorization_required_code() { - return is_user_logged_in() ? 403 : 401; - } } diff --git a/oauth-server.php b/oauth-server.php index a1bbe39..5753d48 100644 --- a/oauth-server.php +++ b/oauth-server.php @@ -128,6 +128,9 @@ function rest_oauth1_loaded() { $authenticator = new WP_REST_OAuth1(); $response = $authenticator->dispatch( $GLOBALS['wp']->query_vars['rest_oauth1'] ); + nocache_headers(); + header( 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' ); + if ( is_wp_error( $response ) ) { $error_data = $response->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['status'] ) ) { @@ -141,7 +144,6 @@ function rest_oauth1_loaded() { die(); } - header( 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' ); $response = http_build_query( $response, '', '&' ); echo $response; @@ -192,7 +194,15 @@ function rest_oauth1_load_authorize_page() { function rest_oauth1_activation( $network_wide ) { if ( function_exists( 'is_multisite' ) && is_multisite() && $network_wide ) { - $mu_blogs = wp_get_sites(); + if ( function_exists( 'get_sites' ) ) { + $blogs = get_sites(); + $mu_blogs = array(); + foreach ( $blogs as $mu_blog ) { + $mu_blogs[] = $mu_blog->to_array(); + } + } else { + $mu_blogs = wp_get_sites(); + } foreach ( $mu_blogs as $mu_blog ) { @@ -219,7 +229,15 @@ function rest_oauth1_activation( $network_wide ) { function rest_oauth1_deactivation( $network_wide ) { if ( function_exists( 'is_multisite' ) && is_multisite() && $network_wide ) { - $mu_blogs = wp_get_sites(); + if ( function_exists( 'get_sites' ) ) { + $blogs = get_sites(); + $mu_blogs = array(); + foreach ( $blogs as $mu_blog ) { + $mu_blogs[] = $mu_blog->to_array(); + } + } else { + $mu_blogs = wp_get_sites(); + } foreach ( $mu_blogs as $mu_blog ) { diff --git a/theme/oauth1-authorize.php b/theme/oauth1-authorize.php index ef4126c..f2cf1d8 100644 --- a/theme/oauth1-authorize.php +++ b/theme/oauth1-authorize.php @@ -1,4 +1,15 @@
post_title ); ?>