From be90781e0e01788f35ca66a533e6be538916468e Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 10 Nov 2020 09:39:18 -0600 Subject: [PATCH 1/7] Add permission callbacks to REST API endpoints This fixes a notice thrown since WP 5.5 when a REST route is registered without explicitly adding a permission callback. --- .../rest-api/auth/class-wp-rest-key-pair.php | 33 ++++++++++--------- .../rest-api/auth/class-wp-rest-token.php | 18 +++++----- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/wp-includes/rest-api/auth/class-wp-rest-key-pair.php b/wp-includes/rest-api/auth/class-wp-rest-key-pair.php index df47258..88f5e2e 100644 --- a/wp-includes/rest-api/auth/class-wp-rest-key-pair.php +++ b/wp-includes/rest-api/auth/class-wp-rest-key-pair.php @@ -92,17 +92,18 @@ public static function get_rest_uri() { */ public function register_routes() { $args = array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'generate_key_pair' ), - 'args' => array( - 'name' => array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'generate_key_pair' ), + 'permission_callback' => '__return_true', + 'args' => array( + 'name' => array( 'description' => esc_html__( 'The name of the key-pair.', 'jwt-auth' ), 'type' => 'string', 'required' => true, 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ), - 'user_id' => array( + 'user_id' => array( 'description' => esc_html__( 'The ID of the user.', 'jwt-auth' ), 'type' => 'integer', 'required' => true, @@ -110,15 +111,16 @@ public function register_routes() { 'validate_callback' => 'rest_validate_request_arg', ), ), - 'schema' => array( $this, 'get_item_schema' ), + 'schema' => array( $this, 'get_item_schema' ), ); register_rest_route( self::_NAMESPACE_, '/' . self::_REST_BASE_ . '/(?P[\d]+)', $args ); $args = array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_all_key_pairs' ), - 'args' => array( - 'user_id' => array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_all_key_pairs' ), + 'permission_callback' => '__return_true', + 'args' => array( + 'user_id' => array( 'description' => esc_html__( 'The ID of the user.', 'jwt-auth' ), 'type' => 'integer', 'required' => true, @@ -130,17 +132,18 @@ public function register_routes() { register_rest_route( self::_NAMESPACE_, '/' . self::_REST_BASE_ . '/(?P[\d]+)/revoke-all', $args ); $args = array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_key_pair' ), - 'args' => array( - 'user_id' => array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_key_pair' ), + 'permission_callback' => '__return_true', + 'args' => array( + 'user_id' => array( 'description' => esc_html__( 'The ID of the user.', 'jwt-auth' ), 'type' => 'integer', 'required' => true, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), - 'api_key' => array( + 'api_key' => array( 'description' => esc_html__( 'The API key being revoked.', 'jwt-auth' ), 'type' => 'string', 'required' => true, diff --git a/wp-includes/rest-api/auth/class-wp-rest-token.php b/wp-includes/rest-api/auth/class-wp-rest-token.php index b51ecb6..2d590ea 100644 --- a/wp-includes/rest-api/auth/class-wp-rest-token.php +++ b/wp-includes/rest-api/auth/class-wp-rest-token.php @@ -98,29 +98,31 @@ public static function get_rest_uri() { */ public function register_routes() { $args = array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'validate' ), + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'validate' ), + 'permission_callback' => '__return_true' ); register_rest_route( self::_NAMESPACE_, '/' . self::_REST_BASE_ . '/validate', $args ); $args = array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'generate_token' ), - 'args' => array( - 'api_key' => array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'generate_token' ), + 'permission_callback' => '__return_true', + 'args' => array( + 'api_key' => array( 'description' => __( 'The API key of the user; requires also setting the api_secret.', 'jwt-auth' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ), - 'api_secret' => array( + 'api_secret' => array( 'description' => __( 'The API secret of the user; requires also setting the api_key.', 'jwt-auth' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ), ), - 'schema' => array( $this, 'get_item_schema' ), + 'schema' => array( $this, 'get_item_schema' ), ); register_rest_route( self::_NAMESPACE_, '/' . self::_REST_BASE_, $args ); } From bfc228408fdf2dacc4728677ca780f854d3d43fa Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 10 Nov 2020 09:56:17 -0600 Subject: [PATCH 2/7] Upgrade dealerdirect/phpcodesniffer-composer-installer to 0.7.0 This upgrade fixes compatibility support for Composer 2.0. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cddfb26..9af8157 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ }, "require-dev": { "brainmaestro/composer-git-hooks": "^2.6.0", - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "firebase/php-jwt": "^5.0", "phpcompatibility/phpcompatibility-wp": "*", "php-coveralls/php-coveralls": "^2.1", From c0f647e7f153b165fad941dad2b648d70d547a5f Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 10 Nov 2020 10:03:08 -0600 Subject: [PATCH 3/7] Enable MySQL and Memcached on Travis Currently Travis is using the xenial build, which doesn't auto-enablew mysql, which causes our tests to fail. This explicitly fixes this by enabling mysql and memcached. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4765b37..7b7cefb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,10 @@ cache: - vendor - $HOME/phpunit-bin +services: + - mysql + - memcached + addons: apt: packages: From e486b326b98d01a2958b84fe4d046968d3cc19fd Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 10 Nov 2020 10:18:39 -0600 Subject: [PATCH 4/7] Fix PHPCS issues --- wp-admin/includes/class-wp-key-pair-list-table.php | 4 ++-- .../rest-api/auth/class-wp-rest-key-pair.php | 12 ++++++------ wp-includes/rest-api/auth/class-wp-rest-token.php | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/wp-admin/includes/class-wp-key-pair-list-table.php b/wp-admin/includes/class-wp-key-pair-list-table.php index ecb563c..27b69bb 100644 --- a/wp-admin/includes/class-wp-key-pair-list-table.php +++ b/wp-admin/includes/class-wp-key-pair-list-table.php @@ -73,12 +73,12 @@ protected function column_default( $item, $column_name ) { if ( empty( $item['created'] ) ) { return '—'; } - return date( 'F j, Y g:i a', $item['created'] ); + return gmdate( 'F j, Y g:i a', $item['created'] ); case 'last_used': if ( empty( $item['last_used'] ) ) { return '—'; } - return date( 'F j, Y g:i a', $item['last_used'] ); + return gmdate( 'F j, Y g:i a', $item['last_used'] ); case 'last_ip': if ( empty( $item['last_ip'] ) ) { return '—'; diff --git a/wp-includes/rest-api/auth/class-wp-rest-key-pair.php b/wp-includes/rest-api/auth/class-wp-rest-key-pair.php index 88f5e2e..aa7f4a6 100644 --- a/wp-includes/rest-api/auth/class-wp-rest-key-pair.php +++ b/wp-includes/rest-api/auth/class-wp-rest-key-pair.php @@ -96,14 +96,14 @@ public function register_routes() { 'callback' => array( $this, 'generate_key_pair' ), 'permission_callback' => '__return_true', 'args' => array( - 'name' => array( + 'name' => array( 'description' => esc_html__( 'The name of the key-pair.', 'jwt-auth' ), 'type' => 'string', 'required' => true, 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ), - 'user_id' => array( + 'user_id' => array( 'description' => esc_html__( 'The ID of the user.', 'jwt-auth' ), 'type' => 'integer', 'required' => true, @@ -120,7 +120,7 @@ public function register_routes() { 'callback' => array( $this, 'delete_all_key_pairs' ), 'permission_callback' => '__return_true', 'args' => array( - 'user_id' => array( + 'user_id' => array( 'description' => esc_html__( 'The ID of the user.', 'jwt-auth' ), 'type' => 'integer', 'required' => true, @@ -136,14 +136,14 @@ public function register_routes() { 'callback' => array( $this, 'delete_key_pair' ), 'permission_callback' => '__return_true', 'args' => array( - 'user_id' => array( + 'user_id' => array( 'description' => esc_html__( 'The ID of the user.', 'jwt-auth' ), 'type' => 'integer', 'required' => true, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), - 'api_key' => array( + 'api_key' => array( 'description' => esc_html__( 'The API key being revoked.', 'jwt-auth' ), 'type' => 'string', 'required' => true, @@ -517,7 +517,7 @@ public function generate_key_pair( WP_REST_Request $request ) { $keypairs[] = $new_item; $this->set_user_key_pairs( $user_id, $keypairs ); - $new_item['created'] = date( 'F j, Y g:i a', $new_item['created'] ); + $new_item['created'] = gmdate( 'F j, Y g:i a', $new_item['created'] ); $new_item['last_used'] = '—'; $new_item['last_ip'] = '—'; diff --git a/wp-includes/rest-api/auth/class-wp-rest-token.php b/wp-includes/rest-api/auth/class-wp-rest-token.php index 2d590ea..518ea7c 100644 --- a/wp-includes/rest-api/auth/class-wp-rest-token.php +++ b/wp-includes/rest-api/auth/class-wp-rest-token.php @@ -100,7 +100,7 @@ public function register_routes() { $args = array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'validate' ), - 'permission_callback' => '__return_true' + 'permission_callback' => '__return_true', ); register_rest_route( self::_NAMESPACE_, '/' . self::_REST_BASE_ . '/validate', $args ); @@ -109,13 +109,13 @@ public function register_routes() { 'callback' => array( $this, 'generate_token' ), 'permission_callback' => '__return_true', 'args' => array( - 'api_key' => array( + 'api_key' => array( 'description' => __( 'The API key of the user; requires also setting the api_secret.', 'jwt-auth' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ), - 'api_secret' => array( + 'api_secret' => array( 'description' => __( 'The API secret of the user; requires also setting the api_key.', 'jwt-auth' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', @@ -382,8 +382,8 @@ public function authenticate_refresh_token( $user, WP_REST_Request $request ) { */ public function require_token() { $require_token = true; - $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( $_SERVER['REQUEST_URI'] ) : false; - $request_method = isset( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( $_SERVER['REQUEST_METHOD'] ) : false; + $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : false; + $request_method = isset( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) : false; // User is already authenticated. $user = wp_get_current_user(); @@ -777,11 +777,11 @@ public function validate_token() { public function get_auth_header() { // Get HTTP Authorization Header. - $header = isset( $_SERVER['HTTP_AUTHORIZATION'] ) ? sanitize_text_field( $_SERVER['HTTP_AUTHORIZATION'] ) : false; + $header = isset( $_SERVER['HTTP_AUTHORIZATION'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_AUTHORIZATION'] ) ) : false; // Check for alternative header. if ( ! $header && isset( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ) { - $header = sanitize_text_field( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ); + $header = sanitize_text_field( wp_unslash( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ); } // The HTTP Authorization Header is missing, return an error. From 330e60c50eb1760df1309692c11f2789e4588cd2 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 10 Nov 2020 10:24:43 -0600 Subject: [PATCH 5/7] Upgrade xwp/wp-dev-lib to 1.6.5 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9af8157..c92ebf8 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "php-coveralls/php-coveralls": "^2.1", "slowprog/composer-copy-file": "0.2.1", "wp-coding-standards/wpcs": "*", - "xwp/wp-dev-lib": "^1.1.1" + "xwp/wp-dev-lib": "^1.6.5" }, "scripts": { "phpcs": [ From cbd381c15e3643e156b0780f9d59df4da6722949 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 10 Nov 2020 10:29:31 -0600 Subject: [PATCH 6/7] Upgrade php-coveralls to 2.4.2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c92ebf8..58b5c19 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "firebase/php-jwt": "^5.0", "phpcompatibility/phpcompatibility-wp": "*", - "php-coveralls/php-coveralls": "^2.1", + "php-coveralls/php-coveralls": "^2.4.2", "slowprog/composer-copy-file": "0.2.1", "wp-coding-standards/wpcs": "*", "xwp/wp-dev-lib": "^1.6.5" From 97e24d252d46508991fa37d51cb4ddcbd78875ba Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 10 Nov 2020 10:42:04 -0600 Subject: [PATCH 7/7] Fix PHPUnit configuration validation --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 1265cd7..51a34b9 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -7,7 +7,7 @@ convertWarningsToExceptions="true" > - + ./tests/ ./tests/