Skip to content

Commit

Permalink
Merge pull request petenelson#32 from petenelson/feature/core-endpoin…
Browse files Browse the repository at this point in the history
…t-authentication

Feature/core endpoint authentication
  • Loading branch information
petenelson committed Dec 13, 2016
2 parents 8dd12c8 + d66b392 commit d6df583
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 3 deletions.
37 changes: 36 additions & 1 deletion includes/class-rest-api-toolbox-common.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ static public function plugins_loaded() {
add_filter( 'rest_endpoints', array( __CLASS__, 'remove_all_core_endpoints'), 100, 1 );
add_filter( 'rest_endpoints', array( __CLASS__, 'remove_selected_core_endpoints'), 100, 1 );

// Filter hook to require authentication for specific endpoints.
add_filter( 'rest_pre_dispatch', array( __CLASS__, 'endpoint_requires_authentication_filter' ), 100, 3 );
}

/**
Expand Down Expand Up @@ -112,7 +114,7 @@ static public function rest_authentication_errors_filter( $error ) {
$disable_rest_api = REST_API_Toolbox_Settings::setting_is_enabled( 'general', 'disable-rest-api' );

if ( $disable_rest_api ) {
$error = new WP_Error( 'rest_disabled', __( 'The REST API is disabled on this site.' ) );
$error = new WP_Error( 'rest_disabled', __( 'The REST API is disabled on this site.' ), array( 'status' => 404 ) );
}
}

Expand Down Expand Up @@ -233,6 +235,39 @@ static public function remove_endpoint( $routes, $remove_endpoint ) {
return $routes;
}

/**
* Filter hook to require authentication on specific endpoints.
*
* @param mixed $result Response to replace the requested version with. Can be anything
* a normal endpoint can return, or null to not hijack the request.
* @param WP_REST_Server $rest_server Server instance.
* @param WP_REST_Request $request Request used to generate the response.
* @return mixed
*/
static public function endpoint_requires_authentication_filter( $result, $rest_server, $request ) {

// Get the route for the request.
$route = $request->get_route();

// Get the settings for core.
$core_settings = get_option( REST_API_Toolbox_Settings::options_key( 'core' ) );
$key = 'require-authentication|' . $route;

// See if this route is configured to require authentication and
// if there is a current user logged in.
if ( ! empty( $core_settings ) && isset( $core_settings[ $key ] ) && '1' === $core_settings[ $key ] && ! is_user_logged_in() ) {

// Return a WP_Error is authentication is required but there
// is no current user logged in.
$result = new WP_Error(
'rest_cannot_view',
sprintf( __( 'The REST API route %s requires authentication on this site.', 'rest-api-toolbox' ), $route ),
array( 'status' => 401 )
);
}

return $result;
}

}

Expand Down
11 changes: 11 additions & 0 deletions includes/settings/class-rest-api-toolbox-settings-core.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,24 @@ static public function register_core_settings() {
$endpoints = REST_API_Toolbox_Common::core_endpoints();

foreach( $endpoints as $endpoint ) {

// Add yes/no options to remove the endpoint.
$name = 'remove-endpoint|/' . $namespace . '/' . $endpoint;
add_settings_field( $name, sprintf( __( 'Remove Endpoint: %s', 'rest-api-toolbox' ), $endpoint),
array( __CLASS__, 'settings_yes_no' ),
$key,
$section,
array( 'key' => $key, 'name' => $name, 'after' => '' )
);

// Add yes/no options to require authentication.
$name = 'require-authentication|/' . $namespace . '/' . $endpoint;
add_settings_field( $name, sprintf( __( 'Require Authentication: %s', 'rest-api-toolbox' ), $endpoint),
array( __CLASS__, 'settings_yes_no' ),
$key,
$section,
array( 'key' => $key, 'name' => $name, 'after' => '' )
);
}

}
Expand Down
8 changes: 7 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tags: rest api, rest, wp rest api
Donate link: https://petenelson.io/
Requires at least: 4.4
Tested up to: 4.7
Stable tag: 1.2.0
Stable tag: 1.3.0
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -40,6 +40,9 @@ Have any questions? We can answer them here?

== Changelog ==

= 1.3.0 December 12th, 2016 =
* Added option to require authentication for core endpoints.

= 1.2.0 December 5th, 2016 =
* Updated the way the REST API can be disabled due to the rest_enabled filter being deprecated.
* Added 'settings' to the list of core endpoints that can be removed.
Expand All @@ -57,6 +60,9 @@ Have any questions? We can answer them here?

== Changelog ==

= 1.3.0 December 12th, 2016 =
* Added option to require authentication for core endpoints.

= 1.2.0 December 5th, 2016 =
* Updated the way the REST API can be disabled due to the rest_enabled filter being deprecated.
* Added 'settings' to the list of core endpoints that can be removed.
Expand Down
2 changes: 1 addition & 1 deletion rest-api-toolbox.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
* Plugin Name: REST API Toolbox
* Version: 1.2.0
* Version: 1.3.0
* Description: Allows easy tweaks of several REST API settings
* Author: Pete Nelson
* Author URI: https://github.com/petenelson/wp-rest-api-toolbox
Expand Down
43 changes: 43 additions & 0 deletions tests/test-core.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,47 @@ function test_do_not_remove_core_endpoints() {

}

function test_require_authentication_core_endpoints() {

$namespace = REST_API_Toolbox_Common::core_namespace();

foreach( REST_API_Toolbox_Common::core_endpoints() as $endpoint ) {

$endpoint = '/' . $namespace . '/' . $endpoint;
$require_auth_endpoint = 'require-authentication|' . $endpoint;

REST_API_Toolbox_Settings::change_enabled_setting( 'core', $require_auth_endpoint, true );

$this->assertEquals( true, REST_API_Toolbox_Settings::setting_is_enabled( 'core', $require_auth_endpoint ) );

// Create a REST request
$request = new WP_REST_Request( 'GET', $endpoint );

// Verify that the request returns a WP_Error for rest_pre_dispatch
$this->assertInstanceOf( 'WP_Error', apply_filters( 'rest_pre_dispatch', array(), rest_get_server(), $request ) );
}
}


function test_do_not_require_authentication_core_endpoints() {

$namespace = REST_API_Toolbox_Common::core_namespace();

foreach( REST_API_Toolbox_Common::core_endpoints() as $endpoint ) {

$endpoint = '/' . $namespace . '/' . $endpoint;
$require_auth_endpoint = 'require-authentication|' . $endpoint;

REST_API_Toolbox_Settings::change_enabled_setting( 'core', $require_auth_endpoint, false );

$this->assertEquals( false, REST_API_Toolbox_Settings::setting_is_enabled( 'core', $require_auth_endpoint ) );

// Create a REST request
$request = new WP_REST_Request( 'GET', $endpoint );

// Verify that the request returns the same result.
$this->assertEquals( array(), apply_filters( 'rest_pre_dispatch', array(), rest_get_server(), $request ) );
}
}

}

0 comments on commit d6df583

Please sign in to comment.