Disable REST API - Version v1.5

Version Description

Download this release

Release Info

Developer dmchale
Plugin Icon 128x128 Disable REST API
Version v1.5
Comparing to
See all releases

Code changes from version 1.4.3 to v1.5

admin.php CHANGED
@@ -1,95 +1,95 @@
1
- <style>
2
- #DRA_container ul li {
3
- padding-left: 20px;
4
- }
5
-
6
- #DRA_container em {
7
- font-size: 0.8em;
8
- }
9
- </style>
10
-
11
- <script>
12
- function dra_namespace_click(namespace, id) {
13
- if (jQuery('#dra_namespace_' + id).is(":checked")) {
14
- jQuery("input[data-namespace='" + namespace + "']").prop('checked', true);
15
- } else {
16
- jQuery("input[data-namespace='" + namespace + "']").prop('checked', false);
17
- }
18
- };
19
- </script>
20
-
21
- <div class="wrap">
22
- <h1><?php echo esc_html__( "Disable REST API", "disable-json-api" ); ?></h1>
23
- <?php settings_errors( 'DRA-notices' ); ?>
24
- <p><?php echo esc_html__( "By default, this plugin ensures that the entire REST API is protected from non-authenticated users. You may use this page to specify which endpoints should be allowed to behave as normal.", "disable-json-api" ); ?></p>
25
- <p>
26
- <strong><?php echo esc_html__( "IMPORTANT NOTE:", "disable-json-api" ); ?></strong> <?php echo esc_html__( "Checking a box merely restores default functionality to an endpoint . Other authentication and/or permissions may still be required for access, or other themes / plugins may also affect access to those endpoints. ", "disable - json - api" ); ?>
27
- </p>
28
-
29
- <form method="post" action="" id="DRA_form">
30
- <?php wp_nonce_field( 'DRA_admin_nonce' ); ?>
31
-
32
- <div id="DRA_container"><?php DRA_display_route_checkboxes(); ?></div>
33
-
34
- <?php submit_button(); ?>
35
- <input type="submit" name="reset"
36
- value="<?php echo esc_attr__( "Reset Whitelisted Routes", "disable-json-api" ); ?>"
37
- onclick="return confirm('<?php echo esc_attr__( "Are you sure you wish to clear all whitelisted rules?", "disable-json-api" ); ?>');">
38
- </form>
39
- </div>
40
-
41
- <?php
42
- /**
43
- * Loop through all routes returned by the REST API and display them on-screen
44
- *
45
- */
46
- function DRA_display_route_checkboxes() {
47
- $wp_rest_server = rest_get_server();
48
- $all_namespaces = $wp_rest_server->get_namespaces();
49
- $all_routes = array_keys( $wp_rest_server->get_routes() );
50
- $whitelisted_routes = is_array( get_option( 'DRA_route_whitelist' ) ) ? get_option( 'DRA_route_whitelist' ) : array();
51
-
52
- $loopCounter = 0;
53
- $current_namespace = '';
54
-
55
- foreach ( $all_routes as $route ) {
56
- $is_route_namespace = in_array( ltrim( $route, "/" ), $all_namespaces );
57
- $checkedProp = DRA_get_route_checked_prop( $route, $whitelisted_routes );
58
-
59
- if ( $is_route_namespace || "/" == $route ) {
60
- $current_namespace = $route;
61
- if ( 0 != $loopCounter ) {
62
- echo "</ul>";
63
- }
64
-
65
- $route_for_display = ( "/" == $route ) ? "/ <em>" . esc_html__( "REST API ROOT", "disable-json-api" ) . "</em>" : esc_html( $route );
66
- echo "<h2><label><input name='rest_routes[]' value='$route' type='checkbox' id='dra_namespace_$loopCounter' onclick='dra_namespace_click(\"$route\", $loopCounter)' $checkedProp>&nbsp;$route_for_display</label></h2><ul>";
67
-
68
- if ( "/" == $route ) {
69
- echo "<li>" . sprintf( esc_html__( "On this website, the REST API root is %s", "disable-json-api" ), "<strong>" . rest_url() . "</strong>" ) . "</li>";
70
- }
71
-
72
- } else {
73
- echo "<li><label><input name='rest_routes[]' value='$route' type='checkbox' data-namespace='$current_namespace' $checkedProp>&nbsp;" . esc_html( $route ) . "</label></li>";
74
- }
75
-
76
- $loopCounter ++;
77
- }
78
- echo "</ul>";
79
- }
80
-
81
-
82
- /**
83
- * During comparison, encode the route being requested in the same fashion that it's stored in the database option
84
- * Encoding during save happens in Disable_REST_API::maybe_process_settings_form()
85
- *
86
- * @param $route
87
- * @param $whitelisted_routes
88
- *
89
- * @return string
90
- */
91
- function DRA_get_route_checked_prop( $route, $whitelisted_routes ) {
92
- $is_route_checked = in_array( esc_html( $route ), $whitelisted_routes, true );
93
-
94
- return checked( $is_route_checked, true, false );
95
- }
1
+ <style>
2
+ #DRA_container ul li {
3
+ padding-left: 20px;
4
+ }
5
+
6
+ #DRA_container em {
7
+ font-size: 0.8em;
8
+ }
9
+ </style>
10
+
11
+ <script>
12
+ function dra_namespace_click(namespace, id) {
13
+ if (jQuery('#dra_namespace_' + id).is(":checked")) {
14
+ jQuery("input[data-namespace='" + namespace + "']").prop('checked', true);
15
+ } else {
16
+ jQuery("input[data-namespace='" + namespace + "']").prop('checked', false);
17
+ }
18
+ };
19
+ </script>
20
+
21
+ <div class="wrap">
22
+ <h1><?php echo esc_html__( "Disable REST API", "disable-json-api" ); ?></h1>
23
+ <?php settings_errors( 'DRA-notices' ); ?>
24
+ <p><?php echo esc_html__( "By default, this plugin ensures that the entire REST API is protected from non-authenticated users. You may use this page to specify which endpoints should be allowed to behave as normal.", "disable-json-api" ); ?></p>
25
+ <p>
26
+ <strong><?php echo esc_html__( "IMPORTANT NOTE:", "disable-json-api" ); ?></strong> <?php echo esc_html__( "Checking a box merely restores default functionality to an endpoint. Other authentication and/or permissions may still be required for access, or other themes/plugins may also affect access to those endpoints.", "disable-json-api" ); ?>
27
+ </p>
28
+
29
+ <form method="post" action="" id="DRA_form">
30
+ <?php wp_nonce_field( 'DRA_admin_nonce' ); ?>
31
+
32
+ <div id="DRA_container"><?php DRA_display_route_checkboxes(); ?></div>
33
+
34
+ <?php submit_button(); ?>
35
+ <input type="submit" name="reset"
36
+ value="<?php echo esc_attr__( "Reset Whitelisted Routes", "disable-json-api" ); ?>"
37
+ onclick="return confirm('<?php echo esc_attr__( "Are you sure you wish to clear all whitelisted routes?", "disable-json-api" ); ?>');">
38
+ </form>
39
+ </div>
40
+
41
+ <?php
42
+ /**
43
+ * Loop through all routes returned by the REST API and display them on-screen
44
+ *
45
+ */
46
+ function DRA_display_route_checkboxes() {
47
+ $wp_rest_server = rest_get_server();
48
+ $all_namespaces = $wp_rest_server->get_namespaces();
49
+ $all_routes = array_keys( $wp_rest_server->get_routes() );
50
+ $whitelisted_routes = is_array( get_option( 'DRA_route_whitelist' ) ) ? get_option( 'DRA_route_whitelist' ) : array();
51
+
52
+ $loopCounter = 0;
53
+ $current_namespace = '';
54
+
55
+ foreach ( $all_routes as $route ) {
56
+ $is_route_namespace = in_array( ltrim( $route, "/" ), $all_namespaces );
57
+ $checkedProp = DRA_get_route_checked_prop( $route, $whitelisted_routes );
58
+
59
+ if ( $is_route_namespace || "/" == $route ) {
60
+ $current_namespace = $route;
61
+ if ( 0 != $loopCounter ) {
62
+ echo "</ul>";
63
+ }
64
+
65
+ $route_for_display = ( "/" == $route ) ? "/ <em>" . esc_html__( "REST API ROOT", "disable-json-api" ) . "</em>" : esc_html( $route );
66
+ echo "<h2><label><input name='rest_routes[]' value='$route' type='checkbox' id='dra_namespace_$loopCounter' onclick='dra_namespace_click(\"$route\", $loopCounter)' $checkedProp>&nbsp;$route_for_display</label></h2><ul>";
67
+
68
+ if ( "/" == $route ) {
69
+ echo "<li>" . sprintf( esc_html__( "On this website, the REST API root is %s", "disable-json-api" ), "<strong>" . rest_url() . "</strong>" ) . "</li>";
70
+ }
71
+
72
+ } else {
73
+ echo "<li><label><input name='rest_routes[]' value='$route' type='checkbox' data-namespace='$current_namespace' $checkedProp>&nbsp;" . esc_html( $route ) . "</label></li>";
74
+ }
75
+
76
+ $loopCounter ++;
77
+ }
78
+ echo "</ul>";
79
+ }
80
+
81
+
82
+ /**
83
+ * During comparison, encode the route being requested in the same fashion that it's stored in the database option
84
+ * Encoding during save happens in Disable_REST_API::maybe_process_settings_form()
85
+ *
86
+ * @param $route
87
+ * @param $whitelisted_routes
88
+ *
89
+ * @return string
90
+ */
91
+ function DRA_get_route_checked_prop( $route, $whitelisted_routes ) {
92
+ $is_route_checked = in_array( esc_html( $route ), $whitelisted_routes, true );
93
+
94
+ return checked( $is_route_checked, true, false );
95
+ }
classes/disable-rest-api.php CHANGED
@@ -1,218 +1,218 @@
1
- <?php
2
-
3
- /**
4
- * Disable_REST_API class
5
- *
6
- * Most of the work is done in here
7
- */
8
- class Disable_REST_API {
9
-
10
- const MENU_SLUG = 'disable_rest_api_settings';
11
- const CAPABILITY = 'manage_options';
12
-
13
- /**
14
- * Stores 'disable-json-api/disable-json-api.php' typically
15
- *
16
- * @var string
17
- */
18
- private $base_file_path;
19
-
20
-
21
- /**
22
- * Disable_REST_API constructor.
23
- *
24
- * @param $path
25
- */
26
- public function __construct( $path ) {
27
-
28
- // Set variable so the class knows how to reference the plugin
29
- $this->base_file_path = plugin_basename( $path );
30
-
31
- add_action( 'admin_menu', array( &$this, 'define_admin_link' ) );
32
-
33
- add_filter( 'rest_authentication_errors', array( &$this, 'whitelist_routes' ), 20 );
34
-
35
- }
36
-
37
-
38
- /**
39
- * Checks for a current route being requested, and processes the whitelist
40
- *
41
- * @param $access
42
- *
43
- * @return WP_Error|null|boolean
44
- */
45
- public function whitelist_routes( $access ) {
46
-
47
- // Return current value of $access and skip all plugin functionality
48
- if ( $this->allow_rest_api() ) {
49
- return $access;
50
- }
51
-
52
- $current_route = $this->get_current_route();
53
-
54
- if ( ! empty( $current_route ) && ! $this->is_whitelisted( $current_route ) ) {
55
- return $this->get_wp_error( $access );
56
- }
57
-
58
- return $access;
59
-
60
- }
61
-
62
-
63
- /**
64
- * Current REST route getter.
65
- *
66
- * @return string
67
- */
68
- private function get_current_route() {
69
- $rest_route = $GLOBALS['wp']->query_vars['rest_route'];
70
-
71
- return ( empty( $rest_route ) || '/' == $rest_route ) ?
72
- $rest_route :
73
- untrailingslashit( $rest_route );
74
- }
75
-
76
-
77
- /**
78
- * Checks a route for whether it belongs to the whitelist
79
- *
80
- * @param $currentRoute
81
- *
82
- * @return boolean
83
- */
84
- private function is_whitelisted( $currentRoute ) {
85
-
86
- return array_reduce( $this->get_route_whitelist_option(), function ( $isMatched, $pattern ) use ( $currentRoute ) {
87
- return $isMatched || (bool) preg_match( '@^' . htmlspecialchars_decode( $pattern ) . '$@i', $currentRoute );
88
- }, false );
89
-
90
- }
91
-
92
-
93
- /**
94
- * Get `DRA_route_whitelist` option array from database
95
- *
96
- * @return array
97
- */
98
- private function get_route_whitelist_option() {
99
-
100
- return (array) get_option( 'DRA_route_whitelist', array() );
101
-
102
- }
103
-
104
-
105
- /**
106
- * Add a menu
107
- *
108
- * @return void
109
- */
110
- public function define_admin_link() {
111
-
112
- add_options_page( esc_html__( 'Disable REST API Settings', 'disable-json-api' ), esc_html__( 'Disable REST API', 'disable-json-api' ), self::CAPABILITY, self::MENU_SLUG, array(
113
- &$this,
114
- 'settings_page'
115
- ) );
116
- add_filter( "plugin_action_links_$this->base_file_path", array( &$this, 'settings_link' ) );
117
-
118
- }
119
-
120
-
121
- /**
122
- * Add Settings Link to plugins page
123
- *
124
- * @param $links
125
- *
126
- * @return array
127
- */
128
- public function settings_link( $links ) {
129
-
130
- $settings_url = menu_page_url( self::MENU_SLUG, false );
131
- $settings_link = "<a href='$settings_url'>" . esc_html__( "Settings", "disable-json-api" ) . "</a>";
132
- array_unshift( $links, $settings_link );
133
-
134
- return $links;
135
- }
136
-
137
-
138
- /**
139
- * Menu Callback
140
- *
141
- * @return void
142
- */
143
- public function settings_page() {
144
-
145
- $this->maybe_process_settings_form();
146
-
147
- // Render the settings template
148
- include( __DIR__ . "/../admin.php" );
149
-
150
- }
151
-
152
-
153
- /**
154
- * Process the admin page settings form submission
155
- *
156
- * @return void
157
- */
158
- private function maybe_process_settings_form() {
159
-
160
- if ( ! ( isset( $_POST['_wpnonce'] ) && check_admin_referer( 'DRA_admin_nonce' ) ) ) {
161
- return;
162
- }
163
-
164
- if ( ! current_user_can( self::CAPABILITY ) ) {
165
- return;
166
- }
167
-
168
- // Catch the routes that should be whitelisted
169
- $rest_routes = ( isset( $_POST['rest_routes'] ) ) ?
170
- array_map( 'esc_html', wp_unslash( $_POST['rest_routes'] ) ) :
171
- null;
172
-
173
- // If resetting or whitelist is empty, clear the option and exit the function
174
- if ( empty( $rest_routes ) || isset( $_POST['reset'] ) ) {
175
- delete_option( 'DRA_route_whitelist' );
176
- add_settings_error( 'DRA-notices', esc_attr( 'settings_updated' ), esc_html__( 'All whitelists have been removed.' ), 'updated' );
177
-
178
- return;
179
- }
180
-
181
- // Save whitelist to the Options table
182
- update_option( 'DRA_route_whitelist', $rest_routes );
183
- add_settings_error( 'DRA-notices', esc_attr( 'settings_updated' ), esc_html__( 'Whitelist settings saved.' ), 'updated' );
184
-
185
- }
186
-
187
-
188
- /**
189
- * Allow carte blanche access for logged-in users (or allow override via filter)
190
- *
191
- * @return bool
192
- */
193
- private function allow_rest_api() {
194
- return (bool) apply_filters( 'dra_allow_rest_api', is_user_logged_in() );
195
- }
196
-
197
-
198
- /**
199
- * If $access is already a WP_Error object, add our error to the list
200
- * Otherwise return a new one
201
- *
202
- * @param $access
203
- *
204
- * @return WP_Error
205
- */
206
- private function get_wp_error( $access ) {
207
- $error_message = esc_html__( 'DRA: Only authenticated users can access the REST API.', 'disable-json-api' );
208
-
209
- if ( is_wp_error( $access ) ) {
210
- $access->add( 'rest_cannot_access', $error_message, array( 'status' => rest_authorization_required_code() ) );
211
-
212
- return $access;
213
- }
214
-
215
- return new WP_Error( 'rest_cannot_access', $error_message, array( 'status' => rest_authorization_required_code() ) );
216
- }
217
-
218
- }
1
+ <?php
2
+
3
+ /**
4
+ * Disable_REST_API class
5
+ *
6
+ * Most of the work is done in here
7
+ */
8
+ class Disable_REST_API {
9
+
10
+ const MENU_SLUG = 'disable_rest_api_settings';
11
+ const CAPABILITY = 'manage_options';
12
+
13
+ /**
14
+ * Stores 'disable-json-api/disable-json-api.php' typically
15
+ *
16
+ * @var string
17
+ */
18
+ private $base_file_path;
19
+
20
+
21
+ /**
22
+ * Disable_REST_API constructor.
23
+ *
24
+ * @param $path
25
+ */
26
+ public function __construct( $path ) {
27
+
28
+ // Set variable so the class knows how to reference the plugin
29
+ $this->base_file_path = plugin_basename( $path );
30
+
31
+ add_action( 'admin_menu', array( &$this, 'define_admin_link' ) );
32
+
33
+ add_filter( 'rest_authentication_errors', array( &$this, 'whitelist_routes' ), 20 );
34
+
35
+ }
36
+
37
+
38
+ /**
39
+ * Checks for a current route being requested, and processes the whitelist
40
+ *
41
+ * @param $access
42
+ *
43
+ * @return WP_Error|null|boolean
44
+ */
45
+ public function whitelist_routes( $access ) {
46
+
47
+ // Return current value of $access and skip all plugin functionality
48
+ if ( $this->allow_rest_api() ) {
49
+ return $access;
50
+ }
51
+
52
+ $current_route = $this->get_current_route();
53
+
54
+ if ( ! $this->is_whitelisted( $current_route ) ) {
55
+ return $this->get_wp_error( $access );
56
+ }
57
+
58
+ return $access;
59
+
60
+ }
61
+
62
+
63
+ /**
64
+ * Current REST route getter.
65
+ *
66
+ * @return string
67
+ */
68
+ private function get_current_route() {
69
+ $rest_route = $GLOBALS['wp']->query_vars['rest_route'];
70
+
71
+ return ( empty( $rest_route ) || '/' == $rest_route ) ?
72
+ $rest_route :
73
+ untrailingslashit( $rest_route );
74
+ }
75
+
76
+
77
+ /**
78
+ * Checks a route for whether it belongs to the whitelist
79
+ *
80
+ * @param $currentRoute
81
+ *
82
+ * @return boolean
83
+ */
84
+ private function is_whitelisted( $currentRoute ) {
85
+
86
+ return array_reduce( $this->get_route_whitelist_option(), function ( $isMatched, $pattern ) use ( $currentRoute ) {
87
+ return $isMatched || (bool) preg_match( '@^' . htmlspecialchars_decode( $pattern ) . '$@i', $currentRoute );
88
+ }, false );
89
+
90
+ }
91
+
92
+
93
+ /**
94
+ * Get `DRA_route_whitelist` option array from database
95
+ *
96
+ * @return array
97
+ */
98
+ private function get_route_whitelist_option() {
99
+
100
+ return (array) get_option( 'DRA_route_whitelist', array() );
101
+
102
+ }
103
+
104
+
105
+ /**
106
+ * Add a menu
107
+ *
108
+ * @return void
109
+ */
110
+ public function define_admin_link() {
111
+
112
+ add_options_page( esc_html__( 'Disable REST API Settings', 'disable-json-api' ), esc_html__( 'Disable REST API', 'disable-json-api' ), self::CAPABILITY, self::MENU_SLUG, array(
113
+ &$this,
114
+ 'settings_page'
115
+ ) );
116
+ add_filter( "plugin_action_links_$this->base_file_path", array( &$this, 'settings_link' ) );
117
+
118
+ }
119
+
120
+
121
+ /**
122
+ * Add Settings Link to plugins page
123
+ *
124
+ * @param $links
125
+ *
126
+ * @return array
127
+ */
128
+ public function settings_link( $links ) {
129
+
130
+ $settings_url = menu_page_url( self::MENU_SLUG, false );
131
+ $settings_link = "<a href='$settings_url'>" . esc_html__( "Settings", "disable-json-api" ) . "</a>";
132
+ array_unshift( $links, $settings_link );
133
+
134
+ return $links;
135
+ }
136
+
137
+
138
+ /**
139
+ * Menu Callback
140
+ *
141
+ * @return void
142
+ */
143
+ public function settings_page() {
144
+
145
+ $this->maybe_process_settings_form();
146
+
147
+ // Render the settings template
148
+ include( __DIR__ . "/../admin.php" );
149
+
150
+ }
151
+
152
+
153
+ /**
154
+ * Process the admin page settings form submission
155
+ *
156
+ * @return void
157
+ */
158
+ private function maybe_process_settings_form() {
159
+
160
+ if ( ! ( isset( $_POST['_wpnonce'] ) && check_admin_referer( 'DRA_admin_nonce' ) ) ) {
161
+ return;
162
+ }
163
+
164
+ if ( ! current_user_can( self::CAPABILITY ) ) {
165
+ return;
166
+ }
167
+
168
+ // Catch the routes that should be whitelisted
169
+ $rest_routes = ( isset( $_POST['rest_routes'] ) ) ?
170
+ array_map( 'esc_html', wp_unslash( $_POST['rest_routes'] ) ) :
171
+ null;
172
+
173
+ // If resetting or whitelist is empty, clear the option and exit the function
174
+ if ( empty( $rest_routes ) || isset( $_POST['reset'] ) ) {
175
+ delete_option( 'DRA_route_whitelist' );
176
+ add_settings_error( 'DRA-notices', esc_attr( 'settings_updated' ), esc_html__( 'All whitelists have been removed.', 'disable-json-api' ), 'updated' );
177
+
178
+ return;
179
+ }
180
+
181
+ // Save whitelist to the Options table
182
+ update_option( 'DRA_route_whitelist', $rest_routes );
183
+ add_settings_error( 'DRA-notices', esc_attr( 'settings_updated' ), esc_html__( 'Whitelist settings saved.', 'disable-json-api' ), 'updated' );
184
+
185
+ }
186
+
187
+
188
+ /**
189
+ * Allow carte blanche access for logged-in users (or allow override via filter)
190
+ *
191
+ * @return bool
192
+ */
193
+ private function allow_rest_api() {
194
+ return (bool) apply_filters( 'dra_allow_rest_api', is_user_logged_in() );
195
+ }
196
+
197
+
198
+ /**
199
+ * If $access is already a WP_Error object, add our error to the list
200
+ * Otherwise return a new one
201
+ *
202
+ * @param $access
203
+ *
204
+ * @return WP_Error
205
+ */
206
+ private function get_wp_error( $access ) {
207
+ $error_message = esc_html__( 'DRA: Only authenticated users can access the REST API.', 'disable-json-api' );
208
+
209
+ if ( is_wp_error( $access ) ) {
210
+ $access->add( 'rest_cannot_access', $error_message, array( 'status' => rest_authorization_required_code() ) );
211
+
212
+ return $access;
213
+ }
214
+
215
+ return new WP_Error( 'rest_cannot_access', $error_message, array( 'status' => rest_authorization_required_code() ) );
216
+ }
217
+
218
+ }
classes/requirements-check.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Disable_REST_API_Requirements_Check
4
+ *
5
+ * Taken from https://markjaquith.wordpress.com/2018/02/19/handling-old-wordpress-and-php-versions-in-your-plugin/
6
+ *
7
+ */
8
+
9
+ class Disable_REST_API_Requirements_Check {
10
+ private $title = '';
11
+ private $php = '5.2.4';
12
+ private $wp = '3.8';
13
+ private $file;
14
+
15
+ public function __construct( $args ) {
16
+ foreach ( array( 'title', 'php', 'wp', 'file' ) as $setting ) {
17
+ if ( isset( $args[$setting] ) ) {
18
+ $this->$setting = $args[$setting];
19
+ }
20
+ }
21
+ }
22
+
23
+ public function passes() {
24
+ $passes = $this->php_passes() && $this->wp_passes();
25
+ if ( ! $passes ) {
26
+ add_action( 'admin_notices', array( $this, 'deactivate' ) );
27
+ }
28
+ return $passes;
29
+ }
30
+
31
+ public function deactivate() {
32
+ if ( isset( $this->file ) ) {
33
+ deactivate_plugins( plugin_basename( $this->file ) );
34
+ }
35
+ }
36
+
37
+ private function php_passes() {
38
+ if ( $this->__php_at_least( $this->php ) ) {
39
+ return true;
40
+ } else {
41
+ add_action( 'admin_notices', array( $this, 'php_version_notice' ) );
42
+ return false;
43
+ }
44
+ }
45
+
46
+ private static function __php_at_least( $min_version ) {
47
+ return version_compare( phpversion(), $min_version, '>=' );
48
+ }
49
+
50
+ public function php_version_notice() {
51
+ echo '<div class="error">';
52
+ echo "<p>The &#8220;" . esc_html( $this->title ) . "&#8221; plugin cannot run on PHP versions older than " . $this->php . '. Please contact your host and ask them to upgrade.</p>';
53
+ echo '</div>';
54
+ }
55
+
56
+ private function wp_passes() {
57
+ if ( $this->__wp_at_least( $this->wp ) ) {
58
+ return true;
59
+ } else {
60
+ add_action( 'admin_notices', array( $this, 'wp_version_notice' ) );
61
+ return false;
62
+ }
63
+ }
64
+
65
+ private static function __wp_at_least( $min_version ) {
66
+ return version_compare( get_bloginfo( 'version' ), $min_version, '>=' );
67
+ }
68
+
69
+ public function wp_version_notice() {
70
+ echo '<div class="error">';
71
+ echo "<p>The &#8220;" . esc_html( $this->title ) . "&#8221; plugin cannot run on WordPress versions older than " . $this->wp . '. Please update WordPress.</p>';
72
+ echo '</div>';
73
+ }
74
+ }
disable-json-api.php CHANGED
@@ -2,8 +2,8 @@
2
  /**
3
  * Plugin Name: Disable REST API
4
  * Plugin URI: http://www.binarytemplar.com/disable-json-api
5
- * Description: Disable the use of the JSON REST API on your website to anonymous users
6
- * Version: 1.4.3
7
  * Author: Dave McHale
8
  * Author URI: http://www.binarytemplar.com
9
  * Text Domain: disable-json-api
@@ -22,17 +22,34 @@ function disable_rest_api_load_textdomain() {
22
  load_plugin_textdomain( 'disable-json-api', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
23
  }
24
 
25
- // Remove REST API info from head and headers
26
- remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' );
27
- remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
28
- remove_action( 'template_redirect', 'rest_output_link_header', 11 );
29
-
30
- // WordPress 4.7+ disables the REST API via authentication short-circuit.
31
- // For versions of WordPress < 4.7, disable the REST API via filters
32
- if ( version_compare( get_bloginfo( 'version' ), '4.7', '>=' ) ) {
33
- require_once( plugin_dir_path( __FILE__ ) . 'classes/disable-rest-api.php' );
34
- new Disable_REST_API( __FILE__ );
35
- } else {
36
- require_once( plugin_dir_path( __FILE__ ) . 'functions/legacy.php' );
37
- DRA_Disable_Via_Filters();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
 
 
2
  /**
3
  * Plugin Name: Disable REST API
4
  * Plugin URI: http://www.binarytemplar.com/disable-json-api
5
+ * Description: Disable the use of the REST API on your website to anonymous users
6
+ * Version: 1.5
7
  * Author: Dave McHale
8
  * Author URI: http://www.binarytemplar.com
9
  * Text Domain: disable-json-api
22
  load_plugin_textdomain( 'disable-json-api', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
23
  }
24
 
25
+ // Requirements check, to cleanly handle failure of WP/PHP version requirements
26
+ include( dirname( __FILE__ ) . '/classes/requirements-check.php' );
27
+
28
+ $dra_requirements_check = new Disable_REST_API_Requirements_Check( array(
29
+ 'title' => 'Disable REST API',
30
+ 'php' => '5.3',
31
+ 'wp' => '4.4',
32
+ 'file' => __FILE__,
33
+ ) );
34
+
35
+ // Only load plugin if we pass minimum requirements
36
+ if ( $dra_requirements_check->passes() ) {
37
+
38
+ // Remove REST API info from head and headers
39
+ remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' );
40
+ remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
41
+ remove_action( 'template_redirect', 'rest_output_link_header', 11 );
42
+
43
+ // WordPress 4.7+ disables the REST API via authentication short-circuit.
44
+ // For versions of WordPress < 4.7, disable the REST API via filters
45
+ if ( version_compare( get_bloginfo( 'version' ), '4.7', '>=' ) ) {
46
+ require_once( plugin_dir_path( __FILE__ ) . 'classes/disable-rest-api.php' );
47
+ new Disable_REST_API( __FILE__ );
48
+ } else {
49
+ require_once( plugin_dir_path( __FILE__ ) . 'functions/legacy.php' );
50
+ DRA_Disable_Via_Filters();
51
+ }
52
+
53
  }
54
+
55
+ unset( $dra_requirements_check );
functions/legacy.php CHANGED
@@ -1,16 +1,16 @@
1
- <?php
2
- /**
3
- * This function gets called if the current version of WordPress is less than 4.7
4
- * We are able to make use of filters to actually disable the functionality entirely
5
- */
6
- function DRA_Disable_Via_Filters() {
7
-
8
- // Filters for WP-API version 1.x
9
- add_filter( 'json_enabled', '__return_false' );
10
- add_filter( 'json_jsonp_enabled', '__return_false' );
11
-
12
- // Filters for WP-API version 2.x
13
- add_filter( 'rest_enabled', '__return_false' );
14
- add_filter( 'rest_jsonp_enabled', '__return_false' );
15
-
16
- }
1
+ <?php
2
+ /**
3
+ * This function gets called if the current version of WordPress is less than 4.7
4
+ * We are able to make use of filters to actually disable the functionality entirely
5
+ */
6
+ function DRA_Disable_Via_Filters() {
7
+
8
+ // Filters for WP-API version 1.x
9
+ add_filter( 'json_enabled', '__return_false' );
10
+ add_filter( 'json_jsonp_enabled', '__return_false' );
11
+
12
+ // Filters for WP-API version 2.x
13
+ add_filter( 'rest_enabled', '__return_false' );
14
+ add_filter( 'rest_jsonp_enabled', '__return_false' );
15
+
16
+ }
readme.txt CHANGED
@@ -2,22 +2,26 @@
2
  Contributors: dmchale, tangrufus
3
  Tags: admin, api, json, REST, rest-api, disable
4
  Requires at least: 4.4
5
- Requires PHP: 5.3
6
- Tested up to: 4.9
7
- Stable tag: 1.4.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
- Disable the use of the JSON REST API on your website to unauthenticated users.
12
 
13
  == Description ==
14
 
15
- ** Version 1.4 now supports whitelisting of individual routes within the REST API **
16
 
17
- The engine for the API has existed in WordPress since v4.4, but additional functionality and endpoints are a
18
- continual project. While this is very exciting news for many reasons - and many plugins, themes, and even pieces of
19
- WordPress core are already beginning to use the REST API - it is also not functionality that every site admin is going
20
- to want enabled on their website if not necessary.
 
 
 
 
21
 
22
  As of WordPress 4.7, the filters provided for disabling the REST API were removed. To compensate, this plugin will
23
  forcibly return an authentication error to any API requests from sources who are not logged into your website, which
@@ -53,9 +57,16 @@ disabled so long as this plugin is active. Namespaces and routes may be whitelis
53
 
54
  1. The JSON returned by a website with the API disabled via filters (WP versions 4.4, 4.5, 4.6)
55
  2. The JSON returned by a website with the API disabled via authentication methods (WP versions 4.7+)
 
56
 
57
  == Changelog ==
58
 
 
 
 
 
 
 
59
  = 1.4.3 =
60
  * Added `load_plugin_textdomain()` for i18n
61
 
2
  Contributors: dmchale, tangrufus
3
  Tags: admin, api, json, REST, rest-api, disable
4
  Requires at least: 4.4
5
+ Requires PHP: 5.6
6
+ Tested up to: 5.3
7
+ Stable tag: 1.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
+ Disable the use of the REST API on your website to unauthenticated users.
12
 
13
  == Description ==
14
 
15
+ The most comprehensive plugin for controlling access to the WordPress REST API!
16
 
17
+ Works as a "set it and forget it" install. Just upload and activate, and the entire REST API will be inaccessible to
18
+ your site visitors. Or if you have a plugin or theme installed which needs some of its endpoints to be accessible to
19
+ site visitors, you can do that too. Go to the Settings page and you can quickly whitelist individual endpoints - or
20
+ entire branches of endpoints - registered with the REST API.
21
+
22
+ The engine for the API has existed in WordPress since v4.4 and additional functionality and endpoints are a
23
+ continual project. While this is very exciting news for many reasons, it is also not functionality that every site
24
+ admin wants enabled on their website if not necessary.
25
 
26
  As of WordPress 4.7, the filters provided for disabling the REST API were removed. To compensate, this plugin will
27
  forcibly return an authentication error to any API requests from sources who are not logged into your website, which
57
 
58
  1. The JSON returned by a website with the API disabled via filters (WP versions 4.4, 4.5, 4.6)
59
  2. The JSON returned by a website with the API disabled via authentication methods (WP versions 4.7+)
60
+ 3. The Settings page lets you selectively whitelist endpoints registered with the REST API.
61
 
62
  == Changelog ==
63
 
64
+ = 1.5 =
65
+ * Tested up to WP v5.3
66
+ * Added enforcement for WordPress and PHP minimum version requirements
67
+ * Fixed minor bug to prevent unintended empty routes
68
+ * Minor text updates and adding textdomain to translation functions that didn't have them
69
+
70
  = 1.4.3 =
71
  * Added `load_plugin_textdomain()` for i18n
72