Restricted Site Access - Version 5.0

Version Description

  • WordPress 3.5 compatibility (3.5 eliminated the Privacy settings panel in favor of a refreshed Reading panel)
  • Real validation (on the fly and on save) for IP address entries
  • "Restriction message" now supports simple HTML and is edited using WordPress's simple HTML tag editor
  • A bunch of visual refinements that conform better with WordPress 3.4 and newer (spacing, native "shake" effect on invalid entries just like the login form, etc.)
  • A bunch of under the hood refinements (e.g. playing nicer with current screen Help API)
Download this release

Release Info

Developer jakemgold
Plugin Icon 128x128 Restricted Site Access
Version 5.0
Comparing to
See all releases

Code changes from version 4.0 to 5.0

readme.txt CHANGED
@@ -1,20 +1,20 @@
1
  === Restricted Site Access ===
2
- Contributors: jakemgold, rcbth
3
- Donate link: http://www.get10up.com/plugins/restricted-site-access-wordpress/
4
- Tags: privacy, restricted, restrict, limited, permissions, security, block
5
- Requires at least: 3.2
6
- Tested up to: 3.2.1
7
- Stable tag: 4.0
8
 
9
- Limit access to visitors who are logged in or at specific IP addresses. Many options for handling blocked visitors. Great for Intranets, dev sites.
10
 
11
  == Description ==
12
 
13
- Limit access your site to visitors who are logged in or accessing the site from a set of specific IP addresses. Send restricted visitors to the log in page, redirect them, or display a message or page. A great solution for Extranets, publicly hosted Intranets, or parallel development / staging sites.
14
 
15
- Adds a number of new configuration options to the Privacy settings panel. From this panel you can:
16
 
17
- 1. Enable or disable site access restriction
18
  1. Change the restriction behavior: send to login, redirect, display a message, display a page
19
  1. Add IP addresses to an unrestricted list, including ranges
20
  1. Quickly add your current IP to the unrestricted list
@@ -25,13 +25,13 @@ Adds a number of new configuration options to the Privacy settings panel. From t
25
 
26
  1. Install easily with the WordPress plugin control panel or manually download the plugin and upload the extracted folder to the `/wp-content/plugins/` directory
27
  1. Activate the plugin through the 'Plugins' menu in WordPress
28
- 1. Configure the plugin by going to the "Privacy" menu under "Settings"
29
 
30
  == Frequently Asked Questions ==
31
 
32
  = How do I unrestrict specific pages or parts of my site? =
33
 
34
- Developers can use the `restricted_site_access_is_restricted` filter to override Restricted Site Access. Note that the restriction checks runs before WordPress executes any queries, so use the global `$wp` variable to investigate what the visitor is trying to load.
35
 
36
  For instance, to unblock an RSS feed, place the following PHP code in the theme's functions.php file or in a simple plug-in:
37
 
@@ -48,19 +48,25 @@ function my_rsa_feed_override( $is_restricted ) {
48
 
49
  = How secure is this plug-in? =
50
 
51
- Users that are not logged in or allowed by IP address will not be able to browse your site. Restricted Site Access does not block access to your "real" files, so direct links to files in your uploads folder (for instance) are not blocked. It is also important to remember that IP addresses can be spoofed by hackers. Because Restricted Site Access runs as a plug-in, it is subject to general WordPress vulnerabilities.
52
 
53
  Restricted Site Access is not meant to be a top secret data safe, but simply a reliable and convenient way to handle unwanted visitors.
54
 
55
  == Screenshots ==
56
 
57
- 1. Screenshot of settings panel with simple Restricted Site Access option (send to login page).
58
- 1. Screenshot of settings panel with redirection method enabled, and confirming removal of an IP address from the exception list
59
- 1. Plenty of inline help! Looks and behaves like native WordPress functionality.
60
- 1. Restricted access mode turned off in the privacy settings panel
61
 
62
  == Changelog ==
63
 
 
 
 
 
 
 
 
64
  = 4.0 =
65
  * New restriction option - show restricted visitor a specified page; use with custom page templates for great for website teasers!
66
  * Major improvements to settings user interface, including hiding unused fields based on settings, easier selection of restriction type, and cleaner "remove" confirmation for IP address list
1
  === Restricted Site Access ===
2
+ Contributors: jakemgold, rcbth, 10up, thinkoomph
3
+ Donate link: http://10up.com/plugins/restricted-site-access-wordpress/
4
+ Tags: privacy, restricted, restrict, privacy, limited, permissions, security, block
5
+ Requires at least: 3.4
6
+ Tested up to: 3.5
7
+ Stable tag: 5.0
8
 
9
+ Limit access to visitors who are logged in or allowed by IP addresses. Includes many options for handling blocked visitors.
10
 
11
  == Description ==
12
 
13
+ Limit access your site to visitors who are logged in or accessing the site from a set of specified IP addresses. Send restricted visitors to the log in page, redirect them, or display a message or page. A great solution for Extranets, publicly hosted Intranets, or parallel development / staging sites.
14
 
15
+ Adds a number of new configuration options to the Reading (WordPress 3.5+) or Privacy (WordPress pre-3.5) settings panel. From this panel you can:
16
 
17
+ 1. Enable or disable site restriction
18
  1. Change the restriction behavior: send to login, redirect, display a message, display a page
19
  1. Add IP addresses to an unrestricted list, including ranges
20
  1. Quickly add your current IP to the unrestricted list
25
 
26
  1. Install easily with the WordPress plugin control panel or manually download the plugin and upload the extracted folder to the `/wp-content/plugins/` directory
27
  1. Activate the plugin through the 'Plugins' menu in WordPress
28
+ 1. Configure the plugin by going to the "Reading" menu (WP3.5+) or "Privacy" (earlier versions) under "Settings"
29
 
30
  == Frequently Asked Questions ==
31
 
32
  = How do I unrestrict specific pages or parts of my site? =
33
 
34
+ Developers can use the `restricted_site_access_is_restricted` filter to override Restricted Site Access. Note that the restriction checks happens before WordPress executes any queries, so use the global `$wp` variable to investigate what the visitor is trying to load.
35
 
36
  For instance, to unblock an RSS feed, place the following PHP code in the theme's functions.php file or in a simple plug-in:
37
 
48
 
49
  = How secure is this plug-in? =
50
 
51
+ Users that are not logged in or allowed by IP address will not be able to browse your site. Restricted Site Access does not block access to your "real" files, so direct links to files in your uploads folder (for instance) are not blocked. It is also important to remember that IP addresses can be spoofed by hackers. Because Restricted Site Access runs as a plug-in, it is subject to any WordPress vulnerabilities.
52
 
53
  Restricted Site Access is not meant to be a top secret data safe, but simply a reliable and convenient way to handle unwanted visitors.
54
 
55
  == Screenshots ==
56
 
57
+ 1. Screenshot of settings panel (WP 3.5) with simple Restricted Site Access option (send to login page).
58
+ 1. Screenshot of settings panel (WP 3.5) with restriction message option enabled
59
+ 1. Plenty of inline help! Looks and behaves like native WordPress help.
 
60
 
61
  == Changelog ==
62
 
63
+ = 5.0 =
64
+ * WordPress 3.5 compatibility (3.5 eliminated the Privacy settings panel in favor of a refreshed Reading panel)
65
+ * Real validation (on the fly and on save) for IP address entries
66
+ * "Restriction message" now supports simple HTML and is edited using WordPress's simple HTML tag editor
67
+ * A bunch of visual refinements that conform better with WordPress 3.4 and newer (spacing, native "shake" effect on invalid entries just like the login form, etc.)
68
+ * A bunch of under the hood refinements (e.g. playing nicer with current screen Help API)
69
+
70
  = 4.0 =
71
  * New restriction option - show restricted visitor a specified page; use with custom page templates for great for website teasers!
72
  * Major improvements to settings user interface, including hiding unused fields based on settings, easier selection of restriction type, and cleaner "remove" confirmation for IP address list
restricted-site-access.dev.js ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function add_ip( ip ) {
2
+ var shake_speed = 600;
3
+ if ( restricted_site_access_l10n.wp_version < 3.5 )
4
+ shake_speed = 60;
5
+
6
+ if ( jQuery.trim(ip) == '' )
7
+ return false;
8
+
9
+ add_btn.attr('disabled', 'disabled');
10
+
11
+ var ips = jQuery('#ip_list input');
12
+ for ( var i = 0, l = ips.length; i < ips.length; i++ ) {
13
+ if( ips[i].value == ip ) {
14
+ jQuery(ips[i]).parent().effect('shake',shake_speed);
15
+ add_btn.removeAttr('disabled');
16
+ return false;
17
+ }
18
+ }
19
+
20
+ jQuery.post( ajaxurl, { action: 'rsa_ip_check', 'ip_address': ip }, function(response) {
21
+ if ( response ) {
22
+ jQuery('#newip').parent().effect('shake',shake_speed);
23
+ add_btn.removeAttr('disabled');
24
+ return false;
25
+ } else {
26
+ jQuery('<div style="display: none;"><input type="text" name="rsa_options[allowed][]" value="' + ip + '" readonly="true" /> <a href="#remove" onclick="remove_ip(this);">' + restricted_site_access_l10n.Remove + '</a></div>').appendTo('#ip_list').slideDown(250);
27
+ if ( ip == jQuery('#newip').val() )
28
+ jQuery('#newip').val('');
29
+ jQuery('#addip').removeAttr('disabled');
30
+ return true;
31
+ }
32
+ } );
33
+ }
34
+
35
+ function remove_ip( btnObj ) {
36
+ jQuery(btnObj).parent().slideUp(250,function(){ jQuery(this).remove(); });
37
+ }
38
+
39
+ var add_btn;
40
+
41
+ jQuery(document).ready(function($){
42
+ // hide and show relevant pieces
43
+ add_btn = $('#addip');
44
+ var rsa_table = $('#rsa-send-to-login').closest('table');
45
+ var rsa_redirect_fields = $('.rsa_redirect_field').closest('tr');
46
+ var rsa_messsage_field = $('#rsa_message').closest('tr');
47
+ var rsa_page_field = $('#rsa_page').closest('tr');
48
+
49
+ if ( ! $('#blog-restricted').is(':checked') )
50
+ rsa_table.hide();
51
+ if ( ! $('#rsa-redirect-visitor').is(':checked') )
52
+ rsa_redirect_fields.hide();
53
+ if ( ! $('#rsa-display-message').is(':checked') )
54
+ rsa_messsage_field.hide();
55
+ if ( ! $('#rsa-unblocked-page').is(':checked') )
56
+ rsa_page_field.hide();
57
+
58
+ $('input[name="rsa_options[approach]"]').change(function(){
59
+ if( $('#rsa-redirect-visitor').is(':checked') )
60
+ rsa_redirect_fields.show();
61
+ else
62
+ rsa_redirect_fields.hide();
63
+
64
+ if( $('#rsa-display-message').is(':checked') )
65
+ rsa_messsage_field.show();
66
+ else
67
+ rsa_messsage_field.hide();
68
+
69
+ if( $('#rsa-unblocked-page').is(':checked') )
70
+ rsa_page_field.show();
71
+ else
72
+ rsa_page_field.hide();
73
+ });
74
+
75
+ $('input[name="blog_public"]').change(function(){
76
+ if( $('#blog-restricted').is(':checked') )
77
+ rsa_table.show();
78
+ else
79
+ rsa_table.hide();
80
+ });
81
+ });
restricted-site-access.js CHANGED
@@ -1,57 +1 @@
1
- // functions for dynamic IP address boxes
2
-
3
- function add_ip(ip) {
4
- if (!jQuery.trim(ip)) return false;
5
-
6
- jQuery('#message').remove();
7
-
8
- var ip_used = false;
9
- jQuery('#ip_list input').each(function(){
10
- if (jQuery(this).val() == ip) {
11
- jQuery(this).animate( { marginLeft: '-45px' }, 250, 'swing', function(){ jQuery(this).animate( { marginLeft: '0px' }, 250, 'swing' ); } );
12
- ip_used = true;
13
- return false;
14
- }
15
- });
16
- if (ip_used) return false;
17
-
18
- jQuery('<span style="display: none;"><input type="text" name="rsa_options[allowed][]" value="'+ip+'" readonly="true" /><input type="button" class="button" onclick="remove_ip(this);" value="' + restricted_site_access_l10n.Remove + '" /> <span class="description">' + restricted_site_access_l10n.SaveChanges + '</span><br /></span>').appendTo('#ip_list').slideDown();
19
- }
20
-
21
- function cancel_remove_ip(btnObj) {
22
- jQuery(btnObj).siblings('.button-primary').removeClass('button-primary').val(restricted_site_access_l10n.Remove);
23
- jQuery(btnObj).remove();
24
- }
25
-
26
- function remove_ip(btnObj) {
27
- var jbtnObj = jQuery(btnObj);
28
- if ( jbtnObj.hasClass('button-primary') ) jbtnObj.parent().slideUp(250,function(){ jQuery(this).remove() });
29
- else jbtnObj.val(restricted_site_access_l10n.ConfirmRemove).addClass('button-primary').after('<input type="button" value="' + restricted_site_access_l10n.Cancel + '" class="button" onclick="cancel_remove_ip(this);" />');
30
- }
31
-
32
- // hide and show relevant pieces
33
- var rsa_table = jQuery('#rsa-send-to-login').closest('table');
34
- var rsa_redirect_fields = jQuery('.rsa_redirect_field').closest('tr');
35
- var rsa_messsage_field = jQuery('#rsa_message').closest('tr');
36
- var rsa_page_field = jQuery('#rsa_page').closest('tr');
37
-
38
- if ( jQuery('#blog-restricted:checked').length <= 0 ) rsa_table.hide();
39
- if ( jQuery('#rsa-redirect-visitor:checked').length <= 0 ) rsa_redirect_fields.hide();
40
- if ( jQuery('#rsa-display-message:checked').length <= 0 ) rsa_messsage_field.hide();
41
- if ( jQuery('#rsa-unblocked-page:checked').length <= 0 ) rsa_page_field.hide();
42
-
43
- jQuery('input[name="rsa_options[approach]"]').change(function(){
44
- if( jQuery('#rsa-redirect-visitor').is(':checked') ) rsa_redirect_fields.show();
45
- else rsa_redirect_fields.hide();
46
-
47
- if( jQuery('#rsa-display-message').is(':checked') ) rsa_messsage_field.show();
48
- else rsa_messsage_field.hide();
49
-
50
- if( jQuery('#rsa-unblocked-page').is(':checked') ) rsa_page_field.show();
51
- else rsa_page_field.hide();
52
- });
53
-
54
- jQuery('input[name="blog_public"]').change(function(){
55
- if( jQuery('#blog-restricted').is(':checked') ) rsa_table.show();
56
- else rsa_table.hide();
57
- });
1
+ function add_ip(e){var t=600;if(restricted_site_access_l10n.wp_version<3.5)t=60;if(jQuery.trim(e)=="")return false;add_btn.attr("disabled","disabled");var n=jQuery("#ip_list input");for(var r=0,i=n.length;r<n.length;r++){if(n[r].value==e){jQuery(n[r]).parent().effect("shake",t);add_btn.removeAttr("disabled");return false}}jQuery.post(ajaxurl,{action:"rsa_ip_check",ip_address:e},function(n){if(n){jQuery("#newip").parent().effect("shake",t);add_btn.removeAttr("disabled");return false}else{jQuery('<div style="display: none;"><input type="text" name="rsa_options[allowed][]" value="'+e+'" readonly="true" /> <a href="#remove" onclick="remove_ip(this);">'+restricted_site_access_l10n.Remove+"</a></div>").appendTo("#ip_list").slideDown(250);if(e==jQuery("#newip").val())jQuery("#newip").val("");jQuery("#addip").removeAttr("disabled");return true}})}function remove_ip(e){jQuery(e).parent().slideUp(250,function(){jQuery(this).remove()})}var add_btn;jQuery(document).ready(function(e){add_btn=e("#addip");var t=e("#rsa-send-to-login").closest("table");var n=e(".rsa_redirect_field").closest("tr");var r=e("#rsa_message").closest("tr");var i=e("#rsa_page").closest("tr");if(!e("#blog-restricted").is(":checked"))t.hide();if(!e("#rsa-redirect-visitor").is(":checked"))n.hide();if(!e("#rsa-display-message").is(":checked"))r.hide();if(!e("#rsa-unblocked-page").is(":checked"))i.hide();e('input[name="rsa_options[approach]"]').change(function(){if(e("#rsa-redirect-visitor").is(":checked"))n.show();else n.hide();if(e("#rsa-display-message").is(":checked"))r.show();else r.hide();if(e("#rsa-unblocked-page").is(":checked"))i.show();else i.hide()});e('input[name="blog_public"]').change(function(){if(e("#blog-restricted").is(":checked"))t.show();else t.hide()})})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
restricted_site_access.php CHANGED
@@ -1,72 +1,111 @@
1
  <?php
2
  /**
3
  Plugin Name: Restricted Site Access
4
- Plugin URI: http://www.get10up.com/plugins/restricted-site-access-wordpress/
5
  Description: <strong>Limit access your site</strong> to visitors who are logged in or accessing the site from a set of specific IP addresses. Send restricted visitors to the log in page, redirect them, or display a message or page. <strong>Powerful control over redirection</strong>, including <strong>SEO friendly redirect headers</strong>. Great solution for Extranets, publicly hosted Intranets, or parallel development sites.
6
- Version: 4.0
7
- Author: Jake Goldman (10up)
8
- Author URI: http://www.get10up.com
9
-
10
- Plugin: Copyright 2011 10up (email : jake@get10up.com)
11
-
12
- This program is free software; you can redistribute it and/or modify
13
- it under the terms of the GNU General Public License as published by
14
- the Free Software Foundation; either version 2 of the License, or
15
- (at your option) any later version.
16
-
17
- This program is distributed in the hope that it will be useful,
18
- but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- GNU General Public License for more details.
21
-
22
- You should have received a copy of the GNU General Public License
23
- along with this program; if not, write to the Free Software
24
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
  */
26
 
27
- class restricted_site_access {
28
 
29
  private $rsa_options;
30
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  public function __construct() {
32
- $this->rsa_options = get_option('rsa_options');
33
 
34
  add_action( 'parse_request', array( $this, 'restrict_access' ), 1 );
35
- add_action( 'admin_init', array( $this, 'admin_init' ) );
36
  add_action( 'init', array( $this, 'init' ) );
37
-
38
- register_activation_hook( __FILE__, array( $this, 'activation' ) );
39
- register_deactivation_hook( __FILE__, array( $this, 'deactivation' ) );
 
40
  }
41
 
42
- function init() {
43
- load_plugin_textdomain( 'restricted-site-access', false, dirname( plugin_basename( __FILE__ ) ) . '/localization/' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
 
46
  public function restrict_access( $wp ) {
47
  remove_action( 'parse_request', array( $this, 'restrict_access' ), 1 ); // only need it the first time
48
 
49
- $is_restricted = ( is_admin() || is_user_logged_in() || get_option('blog_public') != 2 ) ? false : true;
50
-
51
- if ( apply_filters( 'restricted_site_access_is_restricted', $is_restricted ) === false )
52
  return;
53
-
54
- $rsa_options = $this->rsa_options;
55
 
56
  // check for the allow list, if its empty block everything
57
- if( isset($rsa_options['allowed']) && ( $list = $rsa_options['allowed'] ) ) {
58
-
59
  $remote_ip = $_SERVER['REMOTE_ADDR']; //save the remote ip
60
- if( strpos($remote_ip, '.') ) $remote_ip = str_replace('::ffff:', '', $remote_ip); //handle dual-stack addresses
61
- $remote_ip = inet_pton($remote_ip); //parse the remote ip
 
62
 
63
  // iterate through the allow list
64
- foreach($list as $line) {
65
- list($ip, $mask) = explode('/', $line . '/128'); // get the ip and mask from the list
66
 
67
- $mask = str_repeat('f', $mask >> 2); //render the mask as bits, similar to info on the php.net man page discussion for inet_pton
68
 
69
- switch($mask % 4){
70
  case 1:
71
  $mask .= '8';
72
  break;
@@ -78,107 +117,104 @@ class restricted_site_access {
78
  break;
79
  }
80
 
81
- $mask = pack('H*', $mask);
82
 
83
  // check if the masked versions match
84
- if((inet_pton($ip) & $mask) == ($remote_ip & $mask))
85
  return;
86
  }
87
  }
88
 
89
- $rsa_restrict_approach = apply_filters( 'restricted_site_access_approach', $rsa_options['approach'] );
90
-
91
  do_action( 'restrict_site_access_handling', $rsa_restrict_approach ); // allow users to hook handling
92
 
93
  switch( $rsa_restrict_approach ) {
94
  case 4:
95
- if ( ! empty( $rsa_options['page'] ) && ( $page = get_page( $rsa_options['page'] ) ) ) {
96
  unset( $wp->query_vars );
97
- $wp->query_vars['page_id'] = $page->ID;
98
  return;
99
  }
100
 
101
  case 3:
102
- $message = empty($rsa_options['message']) ? __( "Access to this site is restricted.", 'restricted-site-access' ) : $rsa_options['message'];
103
- $message .= "\n<!-- access protected by Restricted Site Access plug-in | http://www.get10up.com/plugins/restricted-site-access-wordpress/ -->";
104
  $message = apply_filters( 'restricted_site_access_message', $message );
105
 
106
- wp_die( $message, get_bloginfo('name') . ' - Site Access Restricted' );
107
 
108
  case 2:
109
- if ( ! empty($rsa_options['redirect_url']) ) {
110
- if( ! empty($rsa_options['redirect_path']) )
111
- $rsa_options['redirect_url'] .= $_SERVER["REQUEST_URI"]; // path
112
-
113
- $rsa_redirect_url = $rsa_options['redirect_url'];
114
- $rsa_redirect_head = empty($rsa_options['head_code']) ? 302 : (int) $rsa_options['head_code']; // code
115
-
116
  break;
117
  }
118
 
119
  default:
120
- $rsa_redirect_head = 302;
121
- $rsa_redirect_url = wp_login_url( empty($_SERVER["REQUEST_URI"]) ? home_url() : $_SERVER["REQUEST_URI"] );
 
122
  }
123
-
124
- wp_redirect( apply_filters( 'restricted_site_access_redirect_url', $rsa_redirect_url ), apply_filters( 'restricted_site_access_head', $rsa_redirect_head ) );
125
- exit;
 
 
126
  }
127
 
128
  public function admin_init() {
 
 
 
129
  // customize privacy message
130
  add_filter( 'privacy_on_link_text', array( $this, 'privacy_on_link_text' ) );
131
  add_filter( 'privacy_on_link_title', array( $this, 'privacy_on_link_title' ) );
132
 
133
  // customize privacy page
134
- add_action( 'load-options-privacy.php', array( $this, 'load_options_privacy' ) );
135
 
136
  // add new choice for blog privacy
137
  add_action( 'blog_privacy_selector', array( $this, 'blog_privacy_selector' ) );
138
 
139
  // settings for restricted site access
140
- register_setting( 'privacy', 'rsa_options', array( $this, 'sanitize_options' ) ); //array of fundamental options including ID and caching info
141
- add_settings_section( 'restricted-site-access', '', '__return_false', 'privacy' );
142
- add_settings_field( 'approach', __('Handle restricted visitors', 'restricted-site-access'), array( $this, 'settings_field_handling' ), 'privacy', 'restricted-site-access' );
143
- add_settings_field( 'message', __('Restriction message', 'restricted-site-access'), array( $this, 'settings_field_message' ), 'privacy', 'restricted-site-access' );
144
- add_settings_field( 'redirect', __('Redirect web address', 'restricted-site-access'), array( $this, 'settings_field_redirect' ), 'privacy', 'restricted-site-access' );
145
- add_settings_field( 'redirect_path', __('Redirect to same path', 'restricted-site-access'), array( $this, 'settings_field_redirect_path' ), 'privacy', 'restricted-site-access' );
146
- add_settings_field( 'redirect_code', __('Redirection status code', 'restricted-site-access'), array( $this, 'settings_field_redirect_code' ), 'privacy', 'restricted-site-access' );
147
- add_settings_field( 'rsa_page', __('Restricted notice page', 'restricted-site-access'), array( $this, 'settings_field_rsa_page' ), 'privacy', 'restricted-site-access' );
148
- add_settings_field( 'allowed', __('Unrestricted IP addresses', 'restricted-site-access'), array( $this, 'settings_field_allowed' ), 'privacy', 'restricted-site-access' );
149
 
150
- add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array( $this, 'plugin_action_links' ) );
151
  }
152
 
153
  public function privacy_on_link_text( $text ) {
154
- if ( get_option('blog_public') == 2 )
155
- $text = __('Public access to this site has been restricted.', 'restricted-site-access');
156
 
157
  return $text;
158
  }
159
 
160
  public function privacy_on_link_title( $text ) {
161
- if ( get_option('blog_public') == 2 )
162
- $text = __('Restricted Site Access plug-in is blocking public access to this site.', 'restricted-site-access');
163
 
164
  return $text;
165
  }
166
 
167
- public function load_options_privacy() {
168
- wp_enqueue_script( 'restricted-site-access', plugin_dir_url( __FILE__ ) . 'restricted-site-access.js', array('jquery'), '3.3', true );
169
- add_filter( 'contextual_help', array( $this, 'contextual_help' ) );
 
 
 
 
 
170
  add_action( 'admin_notices', array( $this, 'admin_notice' ) );
171
-
172
- $js_trans = array(
173
- 'SaveChanges' => __('Click "Save Changes" to save this IP address.','restricted-site-access'),
174
- 'Remove' => __('remove','restricted-site-access'),
175
- 'ConfirmRemove' => __('confirm removal','restricted-site-access'),
176
- 'Cancel' => __('cancel','restricted-site-access')
177
- );
178
- wp_localize_script( 'restricted-site-access', 'restricted_site_access_l10n', $js_trans );
179
  }
180
 
181
- function admin_notice() {
182
  if ( empty( $this->rsa_options['approach'] ) )
183
  return;
184
 
@@ -190,27 +226,50 @@ class restricted_site_access {
190
  if ( ! empty( $message ) )
191
  echo '<div class="updated settings-error"><p>' . $message . '</p></div>';
192
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
  public function blog_privacy_selector() {
195
  ?>
196
- <br />
197
- <input id="blog-restricted" type="radio" name="blog_public" value="2" <?php checked( '2', get_option('blog_public') ); ?> />
198
- <label for="blog-restricted"><?php _e('Restrict site access to visitors who are logged in or allowed by IP address', 'restricted-site-access'); ?></label>
199
  <?php
200
  }
201
 
202
  public function sanitize_options( $input ) {
203
  $new_input['approach'] = (int) $input['approach'];
204
  if ( $new_input['approach'] < 1 || $new_input['approach'] > 4 )
205
- $new_input['approach'] = 1;
206
-
 
 
 
207
  $new_input['redirect_path'] = empty( $input['redirect_path'] ) ? 0 : 1;
208
- $new_input['head_code'] = in_array( (int) $input['head_code'], array(301,302,307) ) ? (int) $input['head_code'] : 302;
209
- $new_input['message'] = trim( $input['message'] );
210
- $new_input['redirect_url'] = empty( $input['redirect_url'] ) ? '' : esc_url( $input['redirect_url'], array('http','https') );
211
- $new_input['page'] = empty( $input['page'] ) ? '' : (int) $input['page'];
212
-
213
- $new_input['allowed'] = $input['allowed']; // probably need regex at some point
 
 
 
 
 
214
 
215
  return $new_input;
216
  }
@@ -238,24 +297,21 @@ class restricted_site_access {
238
  public function settings_field_allowed( $args ) {
239
  ?>
240
  <div class="hide-if-no-js">
241
- <div id="ip_list">
242
- <?php
243
- $ips = empty($this->rsa_options['allowed']) ? array() : $this->rsa_options['allowed'];
244
-
245
- foreach ($ips as $key => $ip) {
246
- if ( empty($ip) )
247
- continue;
248
-
249
- echo '<span><input type="text" name="rsa_options[allowed][]" value="' . esc_attr($ip) . '" readonly="true" /><input type="button" class="button" onclick="remove_ip(this);" value="' . __('remove','restricted-site-access') . '" /><br /></span>';
250
- }
251
- ?>
252
- </div>
253
- <input type="text" name="newip" id="newip" value="" /><input class="button" type="button" onclick="add_ip(jQuery('#newip').val());" value="<?php _e('add','restricted-site-access'); ?>" />
254
- <span class="description"><?php _e('Enter a single IP address or a range using a subnet prefix','restricted-site-access'); ?> (<a href="#" onclick="jQuery('#contextual-help-link').click(); return false;"><?php _e('help'); ?></a>)</span>
255
- <br />
256
- <?php if ( ! empty($_SERVER['REMOTE_ADDR']) ) { ?>
257
- <input class="button" type="button" onclick="add_ip('<?php echo $_SERVER['REMOTE_ADDR']; ?>');" value="<?php _e('add my current IP address','restricted-site-access'); ?>" style="margin: 5px 0;" /><br />
258
- <?php } ?>
259
  </div>
260
  <p class="hide-if-js"><strong><?php _e('To manage IP addresses, you must use a JavaScript enabled browser.','restricted-site-access'); ?></strong></p>
261
  <?php
@@ -264,9 +320,13 @@ class restricted_site_access {
264
  public function settings_field_message( $args ) {
265
  if ( empty($this->rsa_options['message']) )
266
  $this->rsa_options['message'] = __('Access to this site is restricted.','restricted-site-access');
267
- ?>
268
- <input type="text" name="rsa_options[message]" id="rsa_message" value="<?php echo esc_attr( $this->rsa_options['message'] ); ?>" class="regular-text" />
269
- <?php
 
 
 
 
270
  }
271
 
272
  public function settings_field_redirect( $args ) {
@@ -278,7 +338,7 @@ class restricted_site_access {
278
  public function settings_field_redirect_path( $args ) {
279
  ?>
280
  <input type="checkbox" name="rsa_options[redirect_path]" value="1" id="redirect_path" class="rsa_redirect_field" <?php @checked( $this->rsa_options['redirect_path'] ); ?> />
281
- <?php _e('Send restricted visitor to same path (relative URL) at the new web address','restricted-site-access'); ?> (<a href="#" onclick="jQuery('#contextual-help-link').click(); return false;"><?php _e('help'); ?></a>)
282
  <?php
283
  }
284
 
@@ -287,48 +347,60 @@ class restricted_site_access {
287
  $this->rsa_options['head_code'] = 302;
288
  ?>
289
  <select name="rsa_options[head_code]" id="redirect_code" class="rsa_redirect_field">
290
- <option value="301" <?php selected( $this->rsa_options['head_code'], 301 ); ?>><?php _e('301 Permanent','restricted-site-access'); ?></option>
291
- <option value="302" <?php selected( $this->rsa_options['head_code'], 302 ); ?>><?php _e('302 Undefined','restricted-site-access'); ?></option>
292
- <option value="307" <?php selected( $this->rsa_options['head_code'], 307 ); ?>><?php _e('307 Temporary','restricted-site-access'); ?></option>
293
  </select>
294
- <span class="description"><?php _e('HTTP status code sent to browser','restricted-site-access'); ?> (<a href="#" onclick="jQuery('#contextual-help-link').click(); return false;"><?php _e('help'); ?></a>)</span>
295
  <?php
296
  }
297
 
298
  public function settings_field_rsa_page( $args ) {
299
  wp_dropdown_pages(array(
300
- 'selected' => @$this->rsa_options['page'],
301
  'show_option_none' => 'Select a page',
302
  'name' => 'rsa_options[page]',
303
  'id' => 'rsa_page'
304
  ));
305
  }
306
-
307
  /**
308
- * special contextual help added to the privacy screen
309
  */
310
- public function contextual_help( $text )
311
- {
312
- return $text . '
313
- <h5>Restricted Site Access</h5>
314
- <p><a href="http://www.get10up.com/plugins/restricted-site-access-wordpress/" target="_blank">Restricted Site Access</a> ' . __('is a plug-in by','restricted-site-access') . ' <a href="http://www.get10up.com" target="_blank">Jake Goldman</a> (<a href="http://www.get10up.com/plugins/restricted-site-access-wordpress/" target="_blank">10up</a>) ' . __('that allows you to restrict access to logged in users and a set of IP addresses.','restricted-site-access') . '</p>
315
-
316
- <p><strong>' . __('Handle restricted visitors','restricted-site-access') . '</strong> - ' . __('choose the method for handling visitors to your site that are restricted.','restricted-site-access') . '</p>
317
- <p><strong>' . __('Allowed IP addresses','restricted-site-access') . '</strong> - ' . __('enter a single IP address (for example, 192.168.1.105) or an IP range using a network prefix (for example, 10.0.0.1/24). Enter your addresses carefully! Here\'s a','restricted-site-access') . ' <a href="http://www.csgnetwork.com/ipinfocalc.html" target="_blank">' . __('handy calculator','restricted-site-access') . '</a> ' . __('to check your prefix.','restricted-site-access') . '</p>
318
-
319
- <h5>' . __('Redirection Options','restricted-site-access') . '</h5>
320
- <p>' . __('The redirection fields are only used when "Handle restricted visitors" is set to "Redirect them to a specified web address".','restricted-site-access') . '</p>
321
- <p><strong>' . __('Redirect web address','restricted-site-access') . '</strong> - ' . __('the web address of the site you want the visitor redirected to.','restricted-site-access') . '</p>
322
- <p><strong>' . __('Redirect to same path','restricted-site-access') . '</strong> - ' . __('redirect the visitor to the same path (URI) entered at this site. Typically used when there are two, very similar sites at different public web addresses; for instance, a parallel development server accessible on the Internet but not intended for the public.','restricted-site-access') . '</p>
323
- <p><strong>' . __('Redirection status code','restricted-site-access') . '</strong> - ' . __('redirect status codes can provide certain visitors, particularly search engines, more information about the nature of the redirect. A 301 redirect tells search engines that a page has moved permanently to the new location. 307 indicates a temporary redirect. 302 is an undefined redirect.','restricted-site-access') . '</p>
324
- ';
325
  }
326
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  /**
328
  * add settings link directing user to privacy page on plug-in page
329
  */
330
  public function plugin_action_links( $links ) {
331
- $links[] = '<a href="options-privacy.php">'.__('Settings').'</a>';
332
  return $links;
333
  }
334
 
@@ -336,21 +408,19 @@ class restricted_site_access {
336
  * activation of plugin: upgrades old versions, immediately sets privacy
337
  */
338
  public function activation() {
339
- // if upgrading from pre-3.0, update the blog_public option, otherwise just set to 2
340
- $blog_public = ( isset($this->rsa_options['active']) && ! $this->rsa_options['active'] ) ? 1 : 2;
341
- update_option( 'blog_public', $blog_public ); // set blog visibility
342
  }
343
 
344
  /**
345
  * restore privacy option to default value upon deactivating
346
  */
347
  public function deactivation() {
348
- if ( get_option('blog_public') == 2 )
349
  update_option( 'blog_public', 1 );
350
  }
351
  }
352
 
353
- $restricted_site_access = new restricted_site_access;
354
 
355
  /**
356
  * uninstall hook - remove options
@@ -363,4 +433,28 @@ function restricted_site_access_uninstall() {
363
  update_option( 'blog_public', 1 );
364
 
365
  delete_option('rsa_options');
366
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
  /**
3
  Plugin Name: Restricted Site Access
4
+ Plugin URI: http://10up.com/plugins/restricted-site-access-wordpress/
5
  Description: <strong>Limit access your site</strong> to visitors who are logged in or accessing the site from a set of specific IP addresses. Send restricted visitors to the log in page, redirect them, or display a message or page. <strong>Powerful control over redirection</strong>, including <strong>SEO friendly redirect headers</strong>. Great solution for Extranets, publicly hosted Intranets, or parallel development sites.
6
+ Version: 5.0
7
+ Author: Jake Goldman, 10up, Oomph
8
+ Author URI: http://10up.com
9
+ License: GPLv2 or later
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  */
11
 
12
+ class Restricted_Site_Access {
13
 
14
  private $rsa_options;
15
+ private $basename;
16
+ private $settings_page = 'privacy';
17
+ private $fields = array(
18
+ 'approach' => array(
19
+ 'default' => 1,
20
+ 'label' => 'Handle restricted visitors',
21
+ 'field' => 'settings_field_handling',
22
+ ),
23
+ 'message' => array(
24
+ 'default' => 'Access to this site is restricted.',
25
+ 'label' => 'Restriction message',
26
+ 'field' => 'settings_field_message',
27
+ ),
28
+ 'redirect_url' => array(
29
+ 'default' => '',
30
+ 'label' => 'Redirect web address',
31
+ 'field' => 'settings_field_redirect',
32
+ ),
33
+ 'redirect_path' => array(
34
+ 'default' => 0,
35
+ 'label' => 'Redirect to same path',
36
+ 'field' => 'settings_field_redirect_path',
37
+ ),
38
+ 'head_code' => array(
39
+ 'default' => 302,
40
+ 'label' => 'Redirection status code',
41
+ 'field' => 'settings_field_redirect_code',
42
+ ),
43
+ 'page' => array(
44
+ 'default' => 0,
45
+ 'label' => 'Restricted notice page',
46
+ 'field' => 'settings_field_rsa_page',
47
+ ),
48
+ 'allowed' => array(
49
+ 'default' => array(),
50
+ 'label' => 'Unrestricted IP addresses',
51
+ 'field' => 'settings_field_allowed',
52
+ ),
53
+ );
54
+
55
  public function __construct() {
56
+ $this->basename = plugin_basename( __FILE__ );
57
 
58
  add_action( 'parse_request', array( $this, 'restrict_access' ), 1 );
59
+ add_action( 'admin_init', array( $this, 'admin_init' ), 1 );
60
  add_action( 'init', array( $this, 'init' ) );
61
+ add_action( 'wp_ajax_rsa_ip_check', array( $this, 'ajax_rsa_ip_check' ) );
62
+
63
+ add_action( 'activate_' . $this->basename, array( $this, 'activation' ) );
64
+ add_action( 'deactivate_' . $this->basename, array( $this, 'deactivation' ) );
65
  }
66
 
67
+ public function init() {
68
+ load_plugin_textdomain( 'restricted-site-access', false, dirname( $this->basename ) . '/localization/' );
69
+ }
70
+
71
+ /**
72
+ * populate the option with defaults
73
+ */
74
+ private function set_option_defaults() {
75
+ if ( ! empty( $this->rsa_options ) )
76
+ return;
77
+
78
+ // set default options
79
+ $this->rsa_options = (array) get_option( 'rsa_options' );
80
+ foreach( $this->fields as $field_name => $field_details ) {
81
+ if ( ! isset( $this->rsa_options[$field_name] ) )
82
+ $this->rsa_options[$field_name] = $field_details['default'];
83
+ }
84
  }
85
 
86
  public function restrict_access( $wp ) {
87
  remove_action( 'parse_request', array( $this, 'restrict_access' ), 1 ); // only need it the first time
88
 
89
+ $is_restricted = ( is_admin() || is_user_logged_in() || get_option( 'blog_public' ) != 2 ) ? false : true;
90
+ if ( apply_filters( 'restricted_site_access_is_restricted', $is_restricted, $wp ) === false )
 
91
  return;
92
+
93
+ $this->set_option_defaults();
94
 
95
  // check for the allow list, if its empty block everything
96
+ if ( $list = $this->rsa_options['allowed'] ) {
 
97
  $remote_ip = $_SERVER['REMOTE_ADDR']; //save the remote ip
98
+ if ( strpos( $remote_ip, '.' ) )
99
+ $remote_ip = str_replace( '::ffff:', '', $remote_ip ); //handle dual-stack addresses
100
+ $remote_ip = inet_pton( $remote_ip ); //parse the remote ip
101
 
102
  // iterate through the allow list
103
+ foreach( $list as $line ) {
104
+ list( $ip, $mask ) = explode( '/', $line . '/128' ); // get the ip and mask from the list
105
 
106
+ $mask = str_repeat( 'f', $mask >> 2 ); //render the mask as bits, similar to info on the php.net man page discussion for inet_pton
107
 
108
+ switch( $mask % 4 ) {
109
  case 1:
110
  $mask .= '8';
111
  break;
117
  break;
118
  }
119
 
120
+ $mask = pack( 'H*', $mask );
121
 
122
  // check if the masked versions match
123
+ if ( ( inet_pton( $ip ) & $mask ) == ( $remote_ip & $mask ) )
124
  return;
125
  }
126
  }
127
 
128
+ $rsa_restrict_approach = apply_filters( 'restricted_site_access_approach', $this->rsa_options['approach'] );
 
129
  do_action( 'restrict_site_access_handling', $rsa_restrict_approach ); // allow users to hook handling
130
 
131
  switch( $rsa_restrict_approach ) {
132
  case 4:
133
+ if ( $this->rsa_options['page'] && ( $page_id = get_post_field( 'ID', $this->rsa_options['page'] ) ) ) {
134
  unset( $wp->query_vars );
135
+ $wp->query_vars['page_id'] = $page_id;
136
  return;
137
  }
138
 
139
  case 3:
140
+ $message = __( $this->rsa_options['message'], 'restricted-site-access' );
141
+ $message .= "\n<!-- access protected by Restricted Site Access plug-in | http://10up.com/plugins/restricted-site-access-wordpress/ -->";
142
  $message = apply_filters( 'restricted_site_access_message', $message );
143
 
144
+ wp_die( $message, get_bloginfo( 'name' ) . ' - Site Access Restricted' );
145
 
146
  case 2:
147
+ if ( $this->rsa_options['redirect_url'] ) {
148
+ if( ! empty( $this->rsa_options['redirect_path'] ) )
149
+ $this->rsa_options['redirect_url'] = untrailingslashit( $this->rsa_options['redirect_url'] ) . $_SERVER["REQUEST_URI"]; // path
 
 
 
 
150
  break;
151
  }
152
 
153
  default:
154
+ $this->rsa_options['redirect_path'] = 302;
155
+ $current_path = empty( $_SERVER["REQUEST_URI"] ) ? home_url() : $_SERVER["REQUEST_URI"];
156
+ $this->rsa_options['redirect_url'] = wp_login_url( $current_path );
157
  }
158
+
159
+ $redirect_url = apply_filters( 'restricted_site_access_redirect_url', $this->rsa_options['redirect_url'] );
160
+ $redirect_code = apply_filters( 'restricted_site_access_head', $this->rsa_options['redirect_path'] );
161
+ wp_redirect( $redirect_url, $redirect_code );
162
+ die;
163
  }
164
 
165
  public function admin_init() {
166
+ if ( version_compare( floatval( get_bloginfo( 'version' ) ), '3.5', '>=' ) )
167
+ $this->settings_page = 'reading';
168
+
169
  // customize privacy message
170
  add_filter( 'privacy_on_link_text', array( $this, 'privacy_on_link_text' ) );
171
  add_filter( 'privacy_on_link_title', array( $this, 'privacy_on_link_title' ) );
172
 
173
  // customize privacy page
174
+ add_action( 'load-options-' . $this->settings_page . '.php', array( $this, 'load_options_page' ) );
175
 
176
  // add new choice for blog privacy
177
  add_action( 'blog_privacy_selector', array( $this, 'blog_privacy_selector' ) );
178
 
179
  // settings for restricted site access
180
+ register_setting( $this->settings_page, 'rsa_options', array( $this, 'sanitize_options' ) ); // array of fundamental options including ID and caching info
181
+ add_settings_section( 'restricted-site-access', '', '__return_false', $this->settings_page );
182
+ foreach ( $this->fields as $field_name => $field_data ) {
183
+ add_settings_field( $field_name, __( $field_data['label'], 'restricted-site-access' ), array( $this, $field_data['field'] ), $this->settings_page, 'restricted-site-access' );
184
+ }
 
 
 
 
185
 
186
+ add_filter( 'plugin_action_links_' . $this->basename, array( $this, 'plugin_action_links' ) );
187
  }
188
 
189
  public function privacy_on_link_text( $text ) {
190
+ if ( get_option( 'blog_public' ) == 2 )
191
+ $text = __( 'Public access to this site has been restricted.', 'restricted-site-access' );
192
 
193
  return $text;
194
  }
195
 
196
  public function privacy_on_link_title( $text ) {
197
+ if ( get_option( 'blog_public' ) == 2 )
198
+ $text = __( 'Restricted Site Access plug-in is blocking public access to this site.', 'restricted-site-access' );
199
 
200
  return $text;
201
  }
202
 
203
+ public function load_options_page() {
204
+ $dev = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.dev' : '';
205
+ wp_enqueue_script( 'restricted-site-access', plugin_dir_url( __FILE__ ) . 'restricted-site-access'.$dev.'.js', array('jquery-effects-shake'), '5.0', true );
206
+ wp_localize_script( 'restricted-site-access', 'restricted_site_access_l10n', array(
207
+ 'Remove' => __('Remove','restricted-site-access'),
208
+ 'wp_version' => floatval( get_bloginfo( 'version' ) ),
209
+ ) );
210
+
211
  add_action( 'admin_notices', array( $this, 'admin_notice' ) );
212
+ add_action( 'admin_head', array( $this, 'admin_head' ) );
213
+
214
+ $this->set_option_defaults();
 
 
 
 
 
215
  }
216
 
217
+ public function admin_notice() {
218
  if ( empty( $this->rsa_options['approach'] ) )
219
  return;
220
 
226
  if ( ! empty( $message ) )
227
  echo '<div class="updated settings-error"><p>' . $message . '</p></div>';
228
  }
229
+
230
+ public function admin_head() {
231
+ $screen = get_current_screen();
232
+ $screen->add_help_tab( array(
233
+ 'id' => 'restricted-site-access',
234
+ 'title' => __('Restricted Site Acccess'),
235
+ 'content' => '
236
+ <p><strong>' . __('Handle restricted visitors','restricted-site-access') . '</strong> - ' . __('choose the method for handling visitors to your site that are restricted.','restricted-site-access') . '</p>
237
+ <p><strong>' . __('Allowed IP addresses','restricted-site-access') . '</strong> - ' . __('enter a single IP address (for example, 192.168.1.105) or an IP range using a network prefix (for example, 10.0.0.1/24). Enter your addresses carefully! Here\'s a','restricted-site-access') . ' <a href="http://www.csgnetwork.com/ipinfocalc.html" target="_blank">' . __('handy calculator','restricted-site-access') . '</a> ' . __('to check your prefix.','restricted-site-access') . '</p>
238
+ <p>' . __('The redirection fields are only used when "Handle restricted visitors" is set to "Redirect them to a specified web address".','restricted-site-access') . '</p>
239
+ <p><strong>' . __('Redirect web address','restricted-site-access') . '</strong> - ' . __('the web address of the site you want the visitor redirected to.','restricted-site-access') . '</p>
240
+ <p><strong>' . __('Redirect to same path','restricted-site-access') . '</strong> - ' . __('redirect the visitor to the same path (URI) entered at this site. Typically used when there are two, very similar sites at different public web addresses; for instance, a parallel development server accessible on the Internet but not intended for the public.','restricted-site-access') . '</p>
241
+ <p><strong>' . __('Redirection status code','restricted-site-access') . '</strong> - ' . __('redirect status codes can provide certain visitors, particularly search engines, more information about the nature of the redirect. A 301 redirect tells search engines that a page has moved permanently to the new location. 307 indicates a temporary redirect. 302 is an undefined redirect.','restricted-site-access') . '</p>
242
+ ',
243
+ ) );
244
+ }
245
 
246
  public function blog_privacy_selector() {
247
  ?>
248
+ <input id="blog-restricted" type="radio" name="blog_public" value="2" <?php checked( get_option( 'blog_public' ), 2 ); ?> />
249
+ <label for="blog-restricted"><?php _e( 'Restrict site access to visitors who are logged in or allowed by IP address', 'restricted-site-access' ); ?></label>
 
250
  <?php
251
  }
252
 
253
  public function sanitize_options( $input ) {
254
  $new_input['approach'] = (int) $input['approach'];
255
  if ( $new_input['approach'] < 1 || $new_input['approach'] > 4 )
256
+ $new_input['approach'] = $this->fields['approach']['default'];
257
+
258
+ global $allowedtags;
259
+ $new_input['message'] = wp_kses( $input['message'], $allowedtags );
260
+
261
  $new_input['redirect_path'] = empty( $input['redirect_path'] ) ? 0 : 1;
262
+ $new_input['head_code'] = in_array( (int) $input['head_code'], array( 301, 302, 307 ) ) ? (int) $input['head_code'] : $this->fields['head_code']['default'];
263
+ $new_input['redirect_url'] = empty( $input['redirect_url'] ) ? '' : esc_url_raw( $input['redirect_url'], array('http','https') );
264
+ $new_input['page'] = empty( $input['page'] ) ? 0 : (int) $input['page'];
265
+
266
+ $new_input['allowed'] = array();
267
+ if ( !empty( $input['allowed'] ) && is_array( $input['allowed'] ) ) {
268
+ foreach( $input['allowed'] as $ip_address ) {
269
+ if ( $this->is_ip( $ip_address ) )
270
+ $new_input['allowed'][] = $ip_address;
271
+ }
272
+ }
273
 
274
  return $new_input;
275
  }
297
  public function settings_field_allowed( $args ) {
298
  ?>
299
  <div class="hide-if-no-js">
300
+ <div id="ip_list">
301
+ <?php
302
+ foreach ( (array) $this->rsa_options['allowed'] as $ip) {
303
+ if ( empty( $ip ) )
304
+ continue;
305
+
306
+ echo '<div><input type="text" name="rsa_options[allowed][]" value="' . esc_attr( $ip ) . '" readonly="true" /> <a href="#remove" onclick="remove_ip(this);">' . __( 'Remove' ) . '</a></div>';
307
+ }
308
+ ?>
309
+ </div>
310
+ <div>
311
+ <input type="text" name="newip" id="newip" /> <input class="button" type="button" id="addip" onclick="add_ip(jQuery('#newip').val());" value="<?php _e( 'Add' ); ?>" />
312
+ <label for="newip"><span class="description"><?php _e('Enter a single IP address or a range using a subnet prefix','restricted-site-access'); ?></span></label>
313
+ </div>
314
+ <?php if ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) { ?><input class="button" type="button" onclick="add_ip('<?php echo esc_attr( $_SERVER['REMOTE_ADDR'] ); ?>');" value="<?php _e( 'Add My Current IP Address', 'restricted-site-access' ); ?>" style="margin-top: 5px;" /><br /><?php } ?>
 
 
 
315
  </div>
316
  <p class="hide-if-js"><strong><?php _e('To manage IP addresses, you must use a JavaScript enabled browser.','restricted-site-access'); ?></strong></p>
317
  <?php
320
  public function settings_field_message( $args ) {
321
  if ( empty($this->rsa_options['message']) )
322
  $this->rsa_options['message'] = __('Access to this site is restricted.','restricted-site-access');
323
+
324
+ wp_editor( $this->rsa_options['message'], 'rsa_message', array(
325
+ 'media_buttons' => false,
326
+ 'textarea_name' => 'rsa_options[message]',
327
+ 'textarea_rows' => 4,
328
+ 'tinymce' => false,
329
+ ) );
330
  }
331
 
332
  public function settings_field_redirect( $args ) {
338
  public function settings_field_redirect_path( $args ) {
339
  ?>
340
  <input type="checkbox" name="rsa_options[redirect_path]" value="1" id="redirect_path" class="rsa_redirect_field" <?php @checked( $this->rsa_options['redirect_path'] ); ?> />
341
+ <?php _e( 'Send restricted visitor to same path (relative URL) at the new web address', 'restricted-site-access' ); ?>
342
  <?php
343
  }
344
 
347
  $this->rsa_options['head_code'] = 302;
348
  ?>
349
  <select name="rsa_options[head_code]" id="redirect_code" class="rsa_redirect_field">
350
+ <option value="301" <?php selected( $this->rsa_options['head_code'], 301 ); ?>><?php _e( '301 Permanent', 'restricted-site-access' ); ?></option>
351
+ <option value="302" <?php selected( $this->rsa_options['head_code'], 302 ); ?>><?php _e( '302 Undefined', 'restricted-site-access' ); ?></option>
352
+ <option value="307" <?php selected( $this->rsa_options['head_code'], 307 ); ?>><?php _e( '307 Temporary', 'restricted-site-access' ); ?></option>
353
  </select>
354
+ <span class="description"><?php _e( 'HTTP status code sent to browser', 'restricted-site-access' ); ?></span>
355
  <?php
356
  }
357
 
358
  public function settings_field_rsa_page( $args ) {
359
  wp_dropdown_pages(array(
360
+ 'selected' => $this->rsa_options['page'],
361
  'show_option_none' => 'Select a page',
362
  'name' => 'rsa_options[page]',
363
  'id' => 'rsa_page'
364
  ));
365
  }
366
+
367
  /**
368
+ * validate IP address entry on demand (AJAX)
369
  */
370
+ public function ajax_rsa_ip_check() {
371
+ if ( empty( $_POST['ip_address'] ) )
372
+ die('1');
373
+
374
+ if ( $this->is_ip( stripslashes( $_POST['ip_address'] ) ) )
375
+ die;
376
+ else
377
+ die('1');
 
 
 
 
 
 
 
378
  }
379
+
380
+ /**
381
+ * is it a valid IP address? v4/v6 with subnet range
382
+ */
383
+ public function is_ip( $ip_address ) {
384
+ // very basic validation of ranges
385
+ if ( strpos( $ip_address, '/' ) ) {
386
+ $ip_parts = explode( '/', $ip_address );
387
+ if ( empty( $ip_parts[1] ) || !is_numeric( $ip_parts[1] ) || strlen( $ip_parts[1] ) > 3 )
388
+ return false;
389
+ $ip_address = $ip_parts[0];
390
+ }
391
+
392
+ // confirm IP part is a valid IPv6 or IPv4 IP
393
+ if ( empty( $ip_address ) || !inet_pton( stripslashes( $ip_address ) ) )
394
+ return false;
395
+
396
+ return true;
397
+ }
398
+
399
  /**
400
  * add settings link directing user to privacy page on plug-in page
401
  */
402
  public function plugin_action_links( $links ) {
403
+ $links[] = '<a href="options-' . $this->settings_page . '.php">' . __('Settings') . '</a>';
404
  return $links;
405
  }
406
 
408
  * activation of plugin: upgrades old versions, immediately sets privacy
409
  */
410
  public function activation() {
411
+ update_option( 'blog_public', 2 );
 
 
412
  }
413
 
414
  /**
415
  * restore privacy option to default value upon deactivating
416
  */
417
  public function deactivation() {
418
+ if ( get_option( 'blog_public' ) == 2 )
419
  update_option( 'blog_public', 1 );
420
  }
421
  }
422
 
423
+ $restricted_site_access = new Restricted_Site_Access;
424
 
425
  /**
426
  * uninstall hook - remove options
433
  update_option( 'blog_public', 1 );
434
 
435
  delete_option('rsa_options');
436
+ }
437
+
438
+ /**
439
+ * inet_pton is not included in PHP < 5.3 on Windows (WP requires PHP 5.2)
440
+ */
441
+
442
+ if ( ! function_exists( 'inet_pton' ) ) :
443
+
444
+ function inet_pton($ip) {
445
+ if (strpos($ip, '.') !== false) {
446
+ // ipv4
447
+ $ip = pack('N',ip2long($ip));
448
+ } elseif (strpos($ip, ':') !== false) {
449
+ // ipv6
450
+ $ip = explode(':', $ip);
451
+ $res = str_pad('', (4*(8-count($ip))), '0000', STR_PAD_LEFT);
452
+ foreach ($ip as $seg) {
453
+ $res .= str_pad($seg, 4, '0', STR_PAD_LEFT);
454
+ }
455
+ $ip = pack('H'.strlen($res), $res);
456
+ }
457
+ return $ip;
458
+ }
459
+
460
+ endif;
screenshot-1.png CHANGED
Binary file
screenshot-2.png CHANGED
Binary file
screenshot-3.png CHANGED
Binary file
screenshot-4.png DELETED
Binary file