Restricted Site Access - Version 7.2.0

Version Description

  • Added: Warn and confirm before network disabling the plugin (props @pereirinha, @adamsilverstein)
  • Fixed: Ensure comments associated with IPs stay associated correctly (props @adamsilverstein, @ivankk, @helen)
  • Fixed: Don't show escaped HTML in page caching notice (props @adamsilverstein, @aaemnnosttv)
  • Fixed: Multisite: Avoid a redirect loop when logging in as user with no role (props @phyrax, @adamsilverstein, @roytanck, @helen, @rmccue)
Download this release

Release Info

Developer 10upbot
Plugin Icon 128x128 Restricted Site Access
Version 7.2.0
Comparing to
See all releases

Code changes from version 7.1.0 to 7.2.0

assets/css/admin.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ input#rsa-user-message {
2
+ font-size: 2em;
3
+ min-width: 250px;
4
+ }
5
+
6
+ .rsa-user-message {
7
+ text-align: center
8
+ }
assets/js/admin.min.js CHANGED
@@ -1 +1 @@
1
- !function(a,b){"use strict";b(".notice").on("click",".notice-dismiss",function(a){a.delegateTarget.getAttribute("data-rsa-notice")&&b.ajax({method:"post",data:{nonce:rsaAdmin.nonce,action:"rsa_notice_dismiss"},url:ajaxurl})})}(window,jQuery);
1
+ !function(e,s){"use strict";s(".notice").on("click",".notice-dismiss",function(e){e.delegateTarget.getAttribute("data-rsa-notice")&&s.ajax({method:"post",data:{nonce:rsaAdmin.nonce,action:"rsa_notice_dismiss"},url:ajaxurl})})}(window,jQuery),function(s,i){"use strict";({els:{dialog:document.getElementById("rsa-disable-dialog"),userMessage:document.getElementById("rsa-user-message")},variables:{expectedAnswer:rsaAdmin.strings.message.toLowerCase(),disablingURL:null},openDialog:function(e){e.preventDefault(),i(this.els.dialog).dialog("open")},isExpectedAnswer:function(){return this.els.userMessage.value.toLowerCase()===this.variables.expectedAnswer},dialogSettings:function(){var e=this;e.close=function(){i(e.els.dialog).dialog("close"),e.els.userMessage.style.border="1px solid #ddd",e.els.userMessage.value=""},i(this.els.dialog).dialog({dialogClass:"wp-dialog",autoOpen:!1,draggable:!1,width:"auto",modal:!0,resizable:!1,buttons:[{text:rsaAdmin.strings.confirm,click:function(){e.isExpectedAnswer()?s.location.href=e.variables.disablingURL:e.els.userMessage.style.border="1px solid red"}},{text:rsaAdmin.strings.cancel,click:function(){e.close()},class:"button-primary"}],open:function(){i(".ui-widget-overlay").bind("click",function(){e.close()})},create:function(){i(".ui-dialog-titlebar-close").addClass("ui-button"),i(this).siblings(".ui-dialog-titlebar").hide()}}),this.els.buttons=i(this.els.dialog).dialog("option","buttons")},maybeSubmit:function(e){switch(e.key){case"Enter":this.els.buttons[0].click()}},bindEvents:function(){i('[data-slug="restricted-site-access"]').on("click",".deactivate a",this.openDialog.bind(this)),this.els.userMessage.addEventListener("keyup",this.maybeSubmit.bind(this))},init:function(){rsaAdmin.isNetworkWidePluginsPage&&(this.variables.disablingURL=document.getElementById("the-list").querySelector('[data-slug="restricted-site-access"] .deactivate a').href,this.bindEvents(),this.dialogSettings())}}).init()}(window,jQuery);
assets/js/settings.min.js CHANGED
@@ -1 +1 @@
1
- !function(a,b){"use strict";function c(a,c){if(""==b.trim(a))return!1;e.add_btn.attr("disabled","disabled");var f=b(d.querySelectorAll("#ip_list input")),g=0;for(f.length;g<f.length;g++)if(f[g].value==a)return b(f[g]).parent().effect("shake",600),e.add_btn.removeAttr("disabled"),!1;jQuery.post(ajaxurl,{action:"rsa_ip_check",ip_address:a,ip_address_comment:c,nonce:rsaAdmin.nonce},function(d){if(d)return b(e.new_ip.parentNode).effect("shake",600),e.add_btn.removeAttr("disabled"),!1;var f=e.empty_ip.clone().appendTo(e.ip_list_wrap);return f.children("input.ip").val(a),f.children("input.comment").val(c),f.removeAttr("id").slideDown(250),a==e.new_ip.value&&(b(e.new_ip).val(""),b(e.new_ip_comment).val("")),e.add_btn.removeAttr("disabled"),!0})}var d=a.document,e={add_btn:"",new_ip:"",ip_list_wrap:"",empty_ip:"",restrict_radio:"",table:"",redirect_choice:"",message_choice:"",page_choice:"",redirect_fields:"",message_field:"",page_field:""};!function(){e.add_btn=b(d.getElementById("addip")),e.new_ip=d.getElementById("newip"),e.new_ip_comment=d.getElementById("newipcomment"),e.ip_list_wrap=d.getElementById("ip_list"),e.empty_ip=b(d.getElementById("ip_list_empty")),e.restrict_radio=d.getElementById("blog-restricted"),e.table=b(d.getElementById("rsa-send-to-login")).closest("table"),e.redirect_choice=d.getElementById("rsa-redirect-visitor"),e.message_choice=d.getElementById("rsa-display-message"),e.page_choice=d.getElementById("rsa-unblocked-page"),e.redirect_fields=b(d.querySelectorAll(".rsa_redirect_field")).closest("tr"),e.message_field=b(d.getElementById("rsa_message")).closest("tr"),e.page_field=b(d.getElementById("rsa_page")).closest("tr"),e.restrict_radio&&!e.restrict_radio.checked&&e.table.hide(),e.redirect_choice&&!e.redirect_choice.checked&&e.redirect_fields.hide(),e.message_choice&&!e.message_choice.checked&&e.message_field.hide(),e.page_choice&&!e.page_choice.checked&&e.page_field.hide(),b(d.querySelectorAll("#rsa_handle_fields input")).on("change",function(){e.redirect_choice.checked?e.redirect_fields.show():e.redirect_fields.hide(),e.message_choice.checked?e.message_field.show():e.message_field.hide(),e.page_choice.checked?e.page_field.show():e.page_field.hide()}),b(d.querySelectorAll(".option-site-visibility input")).on("change",function(){e.restrict_radio.checked?e.table.show():e.table.hide()}),e.add_btn.on("click",function(){c(e.new_ip.value,e.new_ip_comment.value)});var a=d.getElementById("rsa_myip");null!==a&&b(a).on("click",function(){b(e.new_ip).val(b(this).data("myip"))}),b(e.ip_list_wrap).on("click",".remove_btn",function(){b(this.parentNode).slideUp(250,function(){b(this).remove()})})}()}(window,jQuery);
1
+ !function(e,c){"use strict";var r=e.document,n={add_btn:"",new_ip:"",ip_list_wrap:"",empty_ip:"",restrict_radio:"",table:"",redirect_choice:"",message_choice:"",page_choice:"",redirect_fields:"",message_field:"",page_field:""};!function(){n.add_btn=c(r.getElementById("addip")),n.new_ip=r.getElementById("newip"),n.new_ip_comment=r.getElementById("newipcomment"),n.ip_list_wrap=r.getElementById("ip_list"),n.empty_ip=c(r.getElementById("ip_list_empty")),n.restrict_radio=r.getElementById("blog-restricted"),n.table=c(r.getElementById("rsa-send-to-login")).closest("table"),n.redirect_choice=r.getElementById("rsa-redirect-visitor"),n.message_choice=r.getElementById("rsa-display-message"),n.page_choice=r.getElementById("rsa-unblocked-page"),n.redirect_fields=c(r.querySelectorAll(".rsa_redirect_field")).closest("tr"),n.message_field=c(r.getElementById("rsa_message")).closest("tr"),n.page_field=c(r.getElementById("rsa_page")).closest("tr"),n.restrict_radio&&!n.restrict_radio.checked&&n.table.hide(),n.redirect_choice&&!n.redirect_choice.checked&&n.redirect_fields.hide(),n.message_choice&&!n.message_choice.checked&&n.message_field.hide(),n.page_choice&&!n.page_choice.checked&&n.page_field.hide(),c(r.querySelectorAll("#rsa_handle_fields input")).on("change",function(){n.redirect_choice.checked?n.redirect_fields.show():n.redirect_fields.hide(),n.message_choice.checked?n.message_field.show():n.message_field.hide(),n.page_choice.checked?n.page_field.show():n.page_field.hide()}),c(r.querySelectorAll(".option-site-visibility input")).on("change",function(){n.restrict_radio.checked?n.table.show():n.table.hide()}),n.add_btn.on("click",function(){!function(t,d){if(""==c.trim(t))return;n.add_btn.attr("disabled","disabled");var e=c(r.querySelectorAll("#ip_list input")),i=0;for(e.length;i<e.length;i++)if(e[i].value==t)return c(e[i]).parent().effect("shake",600),n.add_btn.removeAttr("disabled");jQuery.post(ajaxurl,{action:"rsa_ip_check",ip_address:t,ip_address_comment:d,nonce:rsaAdmin.nonce},function(e){if(e)return c(n.new_ip.parentNode).effect("shake",600),n.add_btn.removeAttr("disabled"),!1;var i=n.empty_ip.clone().appendTo(n.ip_list_wrap);return i.children("input.ip").val(t),i.children("input.comment").val(d),i.removeAttr("id").slideDown(250),t==n.new_ip.value&&(c(n.new_ip).val(""),c(n.new_ip_comment).val("")),n.add_btn.removeAttr("disabled"),!0})}(n.new_ip.value,n.new_ip_comment.value)});var e=r.getElementById("rsa_myip");null!==e&&c(e).on("click",function(){c(n.new_ip).val(c(this).data("myip"))}),c(n.ip_list_wrap).on("click",".remove_btn",function(){c(this.parentNode).slideUp(250,function(){c(this).remove()})})}()}(window,jQuery);
assets/js/src/admin.js CHANGED
@@ -5,7 +5,7 @@
5
  * Copyright (c) 2013 10up, jakemgold
6
  * Licensed under the GPLv2+ license.
7
  */
8
- ( function ( window, $ ) {
9
 
10
  'use strict';
11
 
@@ -26,3 +26,108 @@
26
  } );
27
  } );
28
  } )( window, jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  * Copyright (c) 2013 10up, jakemgold
6
  * Licensed under the GPLv2+ license.
7
  */
8
+ ( function( window, $ ) {
9
 
10
  'use strict';
11
 
26
  } );
27
  } );
28
  } )( window, jQuery );
29
+
30
+ ( function( window, $ ) {
31
+ 'use strict';
32
+
33
+ var RSADisablePlugin = {
34
+
35
+ els: {
36
+ dialog: document.getElementById( 'rsa-disable-dialog' ),
37
+ userMessage: document.getElementById( 'rsa-user-message' )
38
+ },
39
+
40
+ variables: {
41
+ expectedAnswer: rsaAdmin.strings.message.toLowerCase(),
42
+ disablingURL: null
43
+ },
44
+
45
+ openDialog: function( event ) {
46
+ event.preventDefault();
47
+ $( this.els.dialog ).dialog( 'open' );
48
+ },
49
+
50
+ isExpectedAnswer: function() {
51
+ var userMessage = this.els.userMessage.value.toLowerCase();
52
+
53
+ if ( userMessage === this.variables.expectedAnswer ) {
54
+ return true;
55
+ }
56
+
57
+ return false;
58
+ },
59
+ dialogSettings: function() {
60
+ var self = this;
61
+
62
+ self.close = function() {
63
+ $( self.els.dialog ).dialog( 'close' );
64
+ self.els.userMessage.style.border = '1px solid #ddd';
65
+ self.els.userMessage.value = '';
66
+ }
67
+
68
+ $( this.els.dialog ).dialog( {
69
+ dialogClass: 'wp-dialog',
70
+ autoOpen: false,
71
+ draggable: false,
72
+ width: 'auto',
73
+ modal: true,
74
+ resizable: false,
75
+ buttons: [
76
+ {
77
+ text: rsaAdmin.strings.confirm,
78
+ click: function() {
79
+ if ( self.isExpectedAnswer() ) {
80
+ window.location.href = self.variables.disablingURL;
81
+ } else {
82
+ self.els.userMessage.style.border = '1px solid red';
83
+ }
84
+ }
85
+ },
86
+ {
87
+ text: rsaAdmin.strings.cancel,
88
+ click: function() {
89
+ self.close();
90
+ },
91
+ 'class': 'button-primary'
92
+ }
93
+ ],
94
+ open: function() {
95
+ $( '.ui-widget-overlay' ).bind( 'click', function() {
96
+ self.close();
97
+ });
98
+ },
99
+ create: function() {
100
+ $( '.ui-dialog-titlebar-close' ).addClass( 'ui-button' );
101
+ $( this ).siblings( '.ui-dialog-titlebar' ).hide();
102
+ }
103
+ } );
104
+
105
+ this.els.buttons = $( this.els.dialog ).dialog( 'option', 'buttons' );
106
+ },
107
+
108
+ maybeSubmit: function( event ) {
109
+ switch ( event.key ) {
110
+ case 'Enter':
111
+ this.els.buttons[0].click();
112
+ break;
113
+ }
114
+ },
115
+
116
+ bindEvents: function() {
117
+ $( '[data-slug="restricted-site-access"]' ).on( 'click', '.deactivate a', this.openDialog.bind( this ) );
118
+ this.els.userMessage.addEventListener( 'keyup', this.maybeSubmit.bind( this ) );
119
+ },
120
+
121
+ init: function() {
122
+ if ( ! rsaAdmin.isNetworkWidePluginsPage ) {
123
+ return;
124
+ }
125
+
126
+ this.variables.disablingURL = document.getElementById( 'the-list' ).querySelector( '[data-slug="restricted-site-access"] .deactivate a' ).href;
127
+ this.bindEvents();
128
+ this.dialogSettings();
129
+ }
130
+ };
131
+
132
+ RSADisablePlugin.init();
133
+ }( window, jQuery ) );
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Restricted Site Access ===
2
  Contributors: jakemgold, rcbth, 10up, thinkoomph, tlovett1
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: 4.6
6
- Tested up to: 5.2
7
- Stable tag: 7.1.0
8
 
9
  Limit access to visitors who are logged in or allowed by IP addresses. Includes many options for handling blocked visitors.
10
 
@@ -108,20 +108,21 @@ define( 'RSA_IP_WHITELIST', '192.0.0.1|192.0.0.10' );
108
 
109
  == Changelog ==
110
 
 
 
 
 
 
 
111
  = 7.1.0 =
112
- **Added**
113
- * IP whitelist: Add a Comment field next to each IP address to help identify IP addresses added to the whitelist.
114
- * Add constants to force enable/disable restrictions. Set `RSA_FORCE_RESTRICTION` to `true` to force restriction or `RSA_FORBID_RESTRICTION` to disable restriction. `RSA_FORCE_RESTRICTION` will override `RSA_FORBID_RESTRICTION` if both are set.
115
-
116
- **Fixed**
117
- * Disable individual site settings when network enforced mode is on to avoid confusion about why your settings are not being respected.
118
- * Correctly load admin JS.
119
- * Improve coding standards across plugin and introduce continuous integration linting against the WordPress coding standards. Update code to VIP Go coding standards.
120
-
121
- **Developers**
122
- * Add unit tests accross plugin. Note that when the `WP_TESTS_DOMAIN` constant is set, plugin redirects are disabled. Only set this constant when running the tests.
123
- * Deploy plugin from GitHub to WordPress.org using GitHub Actions.
124
- * Add various GitHub community files.
125
 
126
  = 7.0.1 =
127
  * Bug fix: Avoid redirect loop when the unrestricted page is set to be the static front page.
1
  === Restricted Site Access ===
2
  Contributors: jakemgold, rcbth, 10up, thinkoomph, tlovett1
3
+ Donate link: https://10up.com/plugins/restricted-site-access-wordpress/
4
  Tags: privacy, restricted, restrict, privacy, limited, permissions, security, block
5
  Requires at least: 4.6
6
+ Tested up to: 5.3
7
+ Stable tag: 7.2.0
8
 
9
  Limit access to visitors who are logged in or allowed by IP addresses. Includes many options for handling blocked visitors.
10
 
108
 
109
  == Changelog ==
110
 
111
+ = 7.2.0 =
112
+ * **Added:** Warn and confirm before network disabling the plugin (props [@pereirinha](profiles.wordpress.org/pereirinha), [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein/))
113
+ * **Fixed:** Ensure comments associated with IPs stay associated correctly (props [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein/), [@ivankk](https://profiles.wordpress.org/ivankk/), [@helen](https://profiles.wordpress.org/helen/))
114
+ * **Fixed:** Don't show escaped HTML in page caching notice (props [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein/), [@aaemnnosttv](https://profiles.wordpress.org/aaemnnosttv/))
115
+ * **Fixed:** Multisite: Avoid a redirect loop when logging in as user with no role (props [@phyrax](https://profiles.wordpress.org/phyrax/), [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein/), [@roytanck](https://profiles.wordpress.org/roytanck/), [@helen](https://profiles.wordpress.org/helen/), [@rmccue](https://profiles.wordpress.org/rmccue/))
116
+
117
  = 7.1.0 =
118
+ * Added: IP whitelist: Add a Comment field next to each IP address to help identify IP addresses added to the whitelist.
119
+ * Added: Add constants to force enable/disable restrictions. Set `RSA_FORCE_RESTRICTION` to `true` to force restriction or `RSA_FORBID_RESTRICTION` to disable restriction. `RSA_FORCE_RESTRICTION` will override `RSA_FORBID_RESTRICTION` if both are set.
120
+ * Fixed: Disable individual site settings when network enforced mode is on to avoid confusion about why your settings are not being respected.
121
+ * Fixed: Correctly load admin JS.
122
+ * Fixed: Improve coding standards across plugin and introduce continuous integration linting against the WordPress coding standards. Update code to VIP Go coding standards.
123
+ * Developers: Add unit tests accross plugin. Note that when the `WP_TESTS_DOMAIN` constant is set, plugin redirects are disabled. Only set this constant when running the tests.
124
+ * Developers: Deploy plugin from GitHub to WordPress.org using GitHub Actions.
125
+ * Developers: Add various GitHub community files.
 
 
 
 
 
126
 
127
  = 7.0.1 =
128
  * Bug fix: Avoid redirect loop when the unrestricted page is set to be the static front page.
restricted_site_access.php CHANGED
@@ -1,16 +1,16 @@
1
  <?php // phpcs:disable WordPress.Files.FileName
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: 7.1.0
7
  * Author: Jake Goldman, 10up, Oomph
8
- * Author URI: http://10up.com
9
  * License: GPLv2 or later
10
  * Text Domain: restricted-site-access
11
  */
12
 
13
- define( 'RSA_VERSION', '7.1.0' );
14
 
15
  /**
16
  * Class responsible for all plugin funcitonality.
@@ -88,6 +88,8 @@ class Restricted_Site_Access {
88
  add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_admin_script' ) );
89
  add_action( 'wp_ajax_rsa_notice_dismiss', array( __CLASS__, 'ajax_notice_dismiss' ) );
90
 
 
 
91
  add_filter( 'pre_option_blog_public', array( __CLASS__, 'pre_option_blog_public' ), 10, 1 );
92
  add_filter( 'pre_site_option_blog_public', array( __CLASS__, 'pre_option_blog_public' ), 10, 1 );
93
  }
@@ -412,7 +414,7 @@ class Restricted_Site_Access {
412
  }
413
  // Fall thru to case 3 if case 2 not handled.
414
  case 3:
415
- $message = esc_html( self::$rsa_options['message'] );
416
  $message .= "\n<!-- protected by Restricted Site Access http://10up.com/plugins/restricted-site-access-wordpress/ -->";
417
  $message = apply_filters( 'restricted_site_access_message', $message, $wp );
418
 
@@ -431,6 +433,7 @@ class Restricted_Site_Access {
431
  }
432
  // No break, fall thru to default.
433
  default:
 
434
  self::$rsa_options['head_code'] = 302;
435
  $current_path = empty( $_SERVER['REQUEST_URI'] ) ? home_url() : sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) );
436
  self::$rsa_options['redirect_url'] = wp_login_url( $current_path );
@@ -445,6 +448,54 @@ class Restricted_Site_Access {
445
  );
446
  }
447
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
448
  /**
449
  * Admin only hooks
450
  */
@@ -618,10 +669,10 @@ class Restricted_Site_Access {
618
  $value = self::sanitize_options( wp_unslash( $_POST[ $option_name ] ) ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.VIP.ValidatedSanitizedInput.InputNotSanitized
619
  break;
620
  case 'blog_public':
621
- $value = absint( $_POST[ $option_name ] );
622
  break;
623
  default:
624
- $value = sanitize_key( $_POST[ $option_name ] );
625
  break;
626
  }
627
 
@@ -677,7 +728,7 @@ class Restricted_Site_Access {
677
  * Enqueue wp-admin scripts.
678
  */
679
  public static function enqueue_admin_script() {
680
- $js_path = plugin_dir_url( __FILE__ ) . 'assets/js/admin.min.js';
681
 
682
  $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
683
  $folder = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'src/' : '';
@@ -685,7 +736,7 @@ class Restricted_Site_Access {
685
  wp_enqueue_script(
686
  'rsa-admin',
687
  plugin_dir_url( __FILE__ ) . 'assets/js/' . $folder . 'admin' . $min . '.js',
688
- array( 'jquery' ),
689
  RSA_VERSION,
690
  true
691
  );
@@ -694,9 +745,22 @@ class Restricted_Site_Access {
694
  'rsa-admin',
695
  'rsaAdmin',
696
  array(
697
- 'nonce' => wp_create_nonce( 'rsa_admin_nonce' ),
 
 
 
 
 
 
698
  )
699
  );
 
 
 
 
 
 
 
700
  }
701
 
702
  /**
@@ -780,7 +844,17 @@ class Restricted_Site_Access {
780
  ?>
781
  <div data-rsa-notice="page-cache" class="notice notice-error is-dismissible">
782
  <p>
783
- <strong><?php esc_html_e( 'Page caching appears to be enabled. Restricted Site Access may not work as expected. <a href="https://wordpress.org/plugins/restricted-site-access/#faq">Learn more</a>.', 'restricted-site-access' ); ?></strong>
 
 
 
 
 
 
 
 
 
 
784
  </p>
785
  </div>
786
  <?php
@@ -931,31 +1005,25 @@ class Restricted_Site_Access {
931
  $new_input['approach'] = self::$fields['approach']['default'];
932
  }
933
 
934
- global $allowedtags;
935
- $new_input['message'] = wp_kses( $input['message'], $allowedtags );
936
-
937
  $new_input['redirect_path'] = empty( $input['redirect_path'] ) ? 0 : 1;
938
  $new_input['head_code'] = in_array( (int) $input['head_code'], array( 301, 302, 307 ), true ) ? (int) $input['head_code'] : self::$fields['head_code']['default'];
939
  $new_input['redirect_url'] = empty( $input['redirect_url'] ) ? '' : esc_url_raw( $input['redirect_url'], array( 'http', 'https' ) );
940
  $new_input['page'] = empty( $input['page'] ) ? 0 : (int) $input['page'];
941
 
942
- $new_input['allowed'] = array();
943
  if ( ! empty( $input['allowed'] ) && is_array( $input['allowed'] ) ) {
944
- foreach ( $input['allowed'] as $ip_address ) {
945
  if ( self::is_ip( $ip_address ) ) {
946
- $new_input['allowed'][] = $ip_address;
947
- }
948
- }
949
- }
950
- $new_input['comment'] = array();
951
- if ( ! empty( $input['comment'] ) && is_array( $input['comment'] ) ) {
952
- foreach ( $input['comment'] as $comment ) {
953
- if ( is_scalar( $comment ) ) {
954
- $new_input['comment'][] = sanitize_text_field( $comment );
955
  }
956
  }
957
  }
958
 
 
 
 
959
  return $new_input;
960
  }
961
 
@@ -999,9 +1067,17 @@ class Restricted_Site_Access {
999
  <?php
1000
  $ips = (array) self::$rsa_options['allowed'];
1001
  $comments = isset( self::$rsa_options['comment'] ) ? (array) self::$rsa_options['comment'] : array();
 
 
 
 
 
 
 
 
1002
  foreach ( $ips as $key => $ip ) {
1003
  if ( ! empty( $ip ) ) {
1004
- echo '<div><input type="text" name="rsa_options[allowed][]" value="' . esc_attr( $ip ) . '" class="ip code" readonly="true" size="20" /> <input type="text" name="rsa_options[comment][]" value="' . ( isset( $comments[ $key + 1 ] ) ? esc_attr( wp_unslash( $comments[ $key + 1 ] ) ) : '' ) . '" size="20" /> <a href="#remove" class="remove_btn">' . esc_html_x( 'Remove', 'remove IP address action', 'restricted-site-access' ) . '</a></div>';
1005
  }
1006
  }
1007
  ?>
@@ -1045,6 +1121,10 @@ class Restricted_Site_Access {
1045
  self::$rsa_options['message'] = esc_html__( 'Access to this site is restricted.', 'restricted-site-access' );
1046
  }
1047
 
 
 
 
 
1048
  wp_editor(
1049
  self::$rsa_options['message'],
1050
  'rsa_message',
@@ -1053,6 +1133,12 @@ class Restricted_Site_Access {
1053
  'textarea_name' => 'rsa_options[message]',
1054
  'textarea_rows' => 4,
1055
  'tinymce' => false,
 
 
 
 
 
 
1056
  )
1057
  );
1058
  }
@@ -1312,6 +1398,43 @@ class Restricted_Site_Access {
1312
 
1313
  }
1314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1315
  /**
1316
  * Check if a given ip is in a network.
1317
  * Source: https://gist.github.com/tott/7684443
1
  <?php // phpcs:disable WordPress.Files.FileName
2
  /**
3
  * Plugin Name: Restricted Site Access
4
+ * Plugin URI: https://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: 7.2.0
7
  * Author: Jake Goldman, 10up, Oomph
8
+ * Author URI: https://10up.com
9
  * License: GPLv2 or later
10
  * Text Domain: restricted-site-access
11
  */
12
 
13
+ define( 'RSA_VERSION', '7.2.0' );
14
 
15
  /**
16
  * Class responsible for all plugin funcitonality.
88
  add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_admin_script' ) );
89
  add_action( 'wp_ajax_rsa_notice_dismiss', array( __CLASS__, 'ajax_notice_dismiss' ) );
90
 
91
+ add_action( 'admin_footer', array( __CLASS__, 'admin_footer' ) );
92
+
93
  add_filter( 'pre_option_blog_public', array( __CLASS__, 'pre_option_blog_public' ), 10, 1 );
94
  add_filter( 'pre_site_option_blog_public', array( __CLASS__, 'pre_option_blog_public' ), 10, 1 );
95
  }
414
  }
415
  // Fall thru to case 3 if case 2 not handled.
416
  case 3:
417
+ $message = self::$rsa_options['message'];
418
  $message .= "\n<!-- protected by Restricted Site Access http://10up.com/plugins/restricted-site-access-wordpress/ -->";
419
  $message = apply_filters( 'restricted_site_access_message', $message, $wp );
420
 
433
  }
434
  // No break, fall thru to default.
435
  default:
436
+ self::validate_blog_access();
437
  self::$rsa_options['head_code'] = 302;
438
  $current_path = empty( $_SERVER['REQUEST_URI'] ) ? home_url() : sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) );
439
  self::$rsa_options['redirect_url'] = wp_login_url( $current_path );
448
  );
449
  }
450
 
451
+ /**
452
+ * Ensure the user has access to the blog attempting to be accessed.
453
+ *
454
+ * This method borrows from core's _access_denied_splash() for multi-site installs.
455
+ */
456
+ public static function validate_blog_access() {
457
+ if ( ! is_multisite() || ! is_user_logged_in() ) {
458
+ return;
459
+ }
460
+
461
+ if ( is_user_member_of_blog() || is_network_admin() ) {
462
+ return;
463
+ }
464
+
465
+ // We're logged in but not a member of this blog, let the user know.
466
+ $blogs = get_blogs_of_user( get_current_user_id() );
467
+
468
+ if ( wp_list_filter( $blogs, array( 'userblog_id' => get_current_blog_id() ) ) ) {
469
+ return;
470
+ }
471
+
472
+ $blog_name = get_bloginfo( 'name' );
473
+
474
+ if ( empty( $blogs ) ) {
475
+ // Translators: %1$s: The site name.
476
+ wp_die( sprintf( esc_html__( 'You attempted to access the "%1$s" site, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.', 'restricted-site-access' ), esc_html( $blog_name ) ), 403 );
477
+ }
478
+
479
+ // Translators: %1$s: The site name.
480
+ $output = '<p>' . sprintf( esc_html__( 'You attempted to access the "%1$s", but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.', 'restricted-site-access' ), esc_html( $blog_name ) ) . '</p>';
481
+ $output .= '<p>' . esc_html__( 'If you reached this screen by accident and meant to visit one of your own sites, here are some shortcuts to help you find your way.', 'restricted-site-access' ) . '</p>';
482
+
483
+ $output .= '<h3>' . esc_html__( 'Your Sites', 'restricted-site-access' ) . '</h3>';
484
+ $output .= '<table>';
485
+
486
+ foreach ( $blogs as $blog ) {
487
+ $output .= '<tr>';
488
+ $output .= '<td>' . esc_html( $blog->blogname ) . '</td>';
489
+ $output .= '<td><a href="' . esc_url( get_admin_url( $blog->userblog_id ) ) . '">' . esc_html__( 'Visit Dashboard', 'restricted-site-access' ) . '</a> | ' .
490
+ '<a href="' . esc_url( $blog->siteurl ) . '">' . esc_html__( 'View Site', 'restricted-site-access' ) . '</a></td>';
491
+ $output .= '</tr>';
492
+ }
493
+
494
+ $output .= '</table>';
495
+
496
+ wp_die( wp_kses_post( $output ), 403 );
497
+ }
498
+
499
  /**
500
  * Admin only hooks
501
  */
669
  $value = self::sanitize_options( wp_unslash( $_POST[ $option_name ] ) ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.VIP.ValidatedSanitizedInput.InputNotSanitized
670
  break;
671
  case 'blog_public':
672
+ $value = absint( $_POST[ $option_name ] ); // phpcs:ignore WordPress.Security.NonceVerification
673
  break;
674
  default:
675
+ $value = sanitize_key( $_POST[ $option_name ] ); // phpcs:ignore WordPress.Security.NonceVerification
676
  break;
677
  }
678
 
728
  * Enqueue wp-admin scripts.
729
  */
730
  public static function enqueue_admin_script() {
731
+ $current_screen = get_current_screen();
732
 
733
  $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
734
  $folder = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'src/' : '';
736
  wp_enqueue_script(
737
  'rsa-admin',
738
  plugin_dir_url( __FILE__ ) . 'assets/js/' . $folder . 'admin' . $min . '.js',
739
+ array( 'jquery', 'jquery-ui-dialog' ),
740
  RSA_VERSION,
741
  true
742
  );
745
  'rsa-admin',
746
  'rsaAdmin',
747
  array(
748
+ 'nonce' => wp_create_nonce( 'rsa_admin_nonce' ),
749
+ 'isNetworkWidePluginsPage' => $current_screen && 'plugins-network' === $current_screen->id,
750
+ 'strings' => array(
751
+ 'confirm' => esc_html__( 'Network Disable Plugin', 'restricted-site-access' ),
752
+ 'cancel' => esc_html__( 'Cancel', 'restricted-site-access' ),
753
+ 'message' => esc_html__( 'I understand', 'restricted-site-access' ),
754
+ ),
755
  )
756
  );
757
+ wp_enqueue_style( 'wp-jquery-ui-dialog' );
758
+ wp_enqueue_style(
759
+ 'rsa-admin',
760
+ plugin_dir_url( __FILE__ ) . 'assets/css/admin.css',
761
+ array(),
762
+ RSA_VERSION
763
+ );
764
  }
765
 
766
  /**
844
  ?>
845
  <div data-rsa-notice="page-cache" class="notice notice-error is-dismissible">
846
  <p>
847
+ <strong>
848
+ <?php
849
+ echo wp_kses_post(
850
+ sprintf(
851
+ /* translators: %s: https://wordpress.org/plugins/restricted-site-access/#faq */
852
+ __( 'Page caching appears to be enabled. Restricted Site Access may not work as expected. <a href="%s">Learn more</a>.', 'restricted-site-access' ),
853
+ __( 'https://wordpress.org/plugins/restricted-site-access/#faq', 'restricted-site-access' )
854
+ )
855
+ );
856
+ ?>
857
+ </strong>
858
  </p>
859
  </div>
860
  <?php
1005
  $new_input['approach'] = self::$fields['approach']['default'];
1006
  }
1007
 
1008
+ $new_input['message'] = wp_kses_post( $input['message'] );
 
 
1009
  $new_input['redirect_path'] = empty( $input['redirect_path'] ) ? 0 : 1;
1010
  $new_input['head_code'] = in_array( (int) $input['head_code'], array( 301, 302, 307 ), true ) ? (int) $input['head_code'] : self::$fields['head_code']['default'];
1011
  $new_input['redirect_url'] = empty( $input['redirect_url'] ) ? '' : esc_url_raw( $input['redirect_url'], array( 'http', 'https' ) );
1012
  $new_input['page'] = empty( $input['page'] ) ? 0 : (int) $input['page'];
1013
 
1014
+ $ips_comments = array();
1015
  if ( ! empty( $input['allowed'] ) && is_array( $input['allowed'] ) ) {
1016
+ foreach ( $input['allowed'] as $count => $ip_address ) {
1017
  if ( self::is_ip( $ip_address ) ) {
1018
+ // Ensure comments are properly matched up to their IPs.
1019
+ $ips_comments[ $ip_address ] = isset( $input['comment'][ $count ] ) ? sanitize_text_field( $input['comment'][ $count ] ) : '';
 
 
 
 
 
 
 
1020
  }
1021
  }
1022
  }
1023
 
1024
+ $new_input['allowed'] = array_keys( $ips_comments );
1025
+ $new_input['comment'] = array_values( $ips_comments );
1026
+
1027
  return $new_input;
1028
  }
1029
 
1067
  <?php
1068
  $ips = (array) self::$rsa_options['allowed'];
1069
  $comments = isset( self::$rsa_options['comment'] ) ? (array) self::$rsa_options['comment'] : array();
1070
+
1071
+ // Prior to version 7.2.0, the data stored for comments included an extra blank entry, so the comments array
1072
+ // always contained one extra (empty) entry. This was fixed and the following code handles loading data from
1073
+ // previous versions - if the ip and comment counts don't match, we remove the first comment.
1074
+ if ( ( 1 + count( $ips ) ) === ( count( $comments ) ) ) {
1075
+ array_shift( $comments );
1076
+ }
1077
+
1078
  foreach ( $ips as $key => $ip ) {
1079
  if ( ! empty( $ip ) ) {
1080
+ echo '<div><input type="text" name="rsa_options[allowed][]" value="' . esc_attr( $ip ) . '" class="ip code" readonly="true" size="20" /> <input type="text" name="rsa_options[comment][]" value="' . ( isset( $comments[ $key ] ) ? esc_attr( wp_unslash( $comments[ $key ] ) ) : '' ) . '" size="20" /> <a href="#remove" class="remove_btn">' . esc_html_x( 'Remove', 'remove IP address action', 'restricted-site-access' ) . '</a></div>';
1081
  }
1082
  }
1083
  ?>
1121
  self::$rsa_options['message'] = esc_html__( 'Access to this site is restricted.', 'restricted-site-access' );
1122
  }
1123
 
1124
+ /*
1125
+ * Removed the 'more' button from quicktags in 7.2.0 and added a filter:
1126
+ * 'restricted_site_access_message_editor_quicktags'
1127
+ */
1128
  wp_editor(
1129
  self::$rsa_options['message'],
1130
  'rsa_message',
1133
  'textarea_name' => 'rsa_options[message]',
1134
  'textarea_rows' => 4,
1135
  'tinymce' => false,
1136
+ 'quicktags' => apply_filters(
1137
+ 'restricted_site_access_message_editor_quicktags',
1138
+ array(
1139
+ 'buttons' => 'strong,em,link,block,del,ins,img,ol,ul,li,code,close', // this is default list minus the 'more' tag button.
1140
+ )
1141
+ ),
1142
  )
1143
  );
1144
  }
1398
 
1399
  }
1400
 
1401
+ /**
1402
+ * Dialog markup to warn network-wide RSA disable
1403
+ *
1404
+ * @return void
1405
+ */
1406
+ public static function admin_footer() {
1407
+ $current_screen = get_current_screen();
1408
+
1409
+ if ( 'plugins-network' !== $current_screen->id ) {
1410
+ return;
1411
+ }
1412
+ ?>
1413
+ <div id="rsa-disable-dialog" class="hidden">
1414
+ <h2><?php esc_html_e( 'Confirm Network Deactivation', 'restricted-site-access' ); ?></h2>
1415
+ <p><?php esc_html_e( 'You are about to disable Restricted Site Access across your entire network. This may unintentionally make other sites on the network public.', 'restricted-site-access' ); ?></p>
1416
+ <p>
1417
+ <?php
1418
+ echo wp_kses_post(
1419
+ sprintf(
1420
+ /* translators: %s: The words 'I understand'. */
1421
+ __( 'If you are absolutely sure you want to network deactivate Restricted Site Access, please type %s to proceed.', 'restricted-site-access' ),
1422
+ sprintf(
1423
+ /* translators: %s: The words 'I understand'. */
1424
+ '<code>%s</code>',
1425
+ esc_html__( 'I understand', 'restricted-site-access' )
1426
+ )
1427
+ )
1428
+ );
1429
+ ?>
1430
+ </p>
1431
+ <p class="rsa-user-message">
1432
+ <input type="text" id="rsa-user-message">
1433
+ </p>
1434
+ </div>
1435
+ <?php
1436
+ }
1437
+
1438
  /**
1439
  * Check if a given ip is in a network.
1440
  * Source: https://gist.github.com/tott/7684443