diff --git a/CHANGELOG.md b/CHANGELOG.md
index c91fb60..a362d4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,17 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+## [2.2] - 2018-05-25
+
+### Added
+- Admin bar icon to indicate wether password protection is enabled/disabled.
+- Option to show "Remember me" checkbox. Props [Christian Güdel](https://github.com/cguedel).
+- REST API access disabled if password not entered.
+- Admin option to allow REST API access.
+
+### Security
+- More robust checking of password hashes.
+
## [2.1] - 2017-07-27
### Added
@@ -175,7 +186,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- First Release. If you spot any bugs or issues please [log them here](https://github.com/benhuson/password-protected/issues).
-[Unreleased]: https://github.com/benhuson/password-protected/compare/2.1...HEAD
+[Unreleased]: https://github.com/benhuson/password-protected/compare/2.2...HEAD
+[2.2]: https://github.com/benhuson/password-protected/compare/2.1...2.2
[2.1]: https://github.com/benhuson/password-protected/compare/2.0.3...2.1
[2.0.3]: https://github.com/benhuson/password-protected/compare/2.0.2...2.0.3
[2.0.2]: https://github.com/benhuson/password-protected/compare/2.0.1...2.0.2
diff --git a/README.md b/README.md
index 887c2fb..c598a11 100644
--- a/README.md
+++ b/README.md
@@ -71,6 +71,9 @@ More instructions can be found at [wp-translations.org](http://wp-translations.o
Upgrade Notice
--------------
+### 2.2
+Added admin bar icon to indicate wether password protection is enabled/disabled. Options to enable REST API access and show "Remember me" checkbox.
+
### 2.1
Update caching notes for WP Engine and W3 Total Cache plugin.
diff --git a/admin/admin-bar.php b/admin/admin-bar.php
new file mode 100644
index 0000000..be33f38
--- /dev/null
+++ b/admin/admin-bar.php
@@ -0,0 +1,137 @@
+add_menu( array(
+ 'id' => 'password_protected',
+ 'title' => __( '', 'password-protected' ),
+ 'href' => self::get_toolbar_item_url(),
+ 'meta' => array(
+ 'title' => self::get_toolbar_item_title()
+ )
+ ) );
+
+ }
+
+ }
+
+ /**
+ * Get Toolbar Item URL
+ *
+ * @return string
+ */
+ private static function get_toolbar_item_url() {
+
+ if ( current_user_can( 'manage_options' ) ) {
+ return admin_url( 'options-general.php?page=password-protected' );
+ }
+
+ return '';
+
+ }
+
+ /**
+ * Get Toolbar Item Title
+ *
+ * @return string
+ */
+ private static function get_toolbar_item_title() {
+
+ if ( self::is_enabled() ) {
+ return __( 'Password Protection is enabled.', 'password-protected' );
+ }
+
+ return __( 'Password Protection is disabled.', 'password-protected' );
+
+ }
+
+ /**
+ * Styles
+ *
+ * @internal Private. Called via `wp_head` and `admin_head` actions.
+ */
+ public static function styles() {
+
+ if ( self::allow_current_user() ) {
+
+ if ( self::is_enabled() ) {
+ $icon = '\f160'; // Locked
+ $background = '#C00';
+ } else {
+ $icon = '\f528'; // Unlocked
+ $background = 'transparent';
+ }
+
+ ?>
+
+ ' . __( 'Password Protected does not always work well with sites that use caching.', 'password-protected' ) . '
- ' . __( 'If your site uses a caching plugin or yur web hosting uses server-side caching, you may need to configure your setup to disable caching for the Password Protected cookie:', 'password-protected' ) . '
';
+ ' . __( 'If your site uses a caching plugin or your web hosting uses server-side caching, you may need to configure your setup to disable caching for the Password Protected cookie:', 'password-protected' ) . '';
}
diff --git a/admin/admin.php b/admin/admin.php
index 5aba2e3..93033ed 100644
--- a/admin/admin.php
+++ b/admin/admin.php
@@ -130,12 +130,31 @@ public function password_protected_settings() {
'password_protected'
);
+ add_settings_field(
+ 'password_protected_remember_me',
+ __( 'Allow Remember me', 'password-protected' ),
+ array( $this, 'password_protected_remember_me_field' ),
+ $this->options_group,
+ 'password_protected'
+ );
+
+ add_settings_field(
+ 'password_protected_remember_me_lifetime',
+ __( 'Remember for this many days', 'password-protected' ),
+ array( $this, 'password_protected_remember_me_lifetime_field' ),
+ $this->options_group,
+ 'password_protected'
+ );
+
register_setting( $this->options_group, 'password_protected_status', 'intval' );
register_setting( $this->options_group, 'password_protected_feeds', 'intval' );
+ register_setting( $this->options_group, 'password_protected_rest', 'intval' );
register_setting( $this->options_group, 'password_protected_administrators', 'intval' );
register_setting( $this->options_group, 'password_protected_users', 'intval' );
register_setting( $this->options_group, 'password_protected_password', array( $this, 'sanitize_password_protected_password' ) );
register_setting( $this->options_group, 'password_protected_allowed_ip_addresses', array( $this, 'sanitize_ip_addresses' ) );
+ register_setting( $this->options_group, 'password_protected_remember_me', 'boolval' );
+ register_setting( $this->options_group, 'password_protected_remember_me_lifetime', 'intval' );
}
@@ -228,6 +247,7 @@ public function password_protected_permissions_field() {
echo '';
echo '';
echo '';
+ echo '';
}
@@ -251,6 +271,24 @@ public function password_protected_allowed_ip_addresses_field() {
}
+ /**
+ * Remember Me Field
+ */
+ public function password_protected_remember_me_field() {
+
+ echo '';
+
+ }
+
+ /**
+ * Remember Me lifetime field
+ */
+ public function password_protected_remember_me_lifetime_field() {
+
+ echo '';
+
+ }
+
/**
* Pre-update 'password_protected_password' Option
*
@@ -289,7 +327,7 @@ public function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $stat
if ( 'password-protected/password-protected.php' == $plugin_file ) {
$plugin_meta[] = sprintf( '%s', __( 'http://github.com/benhuson/password-protected', 'password-protected' ), __( 'GitHub', 'password-protected' ) );
- $plugin_meta[] = sprintf( '%s', __( 'https://www.transifex.com/projects/p/password-protected/resource/password-protected/', 'password-protected' ), __( 'Translate', 'password-protected' ) );
+ $plugin_meta[] = sprintf( '%s', __( 'https://translate.wordpress.org/projects/wp-plugins/password-protected', 'password-protected' ), __( 'Translate', 'password-protected' ) );
}
return $plugin_meta;
diff --git a/password-protected.php b/password-protected.php
index aef5719..f0e5e60 100644
--- a/password-protected.php
+++ b/password-protected.php
@@ -4,7 +4,7 @@
Plugin Name: Password Protected
Plugin URI: https://wordpress.org/plugins/password-protected/
Description: A very simple way to quickly password protect your WordPress site with a single password. Please note: This plugin does not restrict access to uploaded files and images and does not work with some caching setups.
-Version: 2.1
+Version: 2.2
Author: Ben Huson
Text Domain: password-protected
Author URI: http://github.com/benhuson/password-protected/
@@ -42,7 +42,7 @@
class Password_Protected {
- var $version = '2.1';
+ var $version = '2.2';
var $admin = null;
var $errors = null;
@@ -67,12 +67,15 @@ public function __construct() {
add_filter( 'pre_option_password_protected_status', array( $this, 'allow_feeds' ) );
add_filter( 'pre_option_password_protected_status', array( $this, 'allow_administrators' ) );
add_filter( 'pre_option_password_protected_status', array( $this, 'allow_users' ) );
+ add_filter( 'rest_authentication_errors', array( $this, 'only_allow_logged_in_rest_access' ) );
add_action( 'init', array( $this, 'compat' ) );
add_action( 'password_protected_login_messages', array( $this, 'login_messages' ) );
add_action( 'login_enqueue_scripts', array( $this, 'load_theme_stylesheet' ), 5 );
add_shortcode( 'password_protected_logout_link', array( $this, 'logout_link_shortcode' ) );
+ include_once( dirname( __FILE__ ) . '/admin/admin-bar.php' );
+
if ( is_admin() ) {
include_once( dirname( __FILE__ ) . '/admin/admin-caching.php' );
@@ -242,6 +245,17 @@ public function get_allowed_ip_addresses() {
}
+ /**
+ * Allow the remember me function
+ *
+ * @return. boolean
+ */
+ public function allow_remember_me() {
+
+ return (bool) get_option( 'password_protected_remember_me' );
+
+ }
+
/**
* Encrypt Password
*
@@ -288,7 +302,13 @@ public function maybe_process_login() {
// If correct password...
if ( ( hash_equals( $pwd, $this->encrypt_password( $password_protected_pwd ) ) && $pwd != '' ) || apply_filters( 'password_protected_process_login', false, $password_protected_pwd ) ) {
- $this->set_auth_cookie();
+ $remember = isset( $_REQUEST['password_protected_rememberme'] ) ? boolval( $_REQUEST['password_protected_rememberme'] ) : false;
+
+ if ( ! $this->allow_remember_me() ) {
+ $remember = false;
+ }
+
+ $this->set_auth_cookie( $remember );
$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
$redirect_to = apply_filters( 'password_protected_login_redirect', $redirect_to );
@@ -548,15 +568,19 @@ public function generate_auth_cookie( $expiration, $scheme = 'auth' ) {
public function parse_auth_cookie( $cookie = '', $scheme = '' ) {
if ( empty( $cookie ) ) {
+
$cookie_name = $this->cookie_name();
- if ( empty( $_COOKIE[$cookie_name] ) ) {
+ if ( empty( $_COOKIE[ $cookie_name ] ) ) {
return false;
}
- $cookie = $_COOKIE[$cookie_name];
+
+ $cookie = $_COOKIE[ $cookie_name ];
+
}
$cookie_elements = explode( '|', $cookie );
+
if ( count( $cookie_elements ) != 3 ) {
return false;
}
@@ -578,9 +602,11 @@ public function parse_auth_cookie( $cookie = '', $scheme = '' ) {
public function set_auth_cookie( $remember = false, $secure = '') {
if ( $remember ) {
- $expiration = $expire = current_time( 'timestamp' ) + apply_filters( 'password_protected_auth_cookie_expiration', 1209600, $remember );
+ $expiration_time = apply_filters( 'password_protected_auth_cookie_expiration', get_option( 'password_protected_remember_me_lifetime', 14 ) * DAY_IN_SECONDS, $remember );
+ $expiration = $expire = current_time( 'timestamp' ) + $expiration_time;
} else {
- $expiration = current_time( 'timestamp' ) + apply_filters( 'password_protected_auth_cookie_expiration', 172800, $remember );
+ $expiration_time + apply_filters( 'password_protected_auth_cookie_expiration', DAY_IN_SECONDS * 20, $remember );
+ $expiration = current_time( 'timestamp' ) + $expiration_time;
$expire = 0;
}
@@ -684,9 +710,9 @@ public function login_messages() {
$severity = $this->errors->get_error_data( $code );
foreach ( $this->errors->get_error_messages( $code ) as $error ) {
if ( 'message' == $severity ) {
- $messages .= ' ' . $error . "
\n";
+ $messages .= $error . '
';
} else {
- $errors .= ' ' . $error . "
\n";
+ $errors .= $error . '
';
}
}
}
@@ -764,4 +790,21 @@ static function is_plugin_supported() {
}
+ /**
+ * Check whether a given request has permissions
+ *
+ * @param WP_REST_Request $access Full details about the request.
+ * @return WP_Error|boolean
+ */
+ public function only_allow_logged_in_rest_access( $access ) {
+
+ // If user is not logged in
+ if ( ! $this->is_user_logged_in() && ! (bool) get_option( 'password_protected_rest' ) ) {die();
+ return new WP_Error( 'rest_cannot_access', __( 'Only authenticated users can access the REST API.', 'password-protected' ), array( 'status' => rest_authorization_required_code() ) );
+ }
+
+ return $access;
+
+ }
+
}
diff --git a/readme.txt b/readme.txt
index 67bb5c4..4d312ab 100644
--- a/readme.txt
+++ b/readme.txt
@@ -2,10 +2,10 @@
Contributors: husobj
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DXRJDNCMK9U3N
Tags: password, protect, password protect, login
-Requires at least: 3.5
-Tested up to: 4.8
+Requires at least: 3.9
+Tested up to: 4.9.6
Requires PHP: 5.6
-Stable tag: 2.1
+Stable tag: 2.2
License: GPLv2 or later
A very simple way to quickly password protect your WordPress site with a single password.
@@ -82,7 +82,12 @@ More instructions can be found at [wp-translations.org](http://wp-translations.o
== Changelog ==
-= Unreleased =
+= 2.2 =
+* Added admin bar icon to indicate wether password protection is enabled/disabled.
+* Option to show "Remember me" checkbox. Props [Christian Güdel](https://github.com/cguedel).
+* REST API access disabled if password not entered.
+* Admin option to allow REST API access.
+* More robust checking of password hashes.
= 2.1 =
* Update caching notes for WP Engine and W3 Total Cache plugin.
@@ -187,6 +192,9 @@ More instructions can be found at [wp-translations.org](http://wp-translations.o
== Upgrade Notice ==
+= 2.2 =
+Added admin bar icon to indicate wether password protection is enabled/disabled and disable REST API access (admin option to allow).
+
= 2.1 =
Update caching notes for WP Engine and W3 Total Cache plugin.
diff --git a/theme/password-protected-login.php b/theme/password-protected-login.php
index 5125859..491ddf4 100644
--- a/theme/password-protected-login.php
+++ b/theme/password-protected-login.php
@@ -107,9 +107,13 @@ function shake(id,a,d){c=a.shift();s(id,c);if(a.length>0){setTimeout(function(){
-
+
+ allow_remember_me() ) : ?>
+
+
+
+
+