errors = new WP_Error();
register_activation_hook( __FILE__, array( &$this, 'install' ) );
add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
add_filter( 'password_protected_is_active', array( $this, 'allow_ip_addresses' ) );
add_action( 'init', array( $this, 'disable_caching' ), 1 );
add_action( 'init', array( $this, 'maybe_process_logout' ), 1 );
add_action( 'init', array( $this, 'maybe_process_login' ), 1 );
add_action( 'wp', array( $this, 'disable_feeds' ) );
add_action( 'template_redirect', array( $this, 'maybe_show_login' ), -10 );
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_action('password_protected_above_password_field', array( $this, 'password_protected_above_password_field' ));
add_action('password_protected_below_password_field', array( $this, 'password_protected_below_password_field' ));
// Available from WordPress 4.3+
if ( function_exists( 'wp_site_icon' ) ) {
add_action( 'password_protected_login_head', 'wp_site_icon' );
}
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';
include_once dirname( __FILE__ ) . '/admin/admin.php';
$this->admin_caching = new Password_Protected_Admin_Caching( $this );
$this->admin = new Password_Protected_Admin();
}
include_once dirname( __FILE__ ) . '/admin/class-recaptcha.php';
new Password_Protected_reCAPTCHA();
include_once dirname( __FILE__ ) . '/includes/transient-functions.php';
include_once dirname( __FILE__ ) . '/includes/activity-report-email/class-password-protected-activity-report-settings.php';
}
/**
* I18n
*/
public function load_plugin_textdomain() {
load_plugin_textdomain( 'password-protected', false, basename( dirname( __FILE__ ) ) . '/languages' );
}
/**
* Disable Page Caching
*/
public function disable_caching() {
if ( $this->is_active() && ! defined( 'DONOTCACHEPAGE' ) ) {
define( 'DONOTCACHEPAGE', true );
}
}
/**
* Is Active?
*
* @return boolean Is password protection active?
*/
public function is_active() {
global $wp_query;
// Always allow access to robots.txt
if ( isset( $wp_query ) && is_robots() ) {
return false;
}
if ( (bool) get_option( 'password_protected_status' ) ) {
$is_active = true;
} else {
$is_active = false;
}
$is_active = apply_filters( 'password_protected_is_active', $is_active );
if ( isset( $_GET['password-protected'] ) ) {
$is_active = true;
}
return $is_active;
}
/**
* Disable Feeds
*
* @todo An option/filter to prevent disabling of feeds.
*/
public function disable_feeds() {
if ( $this->is_active() ) {
add_action( 'do_feed', array( $this, 'disable_feed' ), 1 );
add_action( 'do_feed_rdf', array( $this, 'disable_feed' ), 1 );
add_action( 'do_feed_rss', array( $this, 'disable_feed' ), 1 );
add_action( 'do_feed_rss2', array( $this, 'disable_feed' ), 1 );
add_action( 'do_feed_atom', array( $this, 'disable_feed' ), 1 );
}
}
/**
* Disable Feed
*
* @todo Make Translatable
*/
public function disable_feed() {
wp_die( sprintf( __( 'Feeds are not available for this site. Please visit the website.', 'password-protected' ), get_bloginfo( 'url' ) ) );
}
/**
* Allow Feeds
*
* @param boolean $bool Allow feeds.
* @return boolean True/false.
*/
public function allow_feeds( $bool ) {
if ( is_feed() && (bool) get_option( 'password_protected_feeds' ) ) {
return 0;
}
return $bool;
}
/**
* Allow Administrators
*
* @param boolean $bool Allow administrators.
* @return boolean True/false.
*/
public function allow_administrators( $bool ) {
if ( ! is_admin() && current_user_can( 'manage_options' ) && (bool) get_option( 'password_protected_administrators' ) ) {
return 0;
}
return $bool;
}
/**
* Allow Users
*
* @param boolean $bool Allow administrators.
* @return boolean True/false.
*/
public function allow_users( $bool ) {
if ( ! is_admin() && is_user_logged_in() && (bool) get_option( 'password_protected_users' ) ) {
return 0;
}
return $bool;
}
/**
* Allow IP Addresses
*
* If user has a valid email address, return false to disable password protection.
*
* @param boolean $bool Allow IP addresses.
* @return boolean True/false.
*/
public function allow_ip_addresses( $bool ) {
$ip_addresses = $this->get_allowed_ip_addresses();
if ( isset( $_SERVER['REMOTE_ADDR'] ) && in_array( $_SERVER['REMOTE_ADDR'], $ip_addresses ) ) {
$bool = false;
}
return $bool;
}
/**
* Get Allowed IP Addresses
*
* @return array IP addresses.
*/
public function get_allowed_ip_addresses() {
return explode( "\n", get_option( 'password_protected_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
*
* @param string $password Password.
* @return string Encrypted password.
*/
public function encrypt_password( $password ) {
return md5( $password );
}
/**
* Maybe Process Logout
*/
public function maybe_process_logout() {
if ( isset( $_REQUEST['password-protected'] ) && sanitize_text_field( $_REQUEST['password-protected'] ) == 'logout' ) {
$this->logout();
if ( isset( $_REQUEST['redirect_to'] ) ) {
$redirect_to = remove_query_arg( 'password-protected', esc_url_raw( $_REQUEST['redirect_to'], array( 'http', 'https' ) ) );
} else {
$redirect_to = home_url( '/' );
}
$this->safe_redirect( $redirect_to );
exit();
}
}
/**
* Maybe Process Login
*/
public function maybe_process_login() {
if ( $this->is_active() && isset( $_REQUEST['password_protected_pwd'] ) ) {
$password_protected_pwd = sanitize_text_field( $_REQUEST['password_protected_pwd'] );
$default_password = get_option( 'password_protected_password' );
$auth = false;
$p_id = 0;
if ( empty( $default_password ) ) {
$authentication = $this->password_protected_check_pro_password( $password_protected_pwd );
$auth = $authentication['auth'];
$p_id = $authentication['p_id'];
} else {
if ( ( hash_equals( $default_password, $this->encrypt_password( $password_protected_pwd ) ) && $default_password != '' ) || apply_filters( 'password_protected_process_login', false, $password_protected_pwd ) ) {
$auth = true;
}
if ( ! $auth ) {
$authentication = $this->password_protected_check_pro_password( $password_protected_pwd );
$auth = $authentication['auth'];
$p_id = $authentication['p_id'];
}
}
$this->errors = apply_filters( 'password_protected_verify_recaptcha', $this->errors );
if( count( @$this->errors->errors ) > 0 ) return;
$this->password_protected_process_login( $auth, $password_protected_pwd, $p_id );
}
}
public function password_protected_process_login( bool $auth, $requested_password, $password_id ) {
if( $auth )
$throttle = apply_filters( 'password_protected_check_for_throttling', true );
if( $auth && $throttle ) {
do_action( 'password_protected_success_login_attempt', 'global', $requested_password, $password_id );
$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'] ) ? esc_url($_REQUEST['redirect_to']) : '';
$redirect_to = apply_filters( 'password_protected_login_redirect', $redirect_to, $requested_password );
if ( ! empty( $redirect_to ) ) {
$this->safe_redirect( remove_query_arg( 'password-protected', $redirect_to ) );
exit;
} elseif ( isset( $_GET['password_protected_pwd'] ) ) {
$this->safe_redirect( remove_query_arg( 'password-protected' ) );
exit;
} else {
$this->safe_redirect( site_url() );
exit;
}
} else {
do_action( 'password_protected_failure_login_attempt', 'global', $requested_password, $password_id );
// ... otherwise incorrect password
$this->clear_auth_cookie();
$show_default_error = apply_filters( 'password_protected_throttling_error_messages', true );
if( $show_default_error )
$this->errors->add( 'incorrect_password', __( 'Incorrect Password', 'password-protected' ) );
}
}
/**
* password_protected_check_pro_password
*
* @param mixed $requested_password
* @return void
*/
public function password_protected_check_pro_password( $requested_password ) {
$pro_passwords = apply_filters( 'password_protected_passwords', array() );
$pro_passwords = array_filter( $pro_passwords );
$auth = false;
$p_id = 0;
if( is_array( $pro_passwords ) && count( $pro_passwords ) > 0 ) {
foreach( $pro_passwords as $i => $p ) {
if ( ( hash_equals( $p, $this->encrypt_password( $requested_password ) ) && $pro_passwords != '' ) || apply_filters( 'password_protected_process_login', false, $requested_password ) ) {
$auth = apply_filters( 'password_protected_login_password_matched', $p, $this->errors );
$p_id = $i;
break;
}
}
} else {
$auth = false;
}
return array(
'auth' => $auth,
'p_id' => $p_id,
);
}
/**
* Is User Logged In?
*
* @return boolean
*/
public function is_user_logged_in() {
return $this->is_active() && $this->validate_auth_cookie();
}
/**
* Maybe Show Login
*/
public function maybe_show_login() {
if ( class_exists( 'Login_designer' ) ) {
if ( is_customize_preview() ) {
return 1;
}
}
// Filter for adding exceptions.
$show_login = apply_filters( 'password_protected_show_login', $this->is_active() );
// Logged in
if ( $this->is_user_logged_in() ) {
$show_login = false;
}
if ( ! $show_login ) {
return 1;
}
// Show login form
if ( isset( $_REQUEST['password-protected'] ) && 'login' == sanitize_text_field( $_REQUEST['password-protected'] ) ) {
$default_theme_file = locate_template( array( 'password-protected-login.php' ) );
if ( empty( $default_theme_file ) ) {
$default_theme_file = dirname( __FILE__ ) . '/theme/password-protected-login.php';
}
$theme_file = apply_filters( 'password_protected_theme_file', $default_theme_file );
if ( ! file_exists( $theme_file ) ) {
$theme_file = $default_theme_file;
}
load_template( $theme_file );
exit();
} else {
global $wp;
$redirect_to = add_query_arg( 'password-protected', 'login', home_url( $wp->request . '?' . $_SERVER['QUERY_STRING'] ) );
// URL to redirect back to after login
$redirect_to_url = apply_filters( 'password_protected_login_redirect_url', ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
if ( ! empty( $redirect_to_url ) ) {
$redirect_to = add_query_arg( 'redirect_to', urlencode( $redirect_to_url ), $redirect_to );
}
nocache_headers();
wp_redirect( $redirect_to );
exit();
}
}
/**
* Get Site ID
*
* @return string Site ID.
*/
public function get_site_id() {
global $blog_id;
return 'bid_' . apply_filters( 'password_protected_blog_id', $blog_id );
}
/**
* Login URL
*
* @return string Login URL.
*/
public function login_url() {
global $wp;
return add_query_arg( 'password-protected', 'login', home_url( $wp->request . '?' . $_SERVER['QUERY_STRING'] ) );
}
/**
* Logout
*/
public function logout() {
$this->clear_auth_cookie();
do_action( 'password_protected_logout' );
}
/**
* Logout URL
*
* @param string $redirect_to Optional. Redirect URL.
* @return string Logout URL.
*/
public function logout_url( $redirect_to = '' ) {
$query = array(
'password-protected' => 'logout',
'redirect_to' => esc_url_raw( $redirect_to ),
);
if ( empty( $query['redirect_to'] ) ) {
unset( $query['redirect_to'] );
}
return add_query_arg( $query, home_url() );
}
/**
* Logout Link
*
* @param array $args Link args.
* @return string HTML link tag.
*/
public function logout_link( $args = null ) {
// Only show if user is logged in
if ( ! $this->is_user_logged_in() ) {
return '';
}
$args = wp_parse_args(
$args,
array(
'redirect_to' => '',
'text' => __( 'Logout', 'password-protected' ),
)
);
if ( empty( $args['text'] ) ) {
$args['text'] = __( 'Logout', 'password-protected' );
}
return sprintf( '%s', esc_url( $this->logout_url( $args['redirect_to'] ) ), esc_html( $args['text'] ) );
}
/**
* Logout Link Shortcode
*
* @param array $args Link args.
* @return string HTML link tag.
*/
public function logout_link_shortcode( $atts, $content = null ) {
$atts = shortcode_atts(
array(
'redirect_to' => '',
'text' => $content,
),
$atts,
'logout_link_shortcode'
);
return $this->logout_link( $atts );
}
/**
* Get Hashed Password
*
* @return string Hashed password.
*/
public function get_hashed_password() {
return md5( get_option( 'password_protected_password' ) . wp_salt() );
}
/**
* Validate Auth Cookie
*
* @param string $cookie Cookie string.
* @param string $scheme Cookie scheme.
* @return boolean Validation successful?
*/
public function validate_auth_cookie( $cookie = '', $scheme = '', $hashed_password = '' ) {
if ( ! $cookie_elements = $this->parse_auth_cookie( $cookie, $scheme ) ) {
do_action( 'password_protected_auth_cookie_malformed', $cookie, $scheme );
return false;
}
extract( $cookie_elements, EXTR_OVERWRITE );
$expired = $expiration;
// Allow a grace period for POST and AJAX requests
if ( defined( 'DOING_AJAX' ) || 'POST' == $_SERVER['REQUEST_METHOD'] ) {
$expired += 3600;
}
// Quick check to see if an honest cookie has expired
if ( $expired < current_time( 'timestamp' ) ) {
do_action( 'password_protected_auth_cookie_expired', $cookie_elements );
return false;
}
if ( empty( $hashed_password ) ) {
$hashed_password = $this->get_hashed_password();
}
$key = md5( $this->get_site_id() . $hashed_password . '|' . $expiration ); // need to modify
$hash = hash_hmac( 'md5', $this->get_site_id() . '|' . $expiration, $key );
if ( $hmac != $hash ) {
do_action( 'password_protected_auth_cookie_bad_hash', $cookie_elements );
return false;
}
if ( $expiration < current_time( 'timestamp' ) ) { // AJAX/POST grace period set above
$GLOBALS['login_grace_period'] = 1;
}
return true;
}
/**
* Generate Auth Cookie
*
* @param int $expiration Expiration time in seconds.
* @param string $scheme Cookie scheme.
* @return string Cookie.
*/
public function generate_auth_cookie( $expiration, $scheme = 'auth', $hashed_password = '' ) {
if ( empty( $hashed_password ) ) {
$hashed_password = $this->get_hashed_password();
}
$key = md5( $this->get_site_id() . $hashed_password . '|' . $expiration ); // need to modify
$hash = hash_hmac( 'md5', $this->get_site_id() . '|' . $expiration, $key );
$cookie = $this->get_site_id() . '|' . $expiration . '|' . $hash;
return $cookie;
}
/**
* Parse Auth Cookie
*
* @param string $cookie Cookie string.
* @param string $scheme Cookie scheme.
* @return string Cookie string.
*/
public function parse_auth_cookie( $cookie = '', $scheme = '' ) {
if ( empty( $cookie ) ) {
$cookie_name = $this->cookie_name();
$use_transient = get_option( 'password_protected_use_transient', '' );
if ( empty( $use_transient ) ) {
if ( empty( $_COOKIE[ $cookie_name ] ) ) {
return false;
}
$cookie = $_COOKIE[ $cookie_name ];
} else {
$cookie = pp_get_transient( $cookie_name );
}
}
$cookie_elements = explode( '|', $cookie );
if ( count( $cookie_elements ) != 3 ) {
return false;
}
list( $site_id, $expiration, $hmac ) = $cookie_elements;
return compact( 'site_id', 'expiration', 'hmac', 'scheme' );
}
/**
* Set Auth Cookie
*
* @todo
*
* @param boolean $remember Remember logged in.
* @param string $secure Secure cookie.
*/
public function set_auth_cookie( $remember = false, $secure = '' ) {
if ( $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_time = apply_filters( 'password_protected_auth_cookie_expiration', DAY_IN_SECONDS * 20, $remember );
$expiration = current_time( 'timestamp' ) + $expiration_time;
$expire = 0;
}
if ( '' === $secure ) {
$secure = is_ssl();
}
$secure_password_protected_cookie = apply_filters( 'password_protected_secure_password_protected_cookie', false, $secure );
$password_protected_cookie = $this->generate_auth_cookie( $expiration, 'password_protected' );
$use_transient = get_option( 'password_protected_use_transient', '' );
if ( empty( $use_transient ) ) {
setcookie( $this->cookie_name(), $password_protected_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_password_protected_cookie, true );
if ( COOKIEPATH != SITECOOKIEPATH ) {
setcookie( $this->cookie_name(), $password_protected_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_password_protected_cookie, true );
}
} else {
pp_set_transient( $this->cookie_name(), $password_protected_cookie, $expiration_time );
}
}
/**
* Clear Auth Cookie
*/
public function clear_auth_cookie() {
$use_transient = get_option( 'password_protected_use_transient', '' );
if ( empty( $use_transient ) ) {
setcookie( $this->cookie_name(), ' ', current_time( 'timestamp' ) - 31536000, COOKIEPATH, COOKIE_DOMAIN );
setcookie( $this->cookie_name(), ' ', current_time( 'timestamp' ) - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN );
} else {
pp_delete_transient( $this->cookie_name() );
}
}
/**
* Cookie Name
*
* @return string Cookie name.
*/
public function cookie_name() {
/**
* Filters the cookie name
*/
return apply_filters( 'password_protected_cookie_name', $this->get_site_id() . '_password_protected_auth', $this );
}
/**
* Install
*/
public function install() {
$old_version = get_option( 'password_protected_version' );
// 1.1 - Upgrade to MD5
if ( empty( $old_version ) || $old_version == '1.1' ) {
$pwd = get_option( 'password_protected_password' );
if ( ! empty( $pwd ) ) {
$new_pwd = $this->encrypt_password( $pwd );
update_option( 'password_protected_password', $new_pwd );
}
}
update_option( 'password_protected_version', $this->version );
}
/**
* Compat
*
* Support for 3rd party plugins:
*
* - Login Logo https://wordpress.org/plugins/login-logo/
* - Uber Login Logo https://wordpress.org/plugins/uber-login-logo/
*/
public function compat() {
if ( class_exists( 'CWS_Login_Logo_Plugin' ) ) {
// Add support for Mark Jaquith's Login Logo plugin
add_action( 'password_protected_login_head', array( new CWS_Login_Logo_Plugin(), 'login_head' ) );
} elseif ( class_exists( 'UberLoginLogo' ) ) {
// Add support for Uber Login Logo plugin
add_action( 'password_protected_login_head', array( 'UberLoginLogo', 'replaceLoginLogo' ) );
}
}
/**
* Login Messages
* Outputs messages and errors in the login template.
*/
public function login_messages() {
// Add message
$message = apply_filters( 'password_protected_login_message', '' );
if ( ! empty( $message ) ) {
echo $message . "\n";
}
if ( $this->errors->get_error_code() ) {
$errors = '';
$messages = '';
foreach ( $this->errors->get_error_codes() as $code ) {
$severity = $this->errors->get_error_data( $code );
foreach ( $this->errors->get_error_messages( $code ) as $error ) {
if ( 'message' == $severity ) {
$messages .= $error . '
';
} else {
$errors .= $error . '
';
}
}
}
if ( ! empty( $errors ) ) {
echo '