PluginProbe
Password Protected — Lock Entire Site, Pages, Posts, Categories, and Partial Content / 2.6.8
Password Protected — Lock Entire Site, Pages, Posts, Categories, and Partial Content v2.6.8
2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0 1.1 1.2 1.2.1 1.2.2 1.3 1.4 1.5 1.6 1.6.1 1.6.2 1.7 1.7.1 1.7.2 1.8 1.9 2.0 2.0.1 2.0.2 2.0.3 All 63 releases
password-protected / password-protected.php

password-protected.php in Password Protected — Lock Entire Site, Pages, Posts, Categories, and Partial Content 2.6.8, at password-protected.php

994 lines 26.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Password Protected
4 Plugin URI: https://wordpress.org/plugins/password-protected/
5 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.
6 Version: 2.6.8
7 Author: Password Protected
8 Text Domain: password-protected
9 Author URI: https://passwordprotectedwp.com/
10 License: GPLv2
11 */
12 /*
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License, version 2, as
15 published by the Free Software Foundation.
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 /**
28 * @todo Use wp_hash_password() ?
29 * @todo Remember me
30 */
31
32 define( 'PASSWORD_PROTECTED_SUBDIR', '/' . str_replace( basename( __FILE__ ), '', plugin_basename( __FILE__ ) ) );
33 define( 'PASSWORD_PROTECTED_URL', plugins_url( PASSWORD_PROTECTED_SUBDIR ) );
34 define( 'PASSWORD_PROTECTED_DIR', plugin_dir_path( __FILE__ ) );
35
36 require_once PASSWORD_PROTECTED_DIR . 'includes/freemius.php';
37
38 global $Password_Protected;
39 $Password_Protected = new Password_Protected();
40
41 class Password_Protected {
42
43 var $version = '2.6.8';
44 var $admin = null;
45 var $errors = null;
46 var $admin_caching = null;
47
48 /**
49 * Constructor
50 */
51 public function __construct() {
52
53 $this->errors = new WP_Error();
54
55 register_activation_hook( __FILE__, array( &$this, 'install' ) );
56
57 add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
58
59 add_filter( 'password_protected_is_active', array( $this, 'allow_ip_addresses' ) );
60 add_filter( 'password_protected_is_active', array( $this, 'compatibility_elementor' ) );
61
62 add_action( 'init', array( $this, 'disable_caching' ), 1 );
63 add_action( 'init', array( $this, 'maybe_process_logout' ), 1 );
64 add_action( 'init', array( $this, 'maybe_process_login' ), 1 );
65 add_action( 'wp', array( $this, 'disable_feeds' ) );
66 add_action( 'template_redirect', array( $this, 'maybe_show_login' ), -10 );
67 add_filter( 'pre_option_password_protected_status', array( $this, 'allow_feeds' ) );
68 add_filter( 'pre_option_password_protected_status', array( $this, 'allow_administrators' ) );
69 add_filter( 'pre_option_password_protected_status', array( $this, 'allow_users' ) );
70 add_filter( 'rest_authentication_errors', array( $this, 'only_allow_logged_in_rest_access' ) );
71 add_action( 'init', array( $this, 'compat' ) );
72 add_action( 'password_protected_login_messages', array( $this, 'login_messages' ) );
73 add_action( 'login_enqueue_scripts', array( $this, 'load_theme_stylesheet' ), 5 );
74
75 add_action( 'password_protected_above_password_field', array( $this, 'password_protected_above_password_field' ) );
76 add_action( 'password_protected_below_password_field', array( $this, 'password_protected_below_password_field' ) );
77
78 // Available from WordPress 4.3+
79 if ( function_exists( 'wp_site_icon' ) ) {
80 add_action( 'password_protected_login_head', 'wp_site_icon' );
81 }
82
83 add_shortcode( 'password_protected_logout_link', array( $this, 'logout_link_shortcode' ) );
84
85 include_once dirname( __FILE__ ) . '/admin/admin-bar.php';
86
87 if ( is_admin() ) {
88
89 include_once dirname( __FILE__ ) . '/admin/admin-caching.php';
90 include_once dirname( __FILE__ ) . '/admin/admin.php';
91
92 $this->admin_caching = new Password_Protected_Admin_Caching( $this );
93 $this->admin = new Password_Protected_Admin();
94
95 }
96 include_once dirname( __FILE__ ) . '/admin/class-recaptcha.php';
97 new Password_Protected_reCAPTCHA();
98
99 include_once dirname( __FILE__ ) . '/includes/transient-functions.php';
100 }
101
102 /**
103 * I18n
104 */
105 public function load_plugin_textdomain() {
106
107 load_plugin_textdomain( 'password-protected', false, basename( dirname( __FILE__ ) ) . '/languages' );
108
109 }
110
111 /**
112 * Disable Page Caching
113 */
114 public function disable_caching() {
115
116 if ( $this->is_active() && ! defined( 'DONOTCACHEPAGE' ) ) {
117 define( 'DONOTCACHEPAGE', true );
118 }
119
120 }
121
122 /**
123 * Is Active?
124 *
125 * @return boolean Is password protection active?
126 */
127 public function is_active() {
128
129 global $wp_query;
130
131 // Always allow access to robots.txt
132 if ( isset( $wp_query ) && is_robots() ) {
133 return false;
134 }
135
136 if ( (bool) get_option( 'password_protected_status' ) ) {
137 $is_active = true;
138 } else {
139 $is_active = false;
140 }
141
142 $is_active = apply_filters( 'password_protected_is_active', $is_active );
143
144 if ( isset( $_GET['password-protected'] ) ) {
145 $is_active = true;
146 }
147
148 return $is_active;
149
150 }
151
152 /**
153 * Disable Feeds
154 *
155 * @todo An option/filter to prevent disabling of feeds.
156 */
157 public function disable_feeds() {
158
159 if ( $this->is_active() ) {
160 add_action( 'do_feed', array( $this, 'disable_feed' ), 1 );
161 add_action( 'do_feed_rdf', array( $this, 'disable_feed' ), 1 );
162 add_action( 'do_feed_rss', array( $this, 'disable_feed' ), 1 );
163 add_action( 'do_feed_rss2', array( $this, 'disable_feed' ), 1 );
164 add_action( 'do_feed_atom', array( $this, 'disable_feed' ), 1 );
165 }
166
167 }
168
169 /**
170 * Disable Feed
171 *
172 * @todo Make Translatable
173 */
174 public function disable_feed() {
175
176 wp_die( sprintf( __( 'Feeds are not available for this site. Please visit the <a href="%s">website</a>.', 'password-protected' ), get_bloginfo( 'url' ) ) );
177
178 }
179
180 /**
181 * Allow Feeds
182 *
183 * @param boolean $bool Allow feeds.
184 * @return boolean True/false.
185 */
186 public function allow_feeds( $bool ) {
187
188 if ( is_feed() && (bool) get_option( 'password_protected_feeds' ) ) {
189 return 0;
190 }
191
192 return $bool;
193
194 }
195
196 /**
197 * Allow Administrators
198 *
199 * @param boolean $bool Allow administrators.
200 * @return boolean True/false.
201 */
202 public function allow_administrators( $bool ) {
203
204 if ( ! is_admin() && current_user_can( 'manage_options' ) && (bool) get_option( 'password_protected_administrators' ) ) {
205 return 0;
206 }
207
208 return $bool;
209
210 }
211
212 /**
213 * Allow Users
214 *
215 * @param boolean $bool Allow administrators.
216 * @return boolean True/false.
217 */
218 public function allow_users( $bool ) {
219
220 if ( ! is_admin() && is_user_logged_in() && (bool) get_option( 'password_protected_users' ) ) {
221 return 0;
222 }
223
224 return $bool;
225
226 }
227
228 /**
229 * Allow IP Addresses
230 *
231 * If user has a valid email address, return false to disable password protection.
232 *
233 * @param boolean $bool Allow IP addresses.
234 * @return boolean True/false.
235 */
236 public function allow_ip_addresses( $bool ) {
237
238 $ip_addresses = $this->get_allowed_ip_addresses();
239
240 if ( isset( $_SERVER['REMOTE_ADDR'] ) && in_array( $_SERVER['REMOTE_ADDR'], $ip_addresses ) ) {
241 $bool = false;
242 }
243
244 return $bool;
245
246 }
247
248 /**
249 * Compatibility with Elementor
250 *
251 * @param boolean $access Access for elementor.
252 *
253 * @return bool
254 */
255 public function compatibility_elementor( $access ) {
256
257 if ( class_exists( 'Elementor\\Plugin' ) ) {
258 if ( Elementor\Plugin::$instance->preview->is_preview_mode() ) {
259 $access = false;
260 }
261 }
262
263 return $access;
264 }
265
266 /**
267 * Get Allowed IP Addresses
268 *
269 * @return array IP addresses.
270 */
271 public function get_allowed_ip_addresses() {
272
273 return explode( "\n", get_option( 'password_protected_allowed_ip_addresses' ) );
274
275 }
276
277 /**
278 * Allow the remember me function
279 *
280 * @return. boolean
281 */
282 public function allow_remember_me() {
283
284 return (bool) get_option( 'password_protected_remember_me' );
285
286 }
287
288 /**
289 * Encrypt Password
290 *
291 * @param string $password Password.
292 * @return string Encrypted password.
293 */
294 public function encrypt_password( $password ) {
295
296 return md5( $password );
297
298 }
299
300 /**
301 * Maybe Process Logout
302 */
303 public function maybe_process_logout() {
304
305 if ( isset( $_REQUEST['password-protected'] ) && sanitize_text_field( $_REQUEST['password-protected'] ) == 'logout' ) {
306
307 $this->logout();
308
309 if ( isset( $_REQUEST['redirect_to'] ) ) {
310 $redirect_to = remove_query_arg( 'password-protected', esc_url_raw( $_REQUEST['redirect_to'], array( 'http', 'https' ) ) );
311 } else {
312 $redirect_to = home_url( '/' );
313 }
314
315 $this->safe_redirect( $redirect_to );
316 exit();
317
318 }
319
320 }
321
322 /**
323 * Maybe Process Login
324 */
325 public function maybe_process_login() {
326
327 if ( $this->is_active() && isset( $_REQUEST['password_protected_pwd'] ) ) {
328
329 $password_protected_pwd = sanitize_text_field( $_REQUEST['password_protected_pwd'] );
330 $default_password = get_option( 'password_protected_password' );
331
332 $auth = false;
333 $p_id = 0;
334
335 if ( empty( $default_password ) ) {
336
337 $authentication = $this->password_protected_check_pro_password( $password_protected_pwd );
338 $auth = $authentication['auth'];
339 $p_id = $authentication['p_id'];
340
341 } else {
342
343 if ( ( hash_equals( $default_password, $this->encrypt_password( $password_protected_pwd ) ) && $default_password != '' ) || apply_filters( 'password_protected_process_login', false, $password_protected_pwd ) ) {
344 $auth = true;
345 }
346
347 if ( ! $auth ) {
348
349 $authentication = $this->password_protected_check_pro_password( $password_protected_pwd );
350 $auth = $authentication['auth'];
351 $p_id = $authentication['p_id'];
352 }
353 }
354
355 $this->errors = apply_filters( 'password_protected_verify_recaptcha', $this->errors );
356
357 if ( count( @$this->errors->errors ) > 0 ) {
358 return;
359 }
360
361 $this->password_protected_process_login( $auth, $password_protected_pwd, $p_id );
362
363 }
364
365 }
366
367 public function password_protected_process_login( bool $auth, $requested_password, $password_id ) {
368
369 if ( $auth ) {
370 $throttle = apply_filters( 'password_protected_check_for_throttling', true );
371 }
372
373 if ( $auth && $throttle ) {
374
375 do_action( 'password_protected_success_login_attempt', 'global', $requested_password, $password_id );
376 $remember = isset( $_REQUEST['password_protected_rememberme'] ) ? boolval( $_REQUEST['password_protected_rememberme'] ) : false;
377
378 if ( ! $this->allow_remember_me() ) {
379 $remember = false;
380 }
381 $this->set_auth_cookie( $remember );
382
383 $redirect_to = isset( $_REQUEST['redirect_to'] ) ? esc_url( $_REQUEST['redirect_to'] ) : '';
384 $redirect_to = apply_filters( 'password_protected_login_redirect', $redirect_to, $requested_password );
385
386 if ( ! empty( $redirect_to ) ) {
387 $this->safe_redirect( remove_query_arg( 'password-protected', $redirect_to ) );
388 exit;
389 } elseif ( isset( $_GET['password_protected_pwd'] ) ) {
390 $this->safe_redirect( remove_query_arg( 'password-protected' ) );
391 exit;
392 } else {
393 $this->safe_redirect( site_url() );
394 exit;
395 }
396 } else {
397 do_action( 'password_protected_failure_login_attempt', 'global', $requested_password, $password_id );
398
399 // ... otherwise incorrect password
400 $this->clear_auth_cookie();
401
402 $show_default_error = apply_filters( 'password_protected_throttling_error_messages', true );
403
404 if ( $show_default_error ) {
405 $this->errors->add( 'incorrect_password', __( 'Incorrect Password', 'password-protected' ) );
406 }
407 }
408 }
409
410 /**
411 * password_protected_check_pro_password
412 *
413 * @param mixed $requested_password
414 * @return void
415 */
416 public function password_protected_check_pro_password( $requested_password ) {
417
418 $pro_passwords = apply_filters( 'password_protected_passwords', array() );
419 $pro_passwords = array_filter( $pro_passwords );
420 $auth = false;
421 $p_id = 0;
422
423 if ( is_array( $pro_passwords ) && count( $pro_passwords ) > 0 ) {
424
425 foreach ( $pro_passwords as $i => $p ) {
426
427 if ( ( hash_equals( $p, $this->encrypt_password( $requested_password ) ) && $pro_passwords != '' ) || apply_filters( 'password_protected_process_login', false, $requested_password ) ) {
428
429 $auth = apply_filters( 'password_protected_login_password_matched', $p, $this->errors );
430 $p_id = $i;
431 break;
432
433 }
434 }
435 } else {
436
437 $auth = false;
438
439 }
440
441 return array(
442 'auth' => $auth,
443 'p_id' => $p_id,
444 );
445 }
446
447 /**
448 * Is User Logged In?
449 *
450 * @return boolean
451 */
452 public function is_user_logged_in() {
453
454 return $this->is_active() && $this->validate_auth_cookie();
455
456 }
457
458 /**
459 * Maybe Show Login
460 */
461 public function maybe_show_login() {
462
463 if ( class_exists( 'Login_designer' ) ) {
464 if ( is_customize_preview() ) {
465 return 1;
466 }
467 }
468
469 // Filter for adding exceptions.
470 $show_login = apply_filters( 'password_protected_show_login', $this->is_active() );
471
472 // Logged in
473 if ( $this->is_user_logged_in() ) {
474 $show_login = false;
475 }
476
477 if ( ! $show_login ) {
478 return 1;
479 }
480
481 // Show login form
482 if ( isset( $_REQUEST['password-protected'] ) && 'login' == sanitize_text_field( $_REQUEST['password-protected'] ) ) {
483
484 $default_theme_file = locate_template( array( 'password-protected-login.php' ) );
485
486 if ( empty( $default_theme_file ) ) {
487 $default_theme_file = dirname( __FILE__ ) . '/theme/password-protected-login.php';
488 }
489
490 $theme_file = apply_filters( 'password_protected_theme_file', $default_theme_file );
491 if ( ! file_exists( $theme_file ) ) {
492 $theme_file = $default_theme_file;
493 }
494
495 load_template( $theme_file );
496 exit();
497
498 } else {
499 global $wp;
500
501 $redirect_to = add_query_arg( 'password-protected', 'login', home_url( $wp->request . '?' . $_SERVER['QUERY_STRING'] ) );
502
503 // URL to redirect back to after login
504 $redirect_to_url = apply_filters( 'password_protected_login_redirect_url', ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
505 if ( ! empty( $redirect_to_url ) ) {
506 $redirect_to = add_query_arg( 'redirect_to', urlencode( $redirect_to_url ), $redirect_to );
507 }
508
509 nocache_headers();
510 wp_redirect( $redirect_to );
511 exit();
512
513 }
514 }
515
516 /**
517 * Get Site ID
518 *
519 * @return string Site ID.
520 */
521 public function get_site_id() {
522
523 global $blog_id;
524 return 'bid_' . apply_filters( 'password_protected_blog_id', $blog_id );
525
526 }
527
528 /**
529 * Login URL
530 *
531 * @return string Login URL.
532 */
533 public function login_url() {
534 global $wp;
535 return add_query_arg( 'password-protected', 'login', home_url( $wp->request . '?' . $_SERVER['QUERY_STRING'] ) );
536
537 }
538
539 /**
540 * Logout
541 */
542 public function logout() {
543
544 $this->clear_auth_cookie();
545 do_action( 'password_protected_logout' );
546
547 }
548
549 /**
550 * Logout URL
551 *
552 * @param string $redirect_to Optional. Redirect URL.
553 * @return string Logout URL.
554 */
555 public function logout_url( $redirect_to = '' ) {
556
557 $query = array(
558 'password-protected' => 'logout',
559 'redirect_to' => esc_url_raw( $redirect_to ),
560 );
561
562 if ( empty( $query['redirect_to'] ) ) {
563 unset( $query['redirect_to'] );
564 }
565
566 return add_query_arg( $query, home_url() );
567
568 }
569
570 /**
571 * Logout Link
572 *
573 * @param array $args Link args.
574 * @return string HTML link tag.
575 */
576 public function logout_link( $args = null ) {
577
578 // Only show if user is logged in
579 if ( ! $this->is_user_logged_in() ) {
580 return '';
581 }
582
583 $args = wp_parse_args(
584 $args,
585 array(
586 'redirect_to' => '',
587 'text' => __( 'Logout', 'password-protected' ),
588 )
589 );
590
591 if ( empty( $args['text'] ) ) {
592 $args['text'] = __( 'Logout', 'password-protected' );
593 }
594
595 return sprintf( '<a href="%s">%s</a>', esc_url( $this->logout_url( $args['redirect_to'] ) ), esc_html( $args['text'] ) );
596
597 }
598
599 /**
600 * Logout Link Shortcode
601 *
602 * @param array $args Link args.
603 * @return string HTML link tag.
604 */
605 public function logout_link_shortcode( $atts, $content = null ) {
606
607 $atts = shortcode_atts(
608 array(
609 'redirect_to' => '',
610 'text' => $content,
611 ),
612 $atts,
613 'logout_link_shortcode'
614 );
615
616 return $this->logout_link( $atts );
617
618 }
619
620 /**
621 * Get Hashed Password
622 *
623 * @return string Hashed password.
624 */
625 public function get_hashed_password() {
626
627 return md5( get_option( 'password_protected_password' ) . wp_salt() );
628
629 }
630
631 /**
632 * Validate Auth Cookie
633 *
634 * @param string $cookie Cookie string.
635 * @param string $scheme Cookie scheme.
636 * @return boolean Validation successful?
637 */
638 public function validate_auth_cookie( $cookie = '', $scheme = '' ) {
639
640 if ( ! $cookie_elements = $this->parse_auth_cookie( $cookie, $scheme ) ) {
641 do_action( 'password_protected_auth_cookie_malformed', $cookie, $scheme );
642 return false;
643 }
644
645 extract( $cookie_elements, EXTR_OVERWRITE );
646
647 $expired = $expiration;
648
649 // Allow a grace period for POST and AJAX requests
650 if ( defined( 'DOING_AJAX' ) || 'POST' == $_SERVER['REQUEST_METHOD'] ) {
651 $expired += 3600;
652 }
653
654 // Quick check to see if an honest cookie has expired
655 if ( $expired < current_time( 'timestamp' ) ) {
656 do_action( 'password_protected_auth_cookie_expired', $cookie_elements );
657 return false;
658 }
659
660 $key = md5( $this->get_site_id() . $this->get_hashed_password() . '|' . $expiration );
661 $hash = hash_hmac( 'md5', $this->get_site_id() . '|' . $expiration, $key );
662
663 if ( $hmac != $hash ) {
664 do_action( 'password_protected_auth_cookie_bad_hash', $cookie_elements );
665 return false;
666 }
667
668 if ( $expiration < current_time( 'timestamp' ) ) { // AJAX/POST grace period set above
669 $GLOBALS['login_grace_period'] = 1;
670 }
671
672 return true;
673
674 }
675
676 /**
677 * Generate Auth Cookie
678 *
679 * @param int $expiration Expiration time in seconds.
680 * @param string $scheme Cookie scheme.
681 * @return string Cookie.
682 */
683 public function generate_auth_cookie( $expiration, $scheme = 'auth' ) {
684
685 $key = md5( $this->get_site_id() . $this->get_hashed_password() . '|' . $expiration );
686 $hash = hash_hmac( 'md5', $this->get_site_id() . '|' . $expiration, $key );
687 $cookie = $this->get_site_id() . '|' . $expiration . '|' . $hash;
688
689 return $cookie;
690
691 }
692
693 /**
694 * Parse Auth Cookie
695 *
696 * @param string $cookie Cookie string.
697 * @param string $scheme Cookie scheme.
698 * @return string Cookie string.
699 */
700 public function parse_auth_cookie( $cookie = '', $scheme = '' ) {
701 if ( empty( $cookie ) ) {
702
703 $cookie_name = $this->cookie_name();
704 $use_transient = get_option( 'password_protected_use_transient', '' );
705
706 if ( empty( $use_transient ) ) {
707 if ( empty( $_COOKIE[ $cookie_name ] ) ) {
708 return false;
709 }
710
711 $cookie = $_COOKIE[ $cookie_name ];
712 } else {
713 $cookie = pp_get_transient( $cookie_name );
714 }
715 }
716
717 $cookie_elements = explode( '|', $cookie );
718
719 if ( count( $cookie_elements ) != 3 ) {
720 return false;
721 }
722
723 list( $site_id, $expiration, $hmac ) = $cookie_elements;
724
725 return compact( 'site_id', 'expiration', 'hmac', 'scheme' );
726
727 }
728
729 /**
730 * Set Auth Cookie
731 *
732 * @todo
733 *
734 * @param boolean $remember Remember logged in.
735 * @param string $secure Secure cookie.
736 */
737 public function set_auth_cookie( $remember = false, $secure = '' ) {
738
739 if ( $remember ) {
740 $expiration_time = apply_filters( 'password_protected_auth_cookie_expiration', get_option( 'password_protected_remember_me_lifetime', 14 ) * DAY_IN_SECONDS, $remember );
741 $expiration = $expire = current_time( 'timestamp' ) + $expiration_time;
742 } else {
743 $expiration_time = apply_filters( 'password_protected_auth_cookie_expiration', DAY_IN_SECONDS * 20, $remember );
744 $expiration = current_time( 'timestamp' ) + $expiration_time;
745 $expire = 0;
746 }
747
748 if ( '' === $secure ) {
749 $secure = is_ssl();
750 }
751
752 $secure_password_protected_cookie = apply_filters( 'password_protected_secure_password_protected_cookie', false, $secure );
753 $password_protected_cookie = $this->generate_auth_cookie( $expiration, 'password_protected' );
754
755 $use_transient = get_option( 'password_protected_use_transient', '' );
756 if ( empty( $use_transient ) ) {
757 setcookie( $this->cookie_name(), $password_protected_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_password_protected_cookie, true );
758 if ( COOKIEPATH != SITECOOKIEPATH ) {
759 setcookie( $this->cookie_name(), $password_protected_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_password_protected_cookie, true );
760 }
761 } else {
762 pp_set_transient( $this->cookie_name(), $password_protected_cookie, $expiration_time );
763 }
764
765 }
766
767 /**
768 * Clear Auth Cookie
769 */
770 public function clear_auth_cookie() {
771 $use_transient = get_option( 'password_protected_use_transient', '' );
772 if ( empty( $use_transient ) ) {
773 setcookie( $this->cookie_name(), ' ', current_time( 'timestamp' ) - 31536000, COOKIEPATH, COOKIE_DOMAIN );
774 setcookie( $this->cookie_name(), ' ', current_time( 'timestamp' ) - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN );
775 } else {
776 pp_delete_transient( $this->cookie_name() );
777 }
778
779 }
780
781 /**
782 * Cookie Name
783 *
784 * @return string Cookie name.
785 */
786 public function cookie_name() {
787
788 /**
789 * Filters the cookie name
790 */
791 return apply_filters( 'password_protected_cookie_name', $this->get_site_id() . '_password_protected_auth', $this );
792
793 }
794
795 /**
796 * Install
797 */
798 public function install() {
799
800 $old_version = get_option( 'password_protected_version' );
801
802 // 1.1 - Upgrade to MD5
803 if ( empty( $old_version ) || $old_version == '1.1' ) {
804 $pwd = get_option( 'password_protected_password' );
805 if ( ! empty( $pwd ) ) {
806 $new_pwd = $this->encrypt_password( $pwd );
807 update_option( 'password_protected_password', $new_pwd );
808 }
809 }
810
811 update_option( 'password_protected_version', $this->version );
812
813 }
814
815 /**
816 * Compat
817 *
818 * Support for 3rd party plugins:
819 *
820 * - Login Logo https://wordpress.org/plugins/login-logo/
821 * - Uber Login Logo https://wordpress.org/plugins/uber-login-logo/
822 */
823 public function compat() {
824
825 if ( class_exists( 'CWS_Login_Logo_Plugin' ) ) {
826
827 // Add support for Mark Jaquith's Login Logo plugin
828 add_action( 'password_protected_login_head', array( new CWS_Login_Logo_Plugin(), 'login_head' ) );
829
830 } elseif ( class_exists( 'UberLoginLogo' ) ) {
831
832 // Add support for Uber Login Logo plugin
833 add_action( 'password_protected_login_head', array( 'UberLoginLogo', 'replaceLoginLogo' ) );
834
835 }
836
837 }
838
839 /**
840 * Login Messages
841 * Outputs messages and errors in the login template.
842 */
843 public function login_messages() {
844
845 // Add message
846 $message = apply_filters( 'password_protected_login_message', '' );
847 if ( ! empty( $message ) ) {
848 echo $message . "\n";
849 }
850
851 if ( $this->errors->get_error_code() ) {
852
853 $errors = '';
854 $messages = '';
855
856 foreach ( $this->errors->get_error_codes() as $code ) {
857 $severity = $this->errors->get_error_data( $code );
858 foreach ( $this->errors->get_error_messages( $code ) as $error ) {
859 if ( 'message' == $severity ) {
860 $messages .= $error . '<br />';
861 } else {
862 $errors .= $error . '<br />';
863 }
864 }
865 }
866
867 if ( ! empty( $errors ) ) {
868 echo '<div id="login_error" class="notice notice-error">' . apply_filters( 'password_protected_login_errors', $errors ) . "</div>\n";
869 }
870 if ( ! empty( $messages ) ) {
871 echo '<p class="message">' . apply_filters( 'password_protected_login_messages', $messages ) . "</p>\n";
872 }
873 }
874
875 }
876
877 /**
878 * Load Theme Stylesheet
879 *
880 * Check wether a 'password-protected-login.css' stylesheet exists in your theme
881 * and if so loads it.
882 *
883 * Works with child themes.
884 *
885 * Possible to specify a different file in the theme folder via the
886 * 'password_protected_stylesheet_file' filter (allows for theme subfolders).
887 */
888 public function load_theme_stylesheet() {
889
890 $filename = apply_filters( 'password_protected_stylesheet_file', 'password-protected-login.css' );
891
892 $located = locate_template( $filename );
893
894 if ( ! empty( $located ) ) {
895
896 $stylesheet_directory = trailingslashit( get_stylesheet_directory() );
897 $template_directory = trailingslashit( get_template_directory() );
898
899 if ( $stylesheet_directory == substr( $located, 0, strlen( $stylesheet_directory ) ) ) {
900 wp_enqueue_style( 'password-protected-login', get_stylesheet_directory_uri() . '/' . $filename );
901 } elseif ( $template_directory == substr( $located, 0, strlen( $template_directory ) ) ) {
902 wp_enqueue_style( 'password-protected-login', get_template_directory_uri() . '/' . $filename );
903 }
904 }
905
906 }
907
908 /**
909 * Safe Redirect
910 *
911 * Ensure the redirect is to the same site or pluggable list of allowed domains.
912 * If invalid will redirect to ...
913 * Based on the WordPress wp_safe_redirect() function.
914 */
915 public function safe_redirect( $location, $status = 302 ) {
916
917 $location = wp_sanitize_redirect( $location );
918 $location = wp_validate_redirect( $location, home_url() );
919
920 wp_redirect( $location, $status );
921
922 }
923
924 /**
925 * Is Plugin Supported?
926 *
927 * Check to see if there are any known reasons why this plugin may not work in
928 * the user's hosting environment.
929 *
930 * @return boolean
931 */
932 static function is_plugin_supported() {
933
934 return true;
935
936 }
937
938 /**
939 * Check whether a given request has permissions
940 *
941 * Always allow logged in users who require REST API for Gutenberg
942 * and other admin/plugin compatibility.
943 *
944 * @param null|WP_Error $access Full details about the request.
945 * @return WP_Error|null
946 */
947 public function only_allow_logged_in_rest_access( $access ) {
948 if ( $this->is_active() ) {
949 if ( is_user_logged_in() ) {
950 global $current_user;
951 if ( $current_user->has_cap( 'edit_posts' ) || $current_user->has_cap( 'edit_pages' ) ) {
952 return $access;
953 }
954 }
955
956 if ( $this->is_user_logged_in() ) {
957 return $access;
958 }
959
960 if ( get_option( 'password_protected_rest' ) ) {
961 return $access;
962 }
963 return new WP_Error( 'rest_cannot_access', __( 'Only authenticated users can access the REST API.', 'password-protected' ), array( 'status' => rest_authorization_required_code() ) );
964 }
965
966 return $access;
967 }
968
969 /**
970 * Print text above password field
971 *
972 * @return void.
973 */
974 public function password_protected_above_password_field() {
975 $text = get_option( 'password_protected_text_above_password' );
976 if ( ! empty( $text ) ) {
977 echo '<div class="password-protected-text-above" style="width:100%;">' . wp_kses_post( $text ) . '</div>';
978 }
979 }
980
981 /**
982 * Print text below password field
983 *
984 * @return void.
985 */
986 public function password_protected_below_password_field() {
987 $text = get_option( 'password_protected_text_below_password' );
988 if ( ! empty( $text ) ) {
989 echo '<div class="password-protected-text-below" style="width:100%">' . wp_kses_post( $text ) . '</div>';
990 }
991 }
992
993 }
994