PluginProbe
Password Protected — Lock Entire Site, Pages, Posts, Categories, and Partial Content / 2.7.10
Password Protected — Lock Entire Site, Pages, Posts, Categories, and Partial Content v2.7.10
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.7.10, at password-protected.php

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