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

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