2023-07-01 17:48:45 +08:00
< ? php
2023-07-07 00:34:11 +03:00
namespace um\frontend ;
2023-07-01 17:48:45 +08:00
2023-07-06 01:56:59 +03:00
use WP_Error ;
2023-07-05 12:00:26 +08:00
use WP_User ;
2023-07-01 17:48:45 +08:00
if ( ! defined ( 'ABSPATH' ) ) {
exit ;
}
2023-07-07 00:34:11 +03:00
if ( ! class_exists ( 'um\frontend\Secure' ) ) {
2023-07-01 17:48:45 +08:00
/**
* Class Secure
*
2023-07-07 00:34:11 +03:00
* @package um\frontend
2023-07-01 17:48:45 +08:00
*
2023-07-03 15:38:29 +08:00
* @since 2.6.8
2023-07-01 17:48:45 +08:00
*/
class Secure {
/**
2023-07-07 00:34:11 +03:00
* Secure constructor.
2023-07-03 15:38:29 +08:00
* @since 2.6.8
2023-07-01 17:48:45 +08:00
*/
public function __construct () {
2023-07-06 01:56:59 +03:00
add_action ( 'init' , array ( $this , 'init' ) );
2023-07-01 17:48:45 +08:00
2023-07-06 01:56:59 +03:00
add_action ( 'um_before_login_fields' , array ( $this , 'reset_password_notice' ), 1 );
2023-07-01 17:48:45 +08:00
2023-07-06 01:56:59 +03:00
add_action ( 'um_before_login_fields' , array ( $this , 'under_maintenance_notice' ), 1 );
2023-07-01 17:48:45 +08:00
add_action ( 'um_submit_form_register' , array ( $this , 'block_register_forms' ) );
add_action ( 'um_user_login' , array ( $this , 'login_validate_expired_pass' ), 1 );
add_action ( 'validate_password_reset' , array ( $this , 'avoid_old_password' ), 1 , 2 );
2023-07-03 23:28:49 +08:00
}
/**
2023-07-06 01:56:59 +03:00
* Adds handlers on form submissions.
2023-07-03 23:28:49 +08:00
*
* @since 2.6.8
*/
public function init () {
2023-07-07 00:34:11 +03:00
if ( ! UM () -> options () -> get ( 'secure_ban_admins_accounts' ) ) {
return ;
}
2023-07-03 23:28:49 +08:00
/**
* Checks the integrity of Current User's Capabilities
*/
2023-07-06 01:56:59 +03:00
add_action ( 'um_after_save_registration_details' , array ( $this , 'secure_user_capabilities' ), 1 );
add_action ( 'um_after_save_registration_details' , array ( $this , 'maybe_set_whitelisted_password' ), 2 );
2023-07-03 23:28:49 +08:00
if ( is_user_logged_in () && ! current_user_can ( 'manage_options' ) ) { // Exclude current Logged-in Administrator from validation checks.
add_action ( 'um_after_user_updated' , array ( $this , 'secure_user_capabilities' ), 1 );
2023-07-04 03:34:19 +08:00
add_action ( 'um_after_user_account_updated' , array ( $this , 'secure_user_capabilities' ), 1 );
2023-07-03 23:28:49 +08:00
}
2023-07-01 17:48:45 +08:00
}
/**
* Add Login notice for Reset Password
*
2023-07-03 15:38:29 +08:00
* @since 2.6.8
2023-07-01 17:48:45 +08:00
*/
2023-07-06 01:56:59 +03:00
public function reset_password_notice () {
2023-07-01 17:48:45 +08:00
if ( ! UM () -> options () -> get ( 'display_login_form_notice' ) ) {
return ;
}
// phpcs:disable WordPress.Security.NonceVerification
if ( ! isset ( $_REQUEST [ 'notice' ] ) || 'expired_password' !== $_REQUEST [ 'notice' ] ) {
return ;
}
// phpcs:enable WordPress.Security.NonceVerification
echo " <p class='um-notice warning'> " ;
echo wp_kses (
sprintf (
2023-07-07 00:34:11 +03:00
// translators: One-time change requires you to reset your password
2023-07-01 17:48:45 +08:00
__ ( '<strong>Important:</strong> Your password has expired. This (one-time) change requires you to reset your password. Please <a href="%s">click here</a> to reset your password via Email.' , 'ultimate-member' ),
um_get_core_page ( 'password-reset' )
),
array (
'strong' => array (),
'a' => array (
'href' => array (),
),
)
);
echo '</p>' ;
}
/**
* Add Login notice for Under Maintance
*
2023-07-03 15:38:29 +08:00
* @since 2.6.8
2023-07-01 17:48:45 +08:00
*/
2023-07-06 01:56:59 +03:00
public function under_maintenance_notice () {
2023-07-01 17:48:45 +08:00
if ( ! UM () -> options () -> get ( 'lock_register_forms' ) ) {
return ;
}
// phpcs:disable WordPress.Security.NonceVerification
2023-07-06 01:56:59 +03:00
if ( ! isset ( $_GET [ 'notice' ] ) || 'maintenance' !== $_GET [ 'notice' ] ) {
2023-07-01 17:48:45 +08:00
return ;
}
// phpcs:enable WordPress.Security.NonceVerification
echo " <p class='um-notice warning'> " ;
echo wp_kses (
2023-07-06 01:56:59 +03:00
__ ( '<strong>Important:</strong> This site is currently under maintenance. Please log in or check back soon.' , 'ultimate-member' ),
2023-07-01 17:48:45 +08:00
array (
'strong' => array (),
'a' => array (
'href' => array (),
),
)
);
echo '</p>' ;
}
/**
* Block all UM Register form submissions.
*
2023-07-03 15:38:29 +08:00
* @since 2.6.8
2023-07-01 17:48:45 +08:00
*/
2023-07-07 00:34:11 +03:00
public function block_register_forms () {
2023-07-01 17:48:45 +08:00
if ( UM () -> options () -> get ( 'lock_register_forms' ) ) {
2023-07-06 01:56:59 +03:00
$login_url = add_query_arg ( 'notice' , 'maintenance' , um_get_core_page ( 'login' ) );
2023-07-01 17:48:45 +08:00
nocache_headers ();
wp_safe_redirect ( $login_url );
exit ;
}
}
/**
* Validate when user has expired password
*
2023-07-03 15:38:29 +08:00
* @since 2.6.8
2023-07-01 17:48:45 +08:00
*/
2023-07-06 01:56:59 +03:00
public function login_validate_expired_pass () {
2023-07-01 17:48:45 +08:00
if ( UM () -> options () -> get ( 'display_login_form_notice' ) ) {
2023-07-06 01:56:59 +03:00
$expired_password_reset = get_user_meta ( um_user ( 'ID' ), 'um_secure_has_reset_password' , true );
if ( ! $expired_password_reset ) {
2023-07-01 17:48:45 +08:00
$login_url = add_query_arg ( 'notice' , 'expired_password' , um_get_core_page ( 'login' ) );
wp_safe_redirect ( $login_url );
exit ;
}
}
}
/**
2023-07-06 01:56:59 +03:00
* Prevent users from using Old Passwords on UM Password Reset form.
*
* @param WP_Error $errors
* @param WP_User|WP_Error $user
2023-07-01 17:48:45 +08:00
*
2023-07-03 15:38:29 +08:00
* @since 2.6.8
2023-07-01 17:48:45 +08:00
*/
public function avoid_old_password ( $errors , $user ) {
2023-07-06 01:56:59 +03:00
if ( empty ( $_POST [ '_um_password_change' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
return ;
}
if ( ! UM () -> options () -> get ( 'display_login_form_notice' ) ) {
return ;
}
2023-07-01 17:48:45 +08:00
if ( isset ( $_REQUEST [ 'user_password' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
2023-07-06 01:56:59 +03:00
$new_user_pass = wp_unslash ( $_REQUEST [ 'user_password' ] ); // phpcs:ignore WordPress.Security.NonceVerification
if ( wp_check_password ( $new_user_pass , $user -> data -> user_pass , $user -> ID ) ) {
2023-07-01 17:48:45 +08:00
UM () -> form () -> add_error ( 'user_password' , __ ( 'Your new password cannot be same as old password.' , 'ultimate-member' ) );
2023-07-06 01:56:59 +03:00
$errors -> add ( 'um_block_old_password' , __ ( 'Your new password cannot be same as old password.' , 'ultimate-member' ) );
2023-07-01 17:48:45 +08:00
} else {
2023-07-06 01:56:59 +03:00
update_user_meta ( $user -> ID , 'um_secure_has_reset_password' , true );
update_user_meta ( $user -> ID , 'um_secure_has_reset_password__timestamp' , current_time ( 'mysql' ) );
2023-07-01 17:48:45 +08:00
}
}
}
/**
2023-07-06 01:56:59 +03:00
* Secure user capabilities and revoke administrative ones.
*
2023-07-03 19:38:16 +08:00
* @since 2.6.8
2023-07-07 00:34:11 +03:00
*
* @param int $user_id
2023-07-01 17:48:45 +08:00
*/
2023-07-03 23:28:49 +08:00
public function secure_user_capabilities ( $user_id ) {
2023-07-03 15:38:29 +08:00
global $wpdb ;
2023-07-06 01:56:59 +03:00
$user = get_userdata ( $user_id );
if ( empty ( $user ) ) {
return ;
}
2023-07-01 17:48:45 +08:00
// Fetch the WP_User object of our user.
2023-07-03 16:54:16 +08:00
um_fetch_user ( $user_id );
2023-07-03 23:28:49 +08:00
$has_admin_cap = false ;
$arr_banned_caps = array ();
if ( UM () -> options () -> get ( 'banned_capabilities' ) ) {
2023-07-07 02:32:37 +03:00
$arr_banned_caps = UM () -> options () -> get ( 'banned_capabilities' );
2023-07-03 23:28:49 +08:00
}
2023-07-06 01:56:59 +03:00
// Add locked administrative capabilities.
$arr_banned_caps = array_merge ( $arr_banned_caps , UM () -> options () -> get_default ( 'banned_capabilities' ) );
2023-07-03 23:28:49 +08:00
2023-07-06 01:56:59 +03:00
foreach ( $arr_banned_caps as $cap ) {
2023-07-03 23:28:49 +08:00
/**
* When there's at least one administrator cap added to the user,
* immediately revoke caps and mark as rejected.
*/
if ( $user -> has_cap ( $cap ) ) {
$has_admin_cap = true ;
break ;
2023-07-01 17:48:45 +08:00
}
}
2023-07-06 01:56:59 +03:00
if ( ! $has_admin_cap ) {
/**
* Double-check if *_user_level has been modified with the highest level
* when user has no administrative capabilities.
*/
$user_level = um_user ( $wpdb -> get_blog_prefix () . 'user_level' );
if ( ! empty ( $user_level ) && 10 === absint ( $user_level ) ) {
2023-07-03 16:48:36 +08:00
$has_admin_cap = true ;
2023-07-01 17:48:45 +08:00
}
}
if ( $has_admin_cap ) {
2023-07-07 00:34:11 +03:00
UM () -> common () -> secure () -> revoke_caps ( $user );
2023-07-03 23:28:49 +08:00
/**
* Notify Administrators Immediately
*/
if ( UM () -> options () -> get ( 'secure_notify_admins_banned_accounts' ) ) {
$interval = UM () -> options () -> get ( 'secure_notify_admins_banned_accounts__interval' );
if ( 'instant' === $interval ) {
2023-07-07 00:34:11 +03:00
UM () -> common () -> secure () -> send_notification ( array ( $user_id ) );
2023-07-03 23:28:49 +08:00
}
}
// Destroy Sessions & Redirect.
wp_destroy_current_session ();
wp_logout ();
session_unset ();
2023-07-04 00:18:36 +08:00
$redirect = apply_filters ( 'um_secure_blocked_user_redirect_immediately' , true );
if ( $redirect ) {
$login_url = add_query_arg ( 'err' , 'inactive' , um_get_core_page ( 'login' ) );
wp_safe_redirect ( $login_url );
exit ;
}
2023-07-06 01:56:59 +03:00
}
}
2023-07-04 00:18:36 +08:00
2023-07-06 01:56:59 +03:00
/**
2023-07-07 00:34:11 +03:00
* Set meta (no need to reset his password) if the user is a new registered.
2023-07-06 01:56:59 +03:00
*
* @since 2.6.8
2023-07-07 00:34:11 +03:00
*
* @param int $user_id
2023-07-06 01:56:59 +03:00
*/
public function maybe_set_whitelisted_password ( $user_id ) {
$user = get_userdata ( $user_id );
if ( empty ( $user ) ) {
return ;
2023-07-01 17:48:45 +08:00
}
2023-07-04 00:18:36 +08:00
2023-07-06 01:56:59 +03:00
if ( UM () -> options () -> get ( 'display_login_form_notice' ) ) {
update_user_meta ( $user_id , 'um_secure_has_reset_password' , true );
update_user_meta ( $user_id , 'um_secure_has_reset_password__timestamp' , current_time ( 'mysql' ) );
}
2023-07-01 17:48:45 +08:00
}
2023-07-05 12:00:26 +08:00
}
2023-07-01 17:48:45 +08:00
}