847 lines
37 KiB
PHP
847 lines
37 KiB
PHP
<?php
|
|
|
|
if (!defined('ABSPATH')) die('No direct access allowed');
|
|
|
|
if (trait_exists('AIOWPSecurity_User_Security_Commands_Trait')) return;
|
|
|
|
trait AIOWPSecurity_User_Security_Commands_Trait {
|
|
|
|
/**
|
|
* Saves user account security settings.
|
|
*
|
|
* This function updates security settings related to user enumeration prevention
|
|
* and strong password enforcement in the AIO WP Security plugin.
|
|
*
|
|
* @param array $data An associative array containing the security settings:
|
|
* - 'aiowps_prevent_users_enumeration' (optional): Set to '1' to prevent user enumeration.
|
|
* - 'aiowps_enforce_strong_password' (optional): Set to '1' to enforce strong passwords.
|
|
*
|
|
* @return array The response array containing:
|
|
* - 'badges' (array): A list of applied security badges.
|
|
*/
|
|
public function perform_save_user_account_settings($data) {
|
|
global $aio_wp_security;
|
|
|
|
// Save settings
|
|
$aio_wp_security->configs->set_value('aiowps_prevent_users_enumeration', isset($data["aiowps_prevent_users_enumeration"]) ? '1' : '', true);
|
|
$aio_wp_security->configs->set_value('aiowps_enforce_strong_password', isset($data['aiowps_enforce_strong_password']) ? '1' : '', true);
|
|
|
|
$badges = array('enforce-strong-password', 'disable-users-enumeration');
|
|
|
|
return $this->handle_response(true, '', array('badges' => $badges));
|
|
}
|
|
|
|
/**
|
|
* Performs the action to change the admin username.
|
|
*
|
|
* @param array $data An array containing the data for changing the admin username.
|
|
* The array may contain the following keys:
|
|
* - 'aiowps_new_user_name': The new username to be set for the admin.
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* and a message indicating the result of the operation.
|
|
* If the operation is successful, it also includes a badge representing the updated feature details.
|
|
*/
|
|
public function perform_change_admin_username($data) {
|
|
global $wpdb, $aio_wp_security;
|
|
|
|
$response = array(
|
|
'status' => 'success',
|
|
'content' => array()
|
|
);
|
|
|
|
$error = '';
|
|
if (!empty($data['aiowps_new_user_name'])) {
|
|
$new_username = sanitize_text_field($data['aiowps_new_user_name']);
|
|
if (validate_username($new_username)) {
|
|
if (AIOWPSecurity_Utility::check_user_exists($new_username)) {
|
|
$response['status'] = 'error';
|
|
$error = sprintf(__('Username: %s already exists, please enter another value.', 'all-in-one-wp-security-and-firewall'), $new_username);
|
|
} else {
|
|
// let's check if currently logged in username is 'admin'
|
|
$user = wp_get_current_user();
|
|
$user_login = $user->user_login;
|
|
if ('admin' == strtolower($user_login)) {
|
|
$username_is_admin = true;
|
|
} else {
|
|
$username_is_admin = false;
|
|
}
|
|
// Now let's change the username
|
|
$sql = $wpdb->prepare("UPDATE `" . $wpdb->users . "` SET user_login = '" . esc_sql($new_username) . "' WHERE user_login=%s", "admin");
|
|
$result = $wpdb->query($sql);
|
|
if (false === $result) {
|
|
// There was an error updating the users table
|
|
$user_update_error = __('The database update operation of the user account failed.', 'all-in-one-wp-security-and-firewall');
|
|
$response['status'] = 'error';
|
|
$response['message'] = $user_update_error;
|
|
$aio_wp_security->debug_logger->log_debug($user_update_error . ' ' . $wpdb->last_error, 4);
|
|
return $response;
|
|
}
|
|
|
|
// multisite considerations
|
|
if (is_multisite()) { // process sitemeta if we're in a multi-site situation
|
|
$oldAdmins = $wpdb->get_var("SELECT meta_value FROM `" . $wpdb->sitemeta . "` WHERE meta_key = 'site_admins'");
|
|
$newAdmins = str_replace('5:"admin"', strlen($new_username) . ':"' . esc_sql($new_username) . '"', $oldAdmins);
|
|
$wpdb->query("UPDATE `" . $wpdb->sitemeta . "` SET meta_value = '" . esc_sql($newAdmins) . "' WHERE meta_key = 'site_admins'");
|
|
}
|
|
|
|
// If user is logged in with username "admin" then log user out and send to login page so they can login again
|
|
if ($username_is_admin) {
|
|
// Lets logout the user
|
|
$aio_wp_security->debug_logger->log_debug("Logging user out with login ".$user_login. " because they changed their username.");
|
|
$after_logout_url = AIOWPSecurity_Utility::get_current_page_url();
|
|
$after_logout_payload = array('redirect_to' => $after_logout_url, 'msg' => $aio_wp_security->user_login_obj->key_login_msg.'=admin_user_changed');
|
|
//Save some of the logout redirect data to a transient
|
|
is_multisite() ? set_site_transient('aiowps_logout_payload', $after_logout_payload, 30 * 60) : set_transient('aiowps_logout_payload', $after_logout_payload, 30 * 60);
|
|
|
|
$logout_url = AIOWPSEC_WP_URL.'?aiowpsec_do_log_out=1';
|
|
$logout_url = AIOWPSecurity_Utility::add_query_data_to_url($logout_url, 'al_additional_data', '1');
|
|
|
|
$response['logout_user'] = true;
|
|
$response['logout_url'] = $logout_url;
|
|
}
|
|
}
|
|
} else { // An invalid username was entered
|
|
$error = __('You entered an invalid username, please enter another value.', 'all-in-one-wp-security-and-firewall');
|
|
}
|
|
} else { // No username value was entered
|
|
$response['status'] = 'error';
|
|
$error = __('Please enter a value for your username.', 'all-in-one-wp-security-and-firewall');
|
|
}
|
|
|
|
if (!empty($error)) { // We have some validation or other error
|
|
$response['message'] = $error;
|
|
} else {
|
|
$response['message'] = __('The username has been successfully changed.', 'all-in-one-wp-security-and-firewall');
|
|
$response['badges'] = $this->get_features_id_and_html(array('user-accounts-change-admin-user'));
|
|
$response['content']['change-admin-username-content'] = $aio_wp_security->include_template('wp-admin/user-security/partials/wp-username-content.php', true);
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Performs the action to save the login lockout settings.
|
|
*
|
|
* @param array $data An array containing the data to be saved.
|
|
*
|
|
* @return array|WP_Error Returns an array containing the status of the operation ('success' or 'error'),
|
|
* a message indicating the result of the operation,
|
|
* and a badge representing the updated feature details.
|
|
*/
|
|
public function perform_save_login_lockout_settings($data) {
|
|
$response = array(
|
|
'status' => 'success',
|
|
'values' => array(),
|
|
'info' => array()
|
|
);
|
|
|
|
$invalid_fields = array();
|
|
|
|
$max_login_attempt_val = sanitize_text_field($data['aiowps_max_login_attempts']);
|
|
if (!is_numeric($max_login_attempt_val) || 1 > $max_login_attempt_val) {
|
|
$invalid_fields[] = 'max login attempts';
|
|
$max_login_attempt_val = '3'; // Set it to the default value for this field
|
|
}
|
|
|
|
$login_retry_time_period = sanitize_text_field($data['aiowps_retry_time_period']);
|
|
if (!is_numeric($login_retry_time_period) || 1 > $login_retry_time_period) {
|
|
$invalid_fields[] = 'login retry time period';
|
|
$login_retry_time_period = '5'; // Set it to the default value for this field
|
|
}
|
|
|
|
$lockout_time_length = sanitize_text_field($data['aiowps_lockout_time_length']);
|
|
if (!is_numeric($lockout_time_length) || 1 > $lockout_time_length) {
|
|
$invalid_fields[] = 'minimum lockout time length';
|
|
$lockout_time_length = '5'; // Set it to the default value for this field
|
|
}
|
|
|
|
$max_lockout_time_length = sanitize_text_field($data['aiowps_max_lockout_time_length']);
|
|
if (!is_numeric($max_lockout_time_length) || 1 > $max_lockout_time_length) {
|
|
$invalid_fields[] = 'maximum lockout time length';
|
|
$max_lockout_time_length = '60'; // Set it to the default value for this field
|
|
}
|
|
|
|
if ($lockout_time_length >= $max_lockout_time_length) {
|
|
$invalid_fields[] = 'minimum lockout time length';
|
|
$lockout_time_length = '5'; // Set it to the default value for this field
|
|
$max_lockout_time_length = '60'; // Set it to the default value for this field
|
|
}
|
|
|
|
$email_addresses = isset($data['aiowps_email_address']) ? stripslashes($data['aiowps_email_address']) : get_bloginfo('admin_email');
|
|
$email_addresses_trimmed = AIOWPSecurity_Utility::explode_trim_filter_empty($email_addresses, "\n");
|
|
// Read into array, sanitize, filter empty and keep only unique usernames.
|
|
$email_address_list = array_unique(
|
|
array_filter(
|
|
array_map(
|
|
'sanitize_email',
|
|
$email_addresses_trimmed
|
|
),
|
|
'is_email'
|
|
)
|
|
);
|
|
|
|
if (isset($data['aiowps_enable_email_notify']) && 1 == $data['aiowps_enable_email_notify'] && 0 == count($email_addresses_trimmed)) {
|
|
$invalid_fields[] = 'email addresses';
|
|
} elseif (isset($data['aiowps_enable_email_notify']) && 1 == $data['aiowps_enable_email_notify'] && (0 == count($email_address_list) || count($email_address_list) != count($email_addresses_trimmed))) {
|
|
$invalid_fields[] = 'email addresses';
|
|
}
|
|
if (isset($data['aiowps_enable_email_notify']) && 0 == count($email_address_list)) {
|
|
$email_address_list[] = get_bloginfo('admin_email');
|
|
}
|
|
|
|
// Instantly lockout specific usernames
|
|
$instantly_lockout_specific_usernames = isset($data['aiowps_instantly_lockout_specific_usernames']) ? $data['aiowps_instantly_lockout_specific_usernames'] : '';
|
|
// Read into array, sanitize, filter empty and keep only unique usernames.
|
|
$instantly_lockout_specific_usernames = array_unique(
|
|
array_filter(
|
|
array_map(
|
|
'sanitize_user',
|
|
AIOWPSecurity_Utility::explode_trim_filter_empty($instantly_lockout_specific_usernames)
|
|
),
|
|
'strlen'
|
|
)
|
|
);
|
|
|
|
$response['message'] = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall');
|
|
|
|
if (!empty($invalid_fields)) {
|
|
$invalid_fields = array_unique($invalid_fields);
|
|
$invalid_fields = implode(", ", $invalid_fields);
|
|
$response['info'][] = sprintf(__('The following options had invalid values and have been set to the defaults: %s', 'all-in-one-wp-security-and-firewall'), $invalid_fields);
|
|
}
|
|
|
|
$options = array();
|
|
|
|
// Save all the form values to the options
|
|
$random_20_digit_string = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(20); // Generate random 20 char string for use during CAPTCHA encode/decode
|
|
$options['aiowps_unlock_request_secret_key'] = $random_20_digit_string;
|
|
|
|
$options['aiowps_enable_login_lockdown'] = isset($data["aiowps_enable_login_lockdown"]) ? '1' : '';
|
|
$options['aiowps_allow_unlock_requests'] = isset($data["aiowps_allow_unlock_requests"]) ? '1' : '';
|
|
$options['aiowps_max_login_attempts'] = absint($max_login_attempt_val);
|
|
$options['aiowps_retry_time_period'] = absint($login_retry_time_period);
|
|
$options['aiowps_lockout_time_length'] = absint($lockout_time_length);
|
|
$options['aiowps_max_lockout_time_length'] = absint($max_lockout_time_length);
|
|
$options['aiowps_set_generic_login_msg'] = isset($data["aiowps_set_generic_login_msg"]) ? '1' : '';
|
|
$options['aiowps_enable_invalid_username_lockdown']= isset($data["aiowps_enable_invalid_username_lockdown"]) ? '1' : '';
|
|
$options['aiowps_instantly_lockout_specific_usernames'] = $instantly_lockout_specific_usernames;
|
|
$options['aiowps_enable_email_notify'] = isset($data["aiowps_enable_email_notify"]) ? '1' : '';
|
|
$options['aiowps_enable_php_backtrace_in_email'] = isset($data['aiowps_enable_php_backtrace_in_email']) ? '1' : '';
|
|
$options['aiowps_email_address'] = $email_address_list;
|
|
$this->save_settings($options);
|
|
|
|
$response['values']['aiowps_max_login_attempts'] = absint($max_login_attempt_val);
|
|
$response['values']['aiowps_retry_time_period'] = absint($login_retry_time_period);
|
|
$response['values']['aiowps_lockout_time_length'] = absint($lockout_time_length);
|
|
$response['values']['aiowps_max_lockout_time_length'] = absint($max_lockout_time_length);
|
|
$response['values']['aiowps_email_address'] = implode("\n", $email_address_list);
|
|
|
|
$response['badges'] = $this->get_features_id_and_html(array('user-login-login-lockdown'));
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Performs the action to save the login lockout whitelist settings.
|
|
*
|
|
* @param array $data An array containing the data to be saved.
|
|
* The array may contain the following keys:
|
|
* - 'aiowps_lockdown_enable_whitelisting': A boolean indicating whether whitelisting is enabled.
|
|
* - 'aiowps_lockdown_allowed_ip_addresses': The allowed IP addresses for whitelisting.
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* a message indicating the result of the operation,
|
|
* and a badge representing the updated feature details.
|
|
*/
|
|
public function perform_save_login_lockout_whitelist_settings($data) {
|
|
global $aio_wp_security;
|
|
|
|
$response = array(
|
|
'status' => 'success'
|
|
);
|
|
|
|
$options = array();
|
|
$result = 1;
|
|
|
|
if (!empty($data['aiowps_lockdown_allowed_ip_addresses'])) {
|
|
$ip_addresses = sanitize_textarea_field(wp_unslash($data['aiowps_lockdown_allowed_ip_addresses']));
|
|
$ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($ip_addresses);
|
|
$validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'whitelist');
|
|
if (is_wp_error($validated_ip_list_array)) {
|
|
$result = -1;
|
|
$response['status'] = 'error';
|
|
$response['message'] = AIOWPSecurity_Admin_Menu::show_msg_error_st(nl2br($validated_ip_list_array->get_error_message()), true);
|
|
} else {
|
|
$allowed_ip_data = implode("\n", $validated_ip_list_array);
|
|
$options['aiowps_lockdown_allowed_ip_addresses'] = $allowed_ip_data;
|
|
}
|
|
} else {
|
|
$options['aiowps_lockdown_allowed_ip_addresses'] = ''; //Clear the IP address config value
|
|
}
|
|
|
|
if (1 == $result) {
|
|
$aio_wp_security->configs->set_value('aiowps_lockdown_enable_whitelisting', isset($data["aiowps_lockdown_enable_whitelisting"]) ? '1' : '', true);
|
|
$response['message'] = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall');
|
|
$response['badges'] = $this->get_features_id_and_html(array('user-login-lockout-ip-whitelisting'));
|
|
}
|
|
|
|
$this->save_settings($options);
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Performs the action to force logout users.
|
|
*
|
|
* @param array $data An array containing the data to be saved.
|
|
* The array may contain the following keys:
|
|
* - 'aiowps_logout_time_period': The time period (in minutes) for logout.
|
|
* - 'aiowps_enable_forced_logout': A boolean indicating whether forced logout is enabled.
|
|
* @return array|WP_Error Returns an array containing the status of the operation ('success' or 'error'),
|
|
* an array of messages indicating the result of the operation,
|
|
* the content representing the logout time period,
|
|
* and a badge representing the updated feature details.
|
|
*/
|
|
public function perform_force_logout($data) {
|
|
global $aio_wp_security;
|
|
|
|
if (AIOS_Helper::is_updraft_central_request()) {
|
|
if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
|
|
return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall'));
|
|
}
|
|
}
|
|
|
|
$response = array(
|
|
'status' => 'success',
|
|
'info' => array(),
|
|
'values' => array()
|
|
);
|
|
|
|
$options = array();
|
|
|
|
|
|
$logout_time_period = sanitize_text_field($data['aiowps_logout_time_period']);
|
|
if (isset($data["aiowps_enable_forced_logout"]) && (!is_numeric($logout_time_period) || $logout_time_period < 1)) {
|
|
$response['info'][] = __('You entered a non numeric or negative value for the logout time period field, it has been set to the default value.', 'all-in-one-wp-security-and-firewall');
|
|
$logout_time_period = '60'; // Set it to the default value for this field
|
|
}
|
|
|
|
// Save all the form values to the options
|
|
$options['aiowps_logout_time_period'] = absint($logout_time_period);
|
|
$options['aiowps_enable_forced_logout'] = isset($data["aiowps_enable_forced_logout"]) ? '1' : '';
|
|
$this->save_settings($options);
|
|
|
|
$response['values']['aiowps_logout_time_period'] = absint($logout_time_period);
|
|
$response['badges'] = $this->get_features_id_and_html(array('user-login-force-logout'));
|
|
$response['message'] = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall');
|
|
|
|
if ('1' === $options['aiowps_enable_forced_logout']) {
|
|
$response['logout_user'] = $this->check_logout_user();
|
|
$response['logout_url'] = $aio_wp_security->user_login_obj->aiowps_force_logout_action_handler(true);
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Performs the action to save the HIBP settings.
|
|
*
|
|
* @param array $data An array containing the data to be saved.
|
|
*
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* a message indicating the result of the operation,
|
|
* and a badge representing the updated feature details.
|
|
*/
|
|
public function perform_save_hibp_settings($data) {
|
|
global $aio_wp_security;
|
|
|
|
$aio_wp_security->configs->set_value('aiowps_hibp_user_profile_update', isset($data['aiowps_hibp_user_profile_update']) ? '1' : '', true);
|
|
$aio_wp_security->configs->set_value('aiowps_http_password_reset', isset($data['aiowps_http_password_reset']) ? '1' : '', true);
|
|
$aio_wp_security->configs->save_config();
|
|
|
|
return $this->handle_response(true, false, array('badges' => array('hibp')));
|
|
}
|
|
|
|
/**
|
|
* Performs the action to disable application password.
|
|
*
|
|
* @param array $data An array containing the data to be saved.
|
|
* The array may contain the following key:
|
|
* - 'aiowps_disable_application_password': A boolean indicating whether application password is disabled.
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* a message indicating the result of the operation,
|
|
* and a badge representing the updated feature details.
|
|
*/
|
|
public function perform_disable_application_password($data) {
|
|
global $aio_wp_security;
|
|
|
|
// Save all the form values to the options
|
|
$aio_wp_security->configs->set_value('aiowps_disable_application_password', isset($data['aiowps_disable_application_password']) ? '1' : '', true);
|
|
|
|
return array(
|
|
'status' => 'success',
|
|
'message' => __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'),
|
|
'badges' => $this->get_features_id_and_html(array('disable-application-password'))
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Performs the action to add salt postfix.
|
|
*
|
|
* @param array $data An array containing the data to be saved.
|
|
* The array may contain the following key:
|
|
* - 'aiowps_enable_salt_postfix': A boolean indicating whether salt postfix is enabled.
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* a message indicating the result of the operation,
|
|
* and a badge representing the updated feature details.
|
|
*/
|
|
public function perform_add_salt_postfix($data) {
|
|
global $aio_wp_security;
|
|
|
|
$response = array(
|
|
'status' => 'success'
|
|
);
|
|
|
|
// Save settings
|
|
$aiowps_enable_salt_postfix = isset($data['aiowps_enable_salt_postfix']) ? '1' : '';
|
|
if ($aiowps_enable_salt_postfix == $aio_wp_security->configs->get_value('aiowps_enable_salt_postfix')) {
|
|
$is_setting_changed = true;
|
|
} else {
|
|
$is_setting_changed = false;
|
|
}
|
|
|
|
$aio_wp_security->configs->set_value('aiowps_enable_salt_postfix', $aiowps_enable_salt_postfix, true);
|
|
$ret_schedule = $this->schedule_change_auth_keys_and_salt();
|
|
|
|
if (is_wp_error($ret_schedule)) {
|
|
$aio_wp_security->debug_logger->log_debug($ret_schedule->get_error_message(), 4);
|
|
}
|
|
|
|
if ('1' == $aiowps_enable_salt_postfix && $is_setting_changed) {
|
|
AIOWPSecurity_Utility::change_salt_postfixes();
|
|
}
|
|
|
|
$response['message'] = __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall');
|
|
$response['badges'] = $this->get_features_id_and_html(array('enable-salt-postfix'));
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Performs actions on logged-in users.
|
|
*
|
|
* @param array $data An array containing the data for the action to be performed.
|
|
* The array may contain the following keys:
|
|
* - 'action': The action to be performed on logged-in users (e.g., 'force_user_logout').
|
|
* - 'logged_in_id': The ID of the logged-in user on which the action will be performed.
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* and a message indicating the result of the operation.
|
|
*/
|
|
public function perform_logged_in_user_action($data) {
|
|
global $aio_wp_security;
|
|
|
|
/* UDC will error out without this */
|
|
if (AIOS_Helper::is_updraft_central_request()) {
|
|
$this->init_wp_list();
|
|
}
|
|
|
|
include_once AIO_WP_SECURITY_PATH.'/admin/wp-security-list-logged-in-users.php'; // For rendering the AIOWPSecurity_List_Table
|
|
$user_list = new AIOWPSecurity_List_Logged_In_Users();
|
|
$response = array(
|
|
'status' => 'success'
|
|
);
|
|
|
|
if (empty($data['action']) || !in_array($data['action'], array('force_user_logout'))) { // more actions can be added
|
|
return array(
|
|
'status' => 'error',
|
|
'message' => __('Invalid action provided for logged in user.', 'all-in-one-wp-security-and-firewall')
|
|
);
|
|
}
|
|
|
|
if ('force_user_logout' == $data['action']) {
|
|
if (empty($data['logged_in_id'])) {
|
|
return array(
|
|
'status' => 'error',
|
|
'message' => __('No user ID was provided', 'all-in-one-wp-security-and-firewall')
|
|
);
|
|
}
|
|
$user_id = strip_tags($data['logged_in_id']);
|
|
$error = '';
|
|
|
|
if (!is_numeric($user_id)) {
|
|
$error = __("Invalid user ID provided.", 'all-in-one-wp-security-and-firewall');
|
|
} elseif (get_current_user_id() == $user_id) {
|
|
$error = __("You cannot log yourself out", 'all-in-one-wp-security-and-firewall');
|
|
} elseif (is_super_admin($user_id)) {
|
|
$error = __("Super admins cannot be logged out.", 'all-in-one-wp-security-and-firewall');
|
|
} elseif (!AIOWPSecurity_Utility::is_user_member_of_blog($user_id)) {
|
|
$error = __("You cannot log out a user from a different subsite.", 'all-in-one-wp-security-and-firewall');
|
|
}
|
|
if ($error) {
|
|
return array(
|
|
'message' => $error,
|
|
'status' => 'error'
|
|
);
|
|
}
|
|
|
|
$user_id = esc_sql($user_id);
|
|
$result = $aio_wp_security->user_login_obj->delete_logged_in_user($user_id);
|
|
|
|
if ($result) {
|
|
$user_list->logout_user($user_id);
|
|
$response['message'] = __('The selected user has been logged out successfully.', 'all-in-one-wp-security-and-firewall');
|
|
} else {
|
|
$response['message'] = __('Failed to log out the selected user.', 'all-in-one-wp-security-and-firewall');
|
|
$response['status'] = 'error';
|
|
}
|
|
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Performs the action to configure manual registration approval settings.
|
|
*
|
|
* @param array $data An array containing the data to be saved.
|
|
* The array may contain the following key:
|
|
* - 'aiowps_enable_manual_registration_approval': A boolean indicating whether manual registration approval is enabled.
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* a message indicating the result of the operation,
|
|
* and a badge representing the updated feature details.
|
|
*/
|
|
public function perform_manual_approval_settings($data) {
|
|
global $aio_wp_security;
|
|
|
|
// Save settings
|
|
$aio_wp_security->configs->set_value('aiowps_enable_manual_registration_approval', isset($data["aiowps_enable_manual_registration_approval"]) ? '1' : '', true);
|
|
|
|
return array(
|
|
'status' => 'success',
|
|
'message' => __('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall'),
|
|
'badges' => $this->get_features_id_and_html(array('manually-approve-registrations'))
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Performs actions on manual approval items (e.g., approve account, delete account, block IP).
|
|
*
|
|
* @param array $data An array containing the data for the action to be performed.
|
|
* The array may contain the following keys:
|
|
* - 'action': The action to be performed on the manual approval item (e.g., 'approve_acct', 'delete_acct', 'block_ip').
|
|
* - 'user_id': The ID of the user for whom the action will be performed (applicable for 'approve_acct' and 'delete_acct' actions).
|
|
* - 'ip_address': The IP address to be blocked (applicable for 'block_ip' action).
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* and a message indicating the result of the operation.
|
|
*/
|
|
public function perform_manual_approval_item_action($data) {
|
|
global $aio_wp_security;
|
|
|
|
include_once AIO_WP_SECURITY_PATH.'/admin/wp-security-list-registered-users.php'; // For rendering the AIOWPSecurity_List_Table
|
|
$user_list = new AIOWPSecurity_List_Registered_Users();
|
|
$status = 'error';
|
|
|
|
$valid_actions = array('approve_acct', 'delete_acct', 'block_ip');
|
|
if (empty($data['action']) || !in_array($data['action'], $valid_actions)) { // more actions can be added
|
|
return array(
|
|
'status' => 'error',
|
|
'message' => __('Invalid action provided for registered user.', 'all-in-one-wp-security-and-firewall')
|
|
);
|
|
}
|
|
|
|
switch ($data['action']) {
|
|
case 'approve_acct':
|
|
if (empty($data['user_id'])) {
|
|
return array(
|
|
'status' => 'error',
|
|
'message' => __('No valid user ID was provided', 'all-in-one-wp-security-and-firewall')
|
|
);
|
|
}
|
|
$user_id = esc_sql(strip_tags($data['user_id']));
|
|
$meta_key = 'aiowps_account_status';
|
|
$meta_value = 'approved'; // set account status
|
|
|
|
// Approve single account
|
|
$result = update_user_meta($user_id, $meta_key, $meta_value);
|
|
if ($result) {
|
|
$user = get_user_by('id', $user_id);
|
|
$user_list->send_email_upon_account_activation($user);
|
|
$message = __('The selected account was approved successfully.', 'all-in-one-wp-security-and-firewall');
|
|
$status = 'success';
|
|
} elseif (false === $result) {
|
|
$aio_wp_security->debug_logger->log_debug("could not approve account ID: $user_id", 4);
|
|
$message = __('The selected account could not be approved.', 'all-in-one-wp-security-and-firewall');
|
|
}
|
|
break;
|
|
case 'delete_acct':
|
|
if (empty($data['user_id'])) {
|
|
return array(
|
|
'status' => 'error',
|
|
'message' => __('No valid user ID was provided', 'all-in-one-wp-security-and-firewall')
|
|
);
|
|
}
|
|
|
|
$user_id = esc_sql(strip_tags($data['user_id']));
|
|
// Delete single account
|
|
$result = wp_delete_user($user_id);
|
|
if (true === $result) {
|
|
$message = __('The selected account was deleted successfully.', 'all-in-one-wp-security-and-firewall');
|
|
$status = 'success';
|
|
} else {
|
|
$aio_wp_security->debug_logger->log_debug("could not delete account ID: $user_id", 4);
|
|
$message = __('The selected account could not be deleted.', 'all-in-one-wp-security-and-firewall');
|
|
}
|
|
break;
|
|
case 'block_ip':
|
|
if (empty($data['ip_address'])) {
|
|
return array(
|
|
'status' => 'error',
|
|
'message' => __('No valid IP address was provided', 'all-in-one-wp-security-and-firewall')
|
|
);
|
|
}
|
|
|
|
$ip = esc_sql(strip_tags($data['ip_address']));
|
|
|
|
if (AIOWPSecurity_Utility_IP::get_user_ip_address() == $ip) {
|
|
$message = __('You cannot block your own IP address:', 'all-in-one-wp-security-and-firewall') . ' ' . $ip;
|
|
break;
|
|
}
|
|
|
|
// Block single IP
|
|
$result = AIOWPSecurity_Blocking::add_ip_to_block_list($ip, 'registration_spam');
|
|
if (true === $result) {
|
|
$message = __('The selected IP was successfully added to the permanent block list.', 'all-in-one-wp-security-and-firewall');
|
|
$message .= ' <a href="admin.php?page='.AIOWPSEC_MAIN_MENU_SLUG.'&tab=permanent-block" target="_blank">'.__('View Blocked IPs', 'all-in-one-wp-security-and-firewall').'</a>';
|
|
$status = 'success';
|
|
} else {
|
|
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::block_selected_ips() - could not block IP: $ip", 4);
|
|
$message = __('The selected IP could not be added to the permanent block list.', 'all-in-one-wp-security-and-firewall');
|
|
}
|
|
break;
|
|
}
|
|
|
|
return array(
|
|
'status' => $status,
|
|
'message' => $message
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Schedule weekly aios_change_auth_keys_and_salt cron event.
|
|
*
|
|
* @return Boolean|WP_Error True if event successfully scheduled. False or WP_Error on failure.
|
|
*/
|
|
private function schedule_change_auth_keys_and_salt() {
|
|
$previous_time = wp_next_scheduled('aios_change_auth_keys_and_salt');
|
|
|
|
if (false !== $previous_time) {
|
|
// Clear schedule so that we don't stack up scheduled backups
|
|
wp_clear_scheduled_hook('aios_change_auth_keys_and_salt');
|
|
}
|
|
$gmt_offset_in_seconds = floatval(get_option('gmt_offset')) * 3600;
|
|
$first_time = strtotime('next Sunday '.apply_filters('aios_salt_change_schedule_time', '3:00 am')) + $gmt_offset_in_seconds;
|
|
return wp_schedule_event($first_time, 'weekly', 'aios_change_auth_keys_and_salt');
|
|
}
|
|
|
|
/**
|
|
* Checks if the current user should be automatically logged out based on last login time.
|
|
*
|
|
* This method compares the current time with the last login time of the user and determines
|
|
* if the user should be logged out based on a configured logout time period.
|
|
*
|
|
* @return bool Returns true if the user should be logged out, false otherwise.
|
|
*/
|
|
private function check_logout_user() {
|
|
global $aio_wp_security;
|
|
|
|
// Get the current user
|
|
$current_user = wp_get_current_user();
|
|
$user_id = $current_user->ID;
|
|
|
|
// Get the current and last login times
|
|
$current_time = current_time('mysql', true);
|
|
$login_time = $aio_wp_security->user_login_obj->get_wp_user_aiowps_last_login_time($user_id);
|
|
|
|
// Return false if login time is empty (no last login recorded)
|
|
if (empty($login_time)) {
|
|
return false;
|
|
}
|
|
|
|
// Calculate the time difference between current time and last login time
|
|
$diff = strtotime($current_time) - strtotime($login_time);
|
|
|
|
// Get the configured logout time period in seconds
|
|
$logout_time_interval_value = $aio_wp_security->configs->get_value('aiowps_logout_time_period');
|
|
$logout_time_interval_val_seconds = $logout_time_interval_value * 60;
|
|
|
|
// Return true if the time difference exceeds the logout time interval, indicating the user should be logged out
|
|
return $diff > $logout_time_interval_val_seconds;
|
|
}
|
|
|
|
/**
|
|
* Saves all the login lockout settings from UDC.
|
|
*
|
|
* @param array $data An array containing the data to be saved.
|
|
* The array may contain the following keys:
|
|
* - 'aiowps_enable_login_lockdown': A boolean indicating whether login lockdown is enabled.
|
|
* - 'aiowps_allow_unlock_requests': A boolean indicating whether unlock requests are allowed.
|
|
* - 'aiowps_max_login_attempts': The maximum number of login attempts allowed before lockout.
|
|
* - 'aiowps_retry_time_period': The time period (in minutes) after which the user is allowed to retry login.
|
|
* - 'aiowps_lockout_time_length': The time period (in minutes) during which the user is locked out after the maximum number of login attempts is reached.
|
|
* - 'aiowps_lockout_message': The message to be displayed to the user when they are locked out.
|
|
* - 'aiowps_lockout_redirect_url': The URL to redirect the user to after lockout.
|
|
* - 'aiowps_lockout_redirect_url_text': The text to be displayed on the redirect URL textbox.
|
|
*
|
|
* @return array|WP_Error
|
|
*/
|
|
public function perform_login_lockout_save_settings($data) {
|
|
if (AIOS_Helper::is_updraft_central_request()) {
|
|
if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
|
|
return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall'));
|
|
}
|
|
}
|
|
|
|
/* Required or UDC will error out. */
|
|
include_once(AIO_WP_SECURITY_PATH . '/admin/wp-security-admin-menu.php');
|
|
|
|
$response = $this->perform_save_login_lockout_whitelist_settings($data);
|
|
|
|
if ('error' === $response['status']) {
|
|
return $response;
|
|
}
|
|
|
|
return $this->perform_save_login_lockout_settings($data);
|
|
}
|
|
|
|
/**
|
|
* Return user security data.
|
|
*
|
|
* @return array Array of option values,
|
|
*/
|
|
public function get_user_security_data() {
|
|
global $aio_wp_security;
|
|
|
|
/* Login lockout */
|
|
$aiowps_enable_login_lockdown = $aio_wp_security->configs->get_value('aiowps_enable_login_lockdown');
|
|
$aiowps_allow_unlock_requests = $aio_wp_security->configs->get_value('aiowps_allow_unlock_requests');
|
|
$aiowps_max_login_attempts = $aio_wp_security->configs->get_value('aiowps_max_login_attempts');
|
|
$aiowps_retry_time_period = $aio_wp_security->configs->get_value('aiowps_retry_time_period');
|
|
$aiowps_lockout_time_length = $aio_wp_security->configs->get_value('aiowps_lockout_time_length');
|
|
$aiowps_max_lockout_time_length = $aio_wp_security->configs->get_value('aiowps_max_lockout_time_length');
|
|
$aiowps_set_generic_login_msg = $aio_wp_security->configs->get_value('aiowps_set_generic_login_msg');
|
|
$aiowps_enable_invalid_username_lockdown = $aio_wp_security->configs->get_value('aiowps_enable_invalid_username_lockdown');
|
|
$aiowps_instantly_lockout_specific_usernames = $aio_wp_security->configs->get_value('aiowps_instantly_lockout_specific_usernames');
|
|
$aiowps_enable_email_notify = $aio_wp_security->configs->get_value('aiowps_enable_email_notify');
|
|
$aiowps_email_address = $aio_wp_security->configs->get_value('aiowps_email_address');
|
|
$aiowps_enable_php_backtrace_in_email = $aio_wp_security->configs->get_value('aiowps_enable_php_backtrace_in_email');
|
|
$aiowps_lockdown_enable_whitelisting = $aio_wp_security->configs->get_value('aiowps_lockdown_enable_whitelisting');
|
|
$aiowps_lockdown_allowed_ip_addresses = $aio_wp_security->configs->get_value('aiowps_lockdown_allowed_ip_addresses');
|
|
|
|
/* Force logout */
|
|
$aiowps_enable_forced_logout = $aio_wp_security->configs->get_value('aiowps_enable_forced_logout');
|
|
$aiowps_logout_time_period = $aio_wp_security->configs->get_value('aiowps_logout_time_period');
|
|
|
|
return array(
|
|
'aiowps_enable_login_lockdown' => $aiowps_enable_login_lockdown,
|
|
'aiowps_allow_unlock_requests'=> $aiowps_allow_unlock_requests,
|
|
'aiowps_max_login_attempts' => $aiowps_max_login_attempts,
|
|
'aiowps_retry_time_period' => $aiowps_retry_time_period,
|
|
'aiowps_lockout_time_length' => $aiowps_lockout_time_length,
|
|
'aiowps_max_lockout_time_length' => $aiowps_max_lockout_time_length,
|
|
'aiowps_set_generic_login_msg' => $aiowps_set_generic_login_msg,
|
|
'aiowps_enable_invalid_username_lockdown' => $aiowps_enable_invalid_username_lockdown,
|
|
'aiowps_instantly_lockout_specific_usernames' => $aiowps_instantly_lockout_specific_usernames,
|
|
'aiowps_enable_email_notify' => $aiowps_enable_email_notify,
|
|
'aiowps_email_address' => AIOWPSecurity_Utility::get_textarea_str_val($aiowps_email_address),
|
|
'aiowps_enable_php_backtrace_in_email' => $aiowps_enable_php_backtrace_in_email,
|
|
'aiowps_lockdown_enable_whitelisting' => $aiowps_lockdown_enable_whitelisting,
|
|
'aiowps_lockdown_allowed_ip_addresses' => $aiowps_lockdown_allowed_ip_addresses,
|
|
'aiowps_enable_forced_logout' => $aiowps_enable_forced_logout,
|
|
'aiowps_logout_time_period' => $aiowps_logout_time_period,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Return logged-in user data.
|
|
*
|
|
* @return array Array of option values,
|
|
*/
|
|
public function get_logged_in_users_data() {
|
|
/* UDC will error out without this */
|
|
if (AIOS_Helper::is_updraft_central_request()) {
|
|
$this->init_wp_list();
|
|
}
|
|
|
|
include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-list-logged-in-users.php';
|
|
|
|
$user_list = new AIOWPSecurity_List_Logged_In_Users();
|
|
$user_list->prepare_items();
|
|
|
|
$column_list = array();
|
|
|
|
foreach ($user_list->get_columns() as $column => $value) {
|
|
if (!empty($column)) {
|
|
if ('cb' !== $column) {
|
|
$column_list[$column] = array('label' => $value);
|
|
}
|
|
}
|
|
}
|
|
|
|
return array(
|
|
'logged_in_user_data' => array(
|
|
'users' => $user_list->items,
|
|
'columns' => $column_list,
|
|
'bulk_actions' => $user_list->get_bulk_actions(),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Whitelists user's IP address
|
|
*
|
|
* @return array Returns an array containing the status of the operation ('success' or 'error'),
|
|
* a message indicating the result of the operation,
|
|
* and a badge representing the updated feature details.
|
|
*/
|
|
public function perform_whitelist_user_ip() {
|
|
$response = array(
|
|
'status' => 'success'
|
|
);
|
|
|
|
if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
|
|
$response['status'] = 'error';
|
|
$response['message'] = __('You don\'t have enough permissions to whitelist your IP address.', 'all-in-one-wp-security-and-firewall');
|
|
return $response;
|
|
}
|
|
|
|
$aiowps_firewall_allow_list = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::ALLOW_LIST);
|
|
|
|
$whitelisted_ips = $aiowps_firewall_allow_list::get_ips();
|
|
$is_whitelisted = $aiowps_firewall_allow_list::is_ip_allowed();
|
|
|
|
if ($is_whitelisted) {
|
|
$response['status'] = 'error';
|
|
$response['message'] = __('Your IP address is already whitelisted.', 'all-in-one-wp-security-and-firewall');
|
|
return $response;
|
|
} else {
|
|
$user_ip = AIOWPSecurity_Utility_IP::get_user_ip_address();
|
|
|
|
if (empty($user_ip)) {
|
|
$response['status'] = 'error';
|
|
$response['message'] = __('Your IP address could not be detected.', 'all-in-one-wp-security-and-firewall');
|
|
return $response;
|
|
}
|
|
|
|
$whitelisted_ips .= (empty($whitelisted_ips) ? '' : "\n") . $user_ip;
|
|
|
|
if (!$aiowps_firewall_allow_list::add_ips($whitelisted_ips)) {
|
|
$response['status'] = 'error';
|
|
$response['message'] = __('There was an error whitelisting your IP address, please try again.', 'all-in-one-wp-security-and-firewall');
|
|
return $response;
|
|
}
|
|
|
|
$response['message'] = __('Your IP address has been whitelisted successfully.', 'all-in-one-wp-security-and-firewall');
|
|
return $response;
|
|
}
|
|
}
|
|
}
|