Phase 6: AIOS security plugin with conservative login lockdown config (10 attempts)
This commit is contained in:
wp-content/plugins/all-in-one-wp-security-and-firewall/admin/general/wp-security-ajax-data-table.php
Executable
+1486
File diff suppressed because it is too large
Load Diff
Executable
+1451
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
/**
|
||||
* Do not modify the files in this folder.
|
||||
*/
|
||||
+626
@@ -0,0 +1,626 @@
|
||||
<?php
|
||||
/**
|
||||
* Inits the admin dashboard side of things.
|
||||
* Main admin file which loads all settings panels and sets up admin menus.
|
||||
*/
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Admin_Init {
|
||||
|
||||
/**
|
||||
* Whether the page is admin dashboard page.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $is_admin_dashboard_page;
|
||||
|
||||
/**
|
||||
* Whether the page is admin AIOS page.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $is_aiowps_admin_page;
|
||||
|
||||
/**
|
||||
* An array of submenu items
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $menu_items = array();
|
||||
|
||||
/**
|
||||
* Used in the premium plugin to add submenus
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $main_menu_page;
|
||||
|
||||
/**
|
||||
* Includes admin dependencies and hook admin actions.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct() {
|
||||
// This class is only initialized if is_admin() is true
|
||||
|
||||
if (AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
|
||||
$this->admin_includes();
|
||||
add_action('admin_menu', array($this, 'setup_menu_items'));
|
||||
add_action('admin_menu', array($this, 'create_admin_menus'));
|
||||
add_action('admin_menu', array($this, 'premium_upgrade_submenu'), 40);
|
||||
add_action('admin_init', array($this, 'aiowps_csv_download'));
|
||||
}
|
||||
|
||||
add_action('admin_init', array($this, 'hook_admin_notices'));
|
||||
|
||||
// Make sure we are on our plugin's menu pages
|
||||
if ($this->is_aiowps_admin_page()) {
|
||||
add_action('admin_print_scripts', array($this, 'admin_menu_page_scripts'));
|
||||
add_action('admin_print_styles', array($this, 'admin_menu_page_styles'));
|
||||
add_action('init', array($this, 'init_hook_handler_for_admin_side'));
|
||||
|
||||
if (class_exists('AIOWPS_PREMIUM')) {
|
||||
add_filter('admin_footer_text', array($this, 'display_footer_review_message'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the menu items array which is used to build admin menus
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_menu_items() {
|
||||
$menu_items = array(
|
||||
array(
|
||||
'page_title' => __('Dashboard', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('Dashboard', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_MAIN_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_dashboard_menu_rendering'),
|
||||
'icon' => 'dashboard',
|
||||
'order' => 20,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('Settings', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('Settings', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_SETTINGS_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_settings_menu_rendering'),
|
||||
'icon' => 'settings',
|
||||
'order' => 30,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('User Security', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('User Security', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_USER_SECURITY_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_user_security_menu_rendering'),
|
||||
'icon' => 'user_security',
|
||||
'order' => 40,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('Database Security', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('Database Security', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_DB_SEC_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_database_menu_rendering'),
|
||||
'icon' => 'database_security',
|
||||
'display_condition_callback' => 'is_super_admin',
|
||||
'order' => 50,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('File Security', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('File Security', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_FILESYSTEM_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_filesystem_menu_rendering'),
|
||||
'icon' => 'filesystem_security',
|
||||
'order' => 60,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('Firewall', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('Firewall', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_FIREWALL_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_firewall_menu_rendering'),
|
||||
'icon' => 'firewall',
|
||||
'order' => 70,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('Brute Force', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('Brute Force', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_BRUTE_FORCE_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_brute_force_menu_rendering'),
|
||||
'icon' => 'brute_force',
|
||||
'order' => 80,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('Spam Prevention', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('Spam Prevention', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_SPAM_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_spam_menu_rendering'),
|
||||
'icon' => 'spam_prevention',
|
||||
'order' => 90,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('Scanner', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('Scanner', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_FILESCAN_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_filescan_menu_rendering'),
|
||||
'icon' => 'scanner',
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
'order' => 100,
|
||||
),
|
||||
array(
|
||||
'page_title' => __('Tools', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_title' => __('Tools', 'all-in-one-wp-security-and-firewall'),
|
||||
'menu_slug' => AIOWPSEC_TOOLS_MENU_SLUG,
|
||||
'render_callback' => array($this, 'handle_tools_menu_rendering'),
|
||||
'icon' => 'tools',
|
||||
'order' => 110,
|
||||
),
|
||||
);
|
||||
$menu_items = apply_filters('aiowpsecurity_menu_items', $menu_items);
|
||||
$this->menu_items = array_filter($menu_items, 'AIOWPSecurity_Utility::should_display_item');
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the menu items array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_menu_items() {
|
||||
return $this->menu_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function creates and outputs the csv file for download
|
||||
*
|
||||
* @param array $items - the content
|
||||
* @param array $export_keys - the keys for the content
|
||||
* @param string $filename - the filename
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function aiowps_output_csv($items, $export_keys, $filename = 'data.csv') {
|
||||
header("Content-Type: text/csv; charset=utf-8");
|
||||
header("Content-Disposition: attachment; filename=".$filename);
|
||||
header("Pragma: no-cache");
|
||||
header("Expires: 0");
|
||||
$output = fopen('php://output', 'w'); //open output stream
|
||||
|
||||
fputcsv($output, $export_keys, ',', '"', '\\'); // let's put column names first
|
||||
|
||||
foreach ($items as $item) {
|
||||
$csv_line = array();
|
||||
|
||||
foreach ($export_keys as $key => $value) {
|
||||
if (isset($item[$key])) {
|
||||
$csv_line[] = ('created' == $key) ? AIOWPSecurity_Utility::convert_timestamp($item[$key]) : $item[$key];
|
||||
}
|
||||
}
|
||||
fputcsv($output, $csv_line, ',', '"', '\\');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the content that we want to export as CSV and send it to the download function
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function aiowps_csv_download() {
|
||||
global $aio_wp_security;
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. Nonce check in two lines.
|
||||
if (isset($_POST['aiowps_export_404_event_logs_to_csv'])) {//Export 404 event logs
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It IS the nonce, so...
|
||||
$nonce = isset($_REQUEST['_wpnonce']) ? sanitize_key(wp_unslash($_REQUEST['_wpnonce'])) : '';
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-export-404-event-logs-to-csv-nonce');
|
||||
if (is_wp_error($result)) {
|
||||
$aio_wp_security->debug_logger->log_debug($result->get_error_message(), 4);
|
||||
die(esc_html($result->get_error_message()));
|
||||
}
|
||||
include_once 'wp-security-list-404.php'; //For rendering the AIOWPSecurity_List_Table in tab1
|
||||
$event_list_404 = new AIOWPSecurity_List_404(); //For rendering the AIOWPSecurity_List_Table in tab1
|
||||
$event_list_404->prepare_items(true);
|
||||
$export_keys = array(
|
||||
'id' => __('Id', 'all-in-one-wp-security-and-firewall'),
|
||||
'event_type' => __('Event Type', 'all-in-one-wp-security-and-firewall'),
|
||||
'ip_or_host' => __('IP Address', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => __('Attempted URL', 'all-in-one-wp-security-and-firewall'),
|
||||
'referer_info' => __('Referer', 'all-in-one-wp-security-and-firewall'),
|
||||
'created' => __('Date and time', 'all-in-one-wp-security-and-firewall'),
|
||||
'status' => __('Lock Status', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
AIOWPSecurity_Utility::output_csv($event_list_404->items, $export_keys, '404_event_logs.csv');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether current admin page is All In One WP Security admin page or not.
|
||||
*
|
||||
* @return boolean True if All In One WP Security admin page, Otherwise false.
|
||||
*/
|
||||
private function is_aiowps_admin_page() {
|
||||
if (isset($this->is_aiowps_admin_page)) {
|
||||
return $this->is_aiowps_admin_page;
|
||||
}
|
||||
global $pagenow;
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce on this _GET.
|
||||
$this->is_aiowps_admin_page = (AIOWPSecurity_Utility_Permissions::has_manage_cap() && 'admin.php' == $pagenow && isset($_GET['page']) && false !== strpos(sanitize_title(wp_unslash($_GET['page'])), AIOWPSEC_MENU_SLUG_PREFIX));
|
||||
return $this->is_aiowps_admin_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook admin notices on admin dashboard page and admin AIOS pages.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hook_admin_notices() {
|
||||
if (!current_user_can('update_plugins')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If none of the admin dashboard page or the AIOS page, Then bail
|
||||
if (!$this->is_admin_dashboard_page() && !$this->is_aiowps_admin_page()) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action('all_admin_notices', array($this, 'render_admin_notices'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether current admin page is Admin Dashboard page or not.
|
||||
*
|
||||
* @return boolean True if Admin Dashboard page, Otherwise false.
|
||||
*/
|
||||
private function is_admin_dashboard_page() {
|
||||
if (isset($this->is_admin_dashboard_page)) {
|
||||
return $this->is_admin_dashboard_page;
|
||||
}
|
||||
global $pagenow;
|
||||
$this->is_admin_dashboard_page = 'index.php' == $pagenow;
|
||||
return $this->is_admin_dashboard_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render admin notices.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_admin_notices() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$custom_notice_ids = array_merge(AIOS_Abstracted_Ids::custom_admin_notice_ids(), AIOS_Abstracted_Ids::htaccess_to_php_feature_notice_ids());
|
||||
foreach ($custom_notice_ids as $custom_admin_notice_id) {
|
||||
$aio_wp_security->notices->do_notice($custom_admin_notice_id, $custom_admin_notice_id);
|
||||
}
|
||||
|
||||
// Bail if the premium plugin is active and does not show ads.
|
||||
if (AIOWPSecurity_Utility_Permissions::is_premium_installed()) return;
|
||||
|
||||
$installed_at = $aio_wp_security->notices->get_aiowps_plugin_installed_timestamp();
|
||||
$time_now = $aio_wp_security->notices->get_time_now();
|
||||
$installed_for = $time_now - $installed_at;
|
||||
|
||||
$dismissed_dash_notice_until = (int) $aio_wp_security->configs->get_value('dismissdashnotice');
|
||||
|
||||
if ($this->is_admin_dashboard_page() && ($installed_at && $time_now > $dismissed_dash_notice_until && $installed_for > (14 * 86400)) || (defined('AIOWPSECURITY_FORCE_DASHNOTICE') && AIOWPSECURITY_FORCE_DASHNOTICE)) {
|
||||
$aio_wp_security->include_template('notices/thanks-for-using-main-dash.php');
|
||||
} elseif ($this->is_aiowps_admin_page() && $installed_at && $installed_for > 14*86400) {
|
||||
$aio_wp_security->notices->do_notice(false, 'top');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will include any files needed for the admin dashboard
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function admin_includes() {
|
||||
include_once('wp-security-admin-menu.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin JavaScripts.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function admin_menu_page_scripts() {
|
||||
if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_script('jquery');
|
||||
wp_enqueue_script('postbox');
|
||||
wp_enqueue_script('dashboard');
|
||||
wp_enqueue_script('thickbox');
|
||||
wp_enqueue_script('media-upload');
|
||||
wp_enqueue_script('chart-bundle', AIO_WP_SECURITY_URL . '/includes/chartjs/Chart.bundle.min.js', array(), AIO_WP_SECURITY_VERSION, true);
|
||||
wp_enqueue_script('chartjs-gauge', AIO_WP_SECURITY_URL . '/includes/chartjs/chartjs-gauge.min.js', array(), AIO_WP_SECURITY_VERSION, true);
|
||||
wp_register_script('jquery-blockui', AIO_WP_SECURITY_URL.'/includes/blockui/jquery.blockUI.js', array('jquery'), AIO_WP_SECURITY_VERSION, true);
|
||||
wp_enqueue_script('jquery-blockui');
|
||||
wp_register_script('aiowpsec-admin-js', AIO_WP_SECURITY_URL. '/js/wp-security-admin-script.js', array('jquery'), AIO_WP_SECURITY_VERSION, true);
|
||||
wp_enqueue_script('aiowpsec-admin-js');
|
||||
wp_localize_script('aiowpsec-admin-js',
|
||||
'aios_data',
|
||||
array(
|
||||
'ajax_nonce' => wp_create_nonce('wp-security-ajax-nonce'),
|
||||
)
|
||||
);
|
||||
wp_localize_script('aiowpsec-admin-js',
|
||||
'aios_trans',
|
||||
array(
|
||||
'unexpected_response' => __('Unexpected response:', 'all-in-one-wp-security-and-firewall'),
|
||||
'copied' => __('Copied', 'all-in-one-wp-security-and-firewall'),
|
||||
'no_import_file' => __('You have not yet selected a file to import.', 'all-in-one-wp-security-and-firewall'),
|
||||
'processing' => __('Processing...', 'all-in-one-wp-security-and-firewall'),
|
||||
'invalid_domain' => __('Please enter a valid IP address or domain name.', 'all-in-one-wp-security-and-firewall'),
|
||||
'logo' => AIO_WP_SECURITY_URL.'/images/plugin-logos/icon-aios-rgb.svg',
|
||||
'saving' => __('Saving...', 'all-in-one-wp-security-and-firewall'),
|
||||
'deleting' => __('Deleting...', 'all-in-one-wp-security-and-firewall'),
|
||||
'blocking' => __('Blocking...', 'all-in-one-wp-security-and-firewall'),
|
||||
'unlocking' => __('Unlocking...', 'all-in-one-wp-security-and-firewall'),
|
||||
'clearing' => __('Clearing...', 'all-in-one-wp-security-and-firewall'),
|
||||
'importing' => __('Importing...', 'all-in-one-wp-security-and-firewall'),
|
||||
'exporting' => __('Exporting...', 'all-in-one-wp-security-and-firewall'),
|
||||
'refreshing' => __('Refreshing...', 'all-in-one-wp-security-and-firewall'),
|
||||
'scanning' => __('Scanning...', 'all-in-one-wp-security-and-firewall'),
|
||||
'close' => __('Close', 'all-in-one-wp-security-and-firewall'),
|
||||
'completed' => __('Completed.', 'all-in-one-wp-security-and-firewall'),
|
||||
'refreshed' => __('Refreshed.', 'all-in-one-wp-security-and-firewall'),
|
||||
'deleted' => __('Deleted.', 'all-in-one-wp-security-and-firewall'),
|
||||
'show_info' => __('show more', 'all-in-one-wp-security-and-firewall'),
|
||||
'hide_info' => __('hide', 'all-in-one-wp-security-and-firewall'),
|
||||
'show_notices' => __('But the following notices have been raised', 'all-in-one-wp-security-and-firewall'),
|
||||
'disabling' => __('Disabling...', 'all-in-one-wp-security-and-firewall'),
|
||||
'setting_up_firewall' => __('Setting up firewall...', 'all-in-one-wp-security-and-firewall'),
|
||||
'downgrading_firewall' => __('Downgrading firewall...', 'all-in-one-wp-security-and-firewall'),
|
||||
'maintenance_mode_enabled' => __('Maintenance mode is currently enabled.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Remember to disable it when you are done.', 'all-in-one-wp-security-and-firewall'),
|
||||
'maintenance_mode_disabled' => __('Maintenance mode is currently disabled.', 'all-in-one-wp-security-and-firewall'),
|
||||
)
|
||||
);
|
||||
wp_register_script('aiowpsec-pw-tool-js', AIO_WP_SECURITY_URL. '/js/password-strength-tool.js', array('jquery'), AIO_WP_SECURITY_VERSION, true); // We will enqueue this in the user acct menu class
|
||||
wp_localize_script('aiowpsec-pw-tool-js',
|
||||
'aios_pwtool_trans',
|
||||
array(
|
||||
'years' => __('year(s)', 'all-in-one-wp-security-and-firewall'),
|
||||
'months' => __('month(s)', 'all-in-one-wp-security-and-firewall'),
|
||||
'days' => __('day(s)', 'all-in-one-wp-security-and-firewall'),
|
||||
'hours' => __('hour(s)', 'all-in-one-wp-security-and-firewall'),
|
||||
'minutes' => __('minute(s)', 'all-in-one-wp-security-and-firewall'),
|
||||
'seconds' => __('second(s)', 'all-in-one-wp-security-and-firewall'),
|
||||
'less_than_one_second' => __('less than one second', 'all-in-one-wp-security-and-firewall')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin styles.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function admin_menu_page_styles() {
|
||||
wp_enqueue_style('dashboard');
|
||||
wp_enqueue_style('thickbox');
|
||||
wp_enqueue_style('global');
|
||||
wp_enqueue_style('wp-admin');
|
||||
$admin_css_version = (defined('WP_DEBUG') && WP_DEBUG) ? time() : filemtime(AIO_WP_SECURITY_PATH. '/css/wp-security-admin-styles.css');
|
||||
wp_enqueue_style('aiowpsec-admin-css', AIO_WP_SECURITY_URL. '/css/wp-security-admin-styles.css', array(), $admin_css_version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up various class and tasks needed for the admin dashboard
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init_hook_handler_for_admin_side() {
|
||||
$this->initialize_feature_manager();
|
||||
$this->do_other_admin_side_init_tasks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show footer review message and link.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function display_footer_review_message() {
|
||||
$message = sprintf(
|
||||
/* translators: 1: Product Name, 2: Rating, 3: Trustpilot URL, 4: G2 URL */
|
||||
__('Enjoyed %1$s? Please leave us a %2$s rating on %3$s or %4$s', 'all-in-one-wp-security-and-firewall').' '.__('We really appreciate your support!', 'all-in-one-wp-security-and-firewall'),
|
||||
'<b>' . htmlspecialchars('All In One Security') . '</b>',
|
||||
'<span style="color:#2271b1">★★★★★</span>',
|
||||
'<a href="https://uk.trustpilot.com/review/aiosplugin.com" target="_blank">Trustpilot</a>',
|
||||
'<a href="https://www.g2.com/products/all-in-one-wp-security-firewall/reviews" target="_blank">G2.com</a>'
|
||||
);
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if the feature manager is initialized and initializes it if it is not then checks the feature status and recalculates the points
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function initialize_feature_manager() {
|
||||
if (!isset($aiowps_feature_mgr)) {
|
||||
$aiowps_feature_mgr = new AIOWPSecurity_Feature_Item_Manager();
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
$GLOBALS['aiowps_feature_mgr'] = $aiowps_feature_mgr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Other admin side init tasks.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
private function do_other_admin_side_init_tasks() {
|
||||
global $aio_wp_security;
|
||||
|
||||
//***New Feature improvement for Cookie Based Brute Force Protection***//
|
||||
// The old "test cookie" used to be too easy to guess because someone could just read the code and get the value.
|
||||
//So now we will drop a more secure test cookie using a 10 digit random string
|
||||
|
||||
if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')) {
|
||||
// This code is for users who had this feature saved using an older release. This will drop the new more secure test cookie to the browser
|
||||
$test_cookie_name_saved = $aio_wp_security->configs->get_value('aiowps_cookie_brute_test');
|
||||
if (empty($test_cookie_name_saved)) {
|
||||
$random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10);
|
||||
$test_cookie_name = 'aiowps_cookie_test_'.$random_suffix;
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_brute_test', $test_cookie_name, true);
|
||||
AIOWPSecurity_Utility::set_cookie_value($test_cookie_name, '1');
|
||||
}
|
||||
}
|
||||
|
||||
// For cookie test form submission case
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. No nonce on this _GET.
|
||||
if (isset($_GET['page']) && AIOWPSEC_BRUTE_FORCE_MENU_SLUG == $_GET['page'] && isset($_GET['tab']) && 'cookie-based-brute-force-prevention' == $_GET['tab']) {
|
||||
if (isset($_POST['aiowps_do_cookie_test_for_bfla'])) {
|
||||
$random_suffix = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(10);
|
||||
$test_cookie_name = 'aiowps_cookie_test_'.$random_suffix;
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_brute_test', $test_cookie_name, true);
|
||||
AIOWPSecurity_Utility::set_cookie_value($test_cookie_name, '1');
|
||||
$cur_url = "admin.php?page=".AIOWPSEC_BRUTE_FORCE_MENU_SLUG."&tab=cookie-based-brute-force-prevention";
|
||||
$redirect_url = AIOWPSecurity_Utility::add_query_data_to_url($cur_url, 'aiowps_cookie_test', "1");
|
||||
AIOWPSecurity_Utility::redirect_to_url($redirect_url);
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['aiowps_cookie_test'])) {
|
||||
$test_cookie = $aio_wp_security->configs->get_value('aiowps_cookie_brute_test');
|
||||
$cookie_val = AIOWPSecurity_Utility::get_cookie_value($test_cookie);
|
||||
if (empty($cookie_val)) {
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_test_success', '');
|
||||
} else {
|
||||
$aio_wp_security->configs->set_value('aiowps_cookie_test_success', '1');
|
||||
}
|
||||
$aio_wp_security->configs->save_config();//save the value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds admin menu page and all submenus to the WordPress dashboard
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function create_admin_menus() {
|
||||
$menu_icon_url = AIO_WP_SECURITY_URL.'/images/aios-plugin-icon.svg';
|
||||
$this->main_menu_page = add_menu_page(__('AIOS', 'all-in-one-wp-security-and-firewall'), __('AIOS', 'all-in-one-wp-security-and-firewall'), apply_filters('aios_management_permission', 'manage_options'), AIOWPSEC_MAIN_MENU_SLUG, array($this, 'handle_dashboard_menu_rendering'), $menu_icon_url);
|
||||
|
||||
foreach ($this->menu_items as $menu_item) {
|
||||
add_submenu_page(AIOWPSEC_MAIN_MENU_SLUG, $menu_item['page_title'], $menu_item['menu_title'], apply_filters('aios_management_permission', 'manage_options'), $menu_item['menu_slug'], $menu_item['render_callback'], $menu_item['order']);
|
||||
}
|
||||
|
||||
do_action('aiowpsecurity_admin_menu_created');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds submenu link for premium upgrade tab.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function premium_upgrade_submenu() {
|
||||
if (!AIOWPSecurity_Utility_Permissions::is_premium_installed()) {
|
||||
global $submenu;
|
||||
$submenu[AIOWPSEC_MAIN_MENU_SLUG][] = array(__('Premium Upgrade', 'all-in-one-wp-security-and-firewall'), apply_filters('aios_management_permission', 'manage_options'), 'admin.php?page='.AIOWPSEC_MAIN_MENU_SLUG.'&tab=premium-upgrade');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Dashboard' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_dashboard_menu_rendering() {
|
||||
include_once('wp-security-dashboard-menu.php');
|
||||
new AIOWPSecurity_Dashboard_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Settings' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_settings_menu_rendering() {
|
||||
include_once('wp-security-settings-menu.php');
|
||||
new AIOWPSecurity_Settings_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'User Security' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_user_security_menu_rendering() {
|
||||
include_once('wp-security-user-security-menu.php');
|
||||
new AIOWPSecurity_User_Security_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Database Security' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_database_menu_rendering() {
|
||||
include_once('wp-security-database-menu.php');
|
||||
new AIOWPSecurity_Database_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Filesystem Security' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_filesystem_menu_rendering() {
|
||||
include_once('wp-security-filesystem-menu.php');
|
||||
new AIOWPSecurity_Filesystem_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Firewall' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_firewall_menu_rendering() {
|
||||
include_once('wp-security-firewall-menu.php');
|
||||
new AIOWPSecurity_Firewall_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Brute Force' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_brute_force_menu_rendering() {
|
||||
include_once('wp-security-brute-force-menu.php');
|
||||
new AIOWPSecurity_Brute_Force_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Spam Prevention' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_spam_menu_rendering() {
|
||||
include_once('wp-security-spam-menu.php');
|
||||
new AIOWPSecurity_Spam_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Scanner' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_filescan_menu_rendering() {
|
||||
include_once('wp-security-filescan-menu.php');
|
||||
new AIOWPSecurity_Filescan_Menu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Tools' submenu page.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function handle_tools_menu_rendering() {
|
||||
include_once('wp-security-tools-menu.php');
|
||||
new AIOWPSecurity_Tools_Menu();
|
||||
}
|
||||
|
||||
} // End of class
|
||||
+280
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
/**
|
||||
* Parent class for all admin menu classes
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
abstract class AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Specify the menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug;
|
||||
|
||||
/**
|
||||
* Specify all the tabs of this menu
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $menu_tabs;
|
||||
|
||||
/**
|
||||
* Constructor adds a admin menu
|
||||
*
|
||||
* @param string $title - Title of menu to be rendered
|
||||
*/
|
||||
public function __construct($title) {
|
||||
$this->setup_menu_tabs();
|
||||
$this->render_page($title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the menu page
|
||||
*
|
||||
* @param string $title - the page title
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_page($title) {
|
||||
$current_tab = $this->get_current_tab();
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h2><?php echo esc_html($title); ?></h2>
|
||||
<?php $this->render_tabs($current_tab); ?>
|
||||
<div id="poststuff">
|
||||
<div id="post-body">
|
||||
<?php call_user_func($this->menu_tabs[$current_tab]['render_callback']); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the menu tabs for this page
|
||||
*
|
||||
* @param string $current_tab - the current tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_tabs($current_tab) {
|
||||
echo '<h2 class="nav-tab-wrapper">';
|
||||
foreach ($this->menu_tabs as $tab_key => $tab_info) {
|
||||
$active = $current_tab == $tab_key ? 'nav-tab-active' : '';
|
||||
echo '<a class="nav-tab ' . esc_attr($active) . '" href="?page=' . esc_attr($this->menu_page_slug) . '&tab=' . esc_attr($tab_key) . '">' . esc_html($tab_info['title']) . '</a>';
|
||||
}
|
||||
echo '</h2>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get valid current tab slug.
|
||||
*
|
||||
* @return string - current valid tab slug or empty string
|
||||
*/
|
||||
protected function get_current_tab() {
|
||||
if (is_array($this->menu_tabs) && !empty($this->menu_tabs)) {
|
||||
$tab_keys = array_keys($this->menu_tabs);
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available.
|
||||
if (empty($_GET['tab'])) {
|
||||
return $tab_keys[0];
|
||||
} else {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available.
|
||||
$current_tab = sanitize_text_field(wp_unslash($_GET['tab']));
|
||||
return in_array($current_tab, $tab_keys) ? $current_tab : $tab_keys[0];
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks to see if there is a display condition for the tab and if so runs it otherwise it returns true to display the tab
|
||||
*
|
||||
* @param array $tab_info - the tab information array contains keys like title, render_callback and display_condition_callback
|
||||
*
|
||||
* @return boolean - true if the tab should be displayed or false to hide it
|
||||
*/
|
||||
protected function should_display_tab($tab_info) {
|
||||
return AIOWPSecurity_Utility::apply_callback_filter($tab_info, 'display_condition_callback');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows postbox for settings menu
|
||||
*
|
||||
* @param string $id - css ID for postbox
|
||||
* @param string $title - title of the postbox section
|
||||
* @param string $content - the content of the postbox
|
||||
**/
|
||||
protected function postbox_toggle($id, $title, $content) {
|
||||
//Always send string with translation markers in it
|
||||
?>
|
||||
<div id="<?php echo esc_attr($id); ?>" class="postbox">
|
||||
<div class="handlediv" title="<?php echo esc_html__('Press to toggle', 'all-in-one-wp-security-and-firewall'); ?>"><br /></div>
|
||||
<h3 class="hndle"><span><?php echo esc_html($title); ?></span></h3>
|
||||
<div class="inside">
|
||||
<?php echo wp_kses_post($content); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a postbox with a title and content.
|
||||
*
|
||||
* This function generates and outputs HTML markup for a postbox with a specified title
|
||||
* and content. The title and content should be provided as parameters, and they will be
|
||||
* automatically escaped for security. The function ensures that translation markers are
|
||||
* included in the output strings.
|
||||
*
|
||||
* @param string $title - The title of the postbox.
|
||||
* @param string $content - The content to be displayed inside the postbox.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function postbox($title, $content) {
|
||||
// Always send string with translation markers in it
|
||||
?>
|
||||
<div class="postbox">
|
||||
<h3 class="hndle"><label for="title"><?php echo esc_html($title); ?></label></h3>
|
||||
<div class="inside">
|
||||
<?php echo wp_kses_post($content); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render settings successfully updated message
|
||||
*
|
||||
* @param bool $return_instead_of_echo - This is used for when the function needs to return the message
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function show_msg_settings_updated($return_instead_of_echo = false) {
|
||||
$message = '<div id="aios_message" class="updated fade"><p><strong>';
|
||||
$message .= esc_html__('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall');
|
||||
$message .= '</strong></p></div>';
|
||||
if ($return_instead_of_echo) return $message;
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML.
|
||||
echo $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render settings successfully updated message
|
||||
*
|
||||
* @param bool $return_instead_of_echo - This is used for when the function needs to return the message
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public static function show_msg_settings_updated_st($return_instead_of_echo = false) {
|
||||
$message = '<div id="aios_message" class="updated fade"><p><strong>';
|
||||
$message .= esc_html__('The settings have been successfully updated.', 'all-in-one-wp-security-and-firewall');
|
||||
$message .= '</strong></p></div>';
|
||||
if ($return_instead_of_echo) return $message;
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML.
|
||||
echo $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders record(s) successfully deleted message at top of page.
|
||||
*
|
||||
* @param bool $return_instead_of_echo - This is used for when the function needs to return the message
|
||||
* @return mixed
|
||||
*/
|
||||
public static function show_msg_record_deleted_st($return_instead_of_echo = false) {
|
||||
return AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected record(s) has been deleted successfully.', 'all-in-one-wp-security-and-firewall'), $return_instead_of_echo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders record(s) unsuccessfully deleted message at top of page.
|
||||
*
|
||||
* @param bool $return_instead_of_echo - This is used for when the function needs to return the message
|
||||
* @return mixed
|
||||
*/
|
||||
public static function show_msg_record_not_deleted_st($return_instead_of_echo = false) {
|
||||
return AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The selected record(s) have failed to delete.', 'all-in-one-wp-security-and-firewall'), $return_instead_of_echo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render successfully updated message
|
||||
*
|
||||
* @param string $msg - This contains the message to show
|
||||
* @param bool $return_instead_of_echo - This is used for when the function needs to return the message
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function show_msg_updated($msg, $return_instead_of_echo = false) {
|
||||
$message = '<div id="aios_message" class="updated fade"><p><strong>';
|
||||
$message .= wp_kses_post($msg);
|
||||
$message .= '</strong></p></div>';
|
||||
if ($return_instead_of_echo) return $message;
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML.
|
||||
echo $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render successfully updated message
|
||||
*
|
||||
* @param string $msg - This contains the message to show
|
||||
* @param bool $return_instead_of_echo - This is used for when the function needs to return the message
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public static function show_msg_updated_st($msg, $return_instead_of_echo = false) {
|
||||
$message = '<div id="aios_message" class="updated fade"><p><strong>';
|
||||
$message .= wp_kses_post($msg);
|
||||
$message .= '</strong></p></div>';
|
||||
if ($return_instead_of_echo) return $message;
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML.
|
||||
echo $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render error message
|
||||
*
|
||||
* @param string $error_msg - This contains the message to show
|
||||
* @param bool $return_instead_of_echo - This is used for when the function needs to return the message
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function show_msg_error($error_msg, $return_instead_of_echo = false) {
|
||||
$message = '<div id="aios_message" class="error"><p><strong>';
|
||||
$message .= wp_kses_post($error_msg);
|
||||
$message .= '</strong></p></div>';
|
||||
if ($return_instead_of_echo) return $message;
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML.
|
||||
echo $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render error message
|
||||
*
|
||||
* @param string $error_msg - This contains the message to show
|
||||
* @param bool $return_instead_of_echo - This is used for when the function needs to return the message
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public static function show_msg_error_st($error_msg, $return_instead_of_echo = false) {
|
||||
$message = '<div id="aios_message" class="error"><p><strong>';
|
||||
$message .= wp_kses_post($error_msg);
|
||||
$message .= '</strong></p></div>';
|
||||
if ($return_instead_of_echo) return $message;
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Variable contains escaped HTML.
|
||||
echo $message;
|
||||
}
|
||||
|
||||
protected function start_buffer() {
|
||||
ob_start();
|
||||
}
|
||||
|
||||
protected function end_buffer_and_collect() {
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
Executable
+176
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* AIOWPSecurity_Brute_Force_Menu class for brute force prevention.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
class AIOWPSecurity_Brute_Force_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Blacklist menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_BRUTE_FORCE_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Brute force
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('Brute force', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'rename-login' => array(
|
||||
'title' => __('Rename login page', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_rename_login'),
|
||||
),
|
||||
'cookie-based-brute-force-prevention' => array(
|
||||
'title' => __('Cookie based brute force prevention', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_cookie_based_brute_force_prevention'),
|
||||
'display_condition_callback' => 'is_main_site',
|
||||
),
|
||||
'captcha-settings' => array(
|
||||
'title' => __('CAPTCHA settings', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_captcha_settings'),
|
||||
),
|
||||
'login-whitelist' => array(
|
||||
'title' => __('Login whitelist', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_login_whitelist'),
|
||||
),
|
||||
'404-detection' => array(
|
||||
'title' => __('404 detection', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_404_detection'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'honeypot' => array(
|
||||
'title' => __('Honeypot', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_honeypot'),
|
||||
),
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename login page tab.
|
||||
*
|
||||
* @global $aio_wp_security
|
||||
* @global $aiowps_feature_mgr
|
||||
*/
|
||||
protected function render_rename_login() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
if (get_option('permalink_structure')) {
|
||||
$home_url = trailingslashit(home_url());
|
||||
} else {
|
||||
$home_url = trailingslashit(home_url()) . '?';
|
||||
}
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/brute-force/rename-login.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'home_url' => $home_url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie based brute force prevention tab.
|
||||
*
|
||||
* @global $aio_wp_security
|
||||
* @global $aiowps_feature_mgr
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_cookie_based_brute_force_prevention() {
|
||||
global $aio_wp_security;
|
||||
global $aiowps_feature_mgr;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/brute-force/cookie-based-brute-force-prevention.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Login captcha tab.
|
||||
*
|
||||
* @global $aio_wp_security
|
||||
* @global $aiowps_feature_mgr
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_captcha_settings() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
$supported_captchas = $aio_wp_security->captcha_obj->get_supported_captchas();
|
||||
$captcha_themes = $aio_wp_security->captcha_obj->get_captcha_themes();
|
||||
|
||||
$captcha_theme = 'auto';
|
||||
if ('cloudflare-turnstile' == $aio_wp_security->configs->get_value('aiowps_default_captcha')) $captcha_theme = $aio_wp_security->configs->get_value('aiowps_turnstile_theme');
|
||||
|
||||
if ('cloudflare-turnstile' == $aio_wp_security->configs->get_value('aiowps_default_captcha') && false === $aio_wp_security->captcha_obj->cloudflare_turnstile_verify_configuration($aio_wp_security->configs->get_value('aiowps_turnstile_site_key'), $aio_wp_security->configs->get_value('aiowps_turnstile_secret_key'))) {
|
||||
echo '<div class="notice notice-warning aio_red_box"><p>' . esc_html__('Your Cloudflare Turnstile configuration is invalid.', 'all-in-one-wp-security-and-firewall').' ' . esc_html__('Please enter the correct Cloudflare Turnstile keys below to use the Turnstile feature.', 'all-in-one-wp-security-and-firewall').'</p></div>';
|
||||
}
|
||||
|
||||
if ('1' == $aio_wp_security->configs->get_value('aios_google_recaptcha_invalid_configuration')) {
|
||||
echo '<div class="notice notice-warning aio_red_box"><p>' . esc_html__('Your Google reCAPTCHA configuration is invalid.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Please enter the correct reCAPTCHA keys below to use the reCAPTCHA feature.', 'all-in-one-wp-security-and-firewall').'</p></div>';
|
||||
}
|
||||
|
||||
$default_captcha = $aio_wp_security->configs->get_value('aiowps_default_captcha');
|
||||
$aio_wp_security->include_template('wp-admin/brute-force/captcha-settings.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'supported_captchas' => $supported_captchas, 'default_captcha' => $default_captcha, 'captcha_themes' => $captcha_themes, 'captcha_theme' => $captcha_theme));
|
||||
}
|
||||
|
||||
/**
|
||||
* Login whitelist tab.
|
||||
*
|
||||
* @return void
|
||||
* @global $aio_wp_security
|
||||
* @global $aiowps_feature_mgr
|
||||
*/
|
||||
protected function render_login_whitelist() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
$ip_v4 = false;
|
||||
$your_ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address();
|
||||
if (filter_var($your_ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) $ip_v4 = true;
|
||||
|
||||
$aiowps_allowed_ip_addresses = $aio_wp_security->configs->get_value('aiowps_allowed_ip_addresses');
|
||||
$aio_wp_security->include_template('wp-admin/brute-force/login-whitelist.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'your_ip_address' => $your_ip_address, 'ip_v4' => $ip_v4, 'aiowps_allowed_ip_addresses' => $aiowps_allowed_ip_addresses));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the 404 Detection tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_404_detection() {
|
||||
global $aio_wp_security;
|
||||
|
||||
include_once 'wp-security-list-404.php'; // For rendering the AIOWPSecurity_List_Table in basic-firewall tab
|
||||
$event_list_404 = new AIOWPSecurity_List_404(); // For rendering the AIOWPSecurity_List_Table in basic-firewall tab
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available.
|
||||
$page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : '';
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce available.
|
||||
$tab = isset($_REQUEST["tab"]) ? sanitize_text_field(wp_unslash($_REQUEST["tab"])) : '';
|
||||
$aio_wp_security->include_template('wp-admin/brute-force/404-detection.php', false, array('event_list_404' => $event_list_404, 'page' => $page, 'tab' => $tab));
|
||||
}
|
||||
|
||||
/**
|
||||
* Honeypot tab.
|
||||
*
|
||||
* @global $aio_wp_security
|
||||
* @global $aiowps_feature_mgr
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_honeypot() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/brute-force/honeypot.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr));
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+653
@@ -0,0 +1,653 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Dashboard_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Dashboard menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_MAIN_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Dashboard
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('Dashboard', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'dashboard' => array(
|
||||
'title' => __('Dashboard', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_dashboard'),
|
||||
),
|
||||
'locked-ip' => array(
|
||||
'title' => __('Locked IP addresses', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_locked_ip'),
|
||||
),
|
||||
'permanent-block' => array(
|
||||
'title' => __('Permanent block list', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_permanent_block'),
|
||||
),
|
||||
'audit-logs' => array(
|
||||
'title' => __('Audit logs', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_audit_logs'),
|
||||
),
|
||||
'debug-logs' => array(
|
||||
'title' => __('Debugging', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_debug_logs'),
|
||||
),
|
||||
'premium-upgrade' => array(
|
||||
'title' => __('Premium upgrade', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_premium_upgrade_tab'),
|
||||
'display_condition_callback' => function() {
|
||||
return !AIOWPSecurity_Utility_Permissions::is_premium_installed();
|
||||
}
|
||||
),
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's dashboard tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_dashboard() {
|
||||
/**
|
||||
* Load WordPress dashboard API
|
||||
*/
|
||||
require_once(ABSPATH . 'wp-admin/includes/dashboard.php');
|
||||
$this->wp_dashboard_setup();
|
||||
|
||||
wp_enqueue_script('dashboard');
|
||||
if (wp_is_mobile()) wp_enqueue_script('jquery-touch-punch');
|
||||
|
||||
?>
|
||||
<?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- Needed for dashboard widget. ?>
|
||||
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
|
||||
<div id="dashboard-widgets-wrap">
|
||||
<?php $this->wp_dashboard(); ?>
|
||||
</div><!-- dashboard-widgets-wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's locked IP addresses tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_locked_ip() {
|
||||
global $aio_wp_security;
|
||||
include_once 'wp-security-list-locked-ip.php';
|
||||
$locked_ip_list = new AIOWPSecurity_List_Locked_IP();
|
||||
$tab = isset($_REQUEST["tab"]) ? sanitize_text_field(wp_unslash($_REQUEST["tab"])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce for tabs.
|
||||
$page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce for page.
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/dashboard/locked-ip.php', false, array('locked_ip_list' => $locked_ip_list, 'page' => $page, 'tab' => $tab));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's permanent block tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_permanent_block() {
|
||||
global $aio_wp_security;
|
||||
include_once 'wp-security-list-permanent-blocked-ip.php'; // For rendering the AIOWPSecurity_List_Table
|
||||
$blocked_ip_list = new AIOWPSecurity_List_Blocked_IP(); // For rendering the AIOWPSecurity_List_Table
|
||||
$tab = isset($_REQUEST["tab"]) ? sanitize_text_field(wp_unslash($_REQUEST["tab"])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce for tab.
|
||||
$page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce for page.
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/dashboard/permanent-block.php', false, array('blocked_ip_list' => $blocked_ip_list, 'page' => $page, 'tab' => $tab));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's audit logs tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_audit_logs() {
|
||||
global $aio_wp_security;
|
||||
|
||||
// Needed for rendering the audit log table
|
||||
include_once 'wp-security-list-audit.php';
|
||||
$data = array();
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. Processing form data without nonce verification. No nonce.
|
||||
if (isset($_GET['event-filter'])) $data['event-filter'] = sanitize_text_field(wp_unslash($_GET['event-filter'])); // Failed logins and logins only to show as audit log
|
||||
$audit_log_list = new AIOWPSecurity_List_Audit_Log($data);
|
||||
$tab = isset($_REQUEST["tab"]) ? sanitize_text_field(wp_unslash($_REQUEST["tab"])) : '';
|
||||
$page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : '';
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. Processing form data without nonce verification. No nonce.
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/dashboard/audit-logs.php', false, array('audit_log_list' => $audit_log_list, 'page' => $page, 'tab' => $tab));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's debug logs tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_debug_logs() {
|
||||
// Needed for rendering the debug log table
|
||||
include_once 'wp-security-list-debug.php';
|
||||
$debug_log_list = new AIOWPSecurity_List_Debug_Log();
|
||||
global $aio_wp_security;
|
||||
$aio_wp_security->include_template('wp-admin/dashboard/debug-logs.php', false, array('debug_log_list' => $debug_log_list));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's premium-upgrade tab body.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_premium_upgrade_tab() {
|
||||
global $aio_wp_security;
|
||||
$enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? AIO_WP_SECURITY_VERSION.'.'.time() : AIO_WP_SECURITY_VERSION;
|
||||
wp_enqueue_style('aiowpsec-admin-premium-upgrade-css', AIO_WP_SECURITY_URL.'/css/wp-security-premium-upgrade.css', array(), $enqueue_version);
|
||||
|
||||
echo '<div class="postbox wpo-tab-postbox">';
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/dashboard/may-also-like.php');
|
||||
|
||||
echo '</div><!-- END .postbox -->';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to customize the layout of the WordPress dashboard.
|
||||
* Organizes meta-boxes into different containers based on screen columns.
|
||||
*/
|
||||
private function wp_dashboard() {
|
||||
$screen = get_current_screen();
|
||||
$columns = absint($screen->get_columns());
|
||||
$columns_css = '';
|
||||
if ($columns) {
|
||||
$columns_css = " columns-$columns";
|
||||
}
|
||||
|
||||
?>
|
||||
<div id="dashboard-widgets" class="metabox-holder<?php echo esc_attr($columns_css); ?>">
|
||||
<div id="postbox-container-1" class="postbox-container">
|
||||
<?php do_meta_boxes($screen->id, 'normal', ''); ?>
|
||||
</div>
|
||||
<div id="postbox-container-2" class="postbox-container">
|
||||
<?php do_meta_boxes($screen->id, 'side', ''); ?>
|
||||
</div>
|
||||
<div id="postbox-container-3" class="postbox-container">
|
||||
<?php do_meta_boxes($screen->id, 'column3', ''); ?>
|
||||
</div>
|
||||
<div id="postbox-container-4" class="postbox-container">
|
||||
<?php do_meta_boxes($screen->id, 'column4', ''); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
|
||||
wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
|
||||
}
|
||||
|
||||
private function wp_dashboard_setup() {
|
||||
global $aio_wp_security, $wp_registered_widgets, $wp_registered_widget_controls, $wp_dashboard_control_callbacks;
|
||||
$wp_dashboard_control_callbacks = array();
|
||||
get_current_screen();
|
||||
|
||||
// Add widgets
|
||||
wp_add_dashboard_widget('security_strength_meter', __('Security strength meter', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_security_strength_meter'));
|
||||
wp_add_dashboard_widget('security_points_breakdown', __('Security points breakdown', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_security_points_breakdown'));
|
||||
wp_add_dashboard_widget('spread_the_word', __('Spread the word', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_spread_the_word'));
|
||||
wp_add_dashboard_widget('know_developers', __('Get to know the developers', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_know_developers'));
|
||||
wp_add_dashboard_widget('critical_feature_status', __('Critical feature status', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_critical_feature_status'));
|
||||
wp_add_dashboard_widget('last_5_logins', __('Last 5 login summary', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_last_5_logins'));
|
||||
wp_add_dashboard_widget('maintenance_mode_status', __('Maintenance mode status', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_maintenance_mode_status'));
|
||||
if ('1' == $aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention')
|
||||
|| '1' == $aio_wp_security->configs->get_value('aiowps_enable_rename_login_page')
|
||||
) {
|
||||
wp_add_dashboard_widget('brute_force', __('Brute force prevention login page', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_brute_force'));
|
||||
}
|
||||
wp_add_dashboard_widget('logged_in_users', __('Logged in users', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_logged_in_users'));
|
||||
wp_add_dashboard_widget('locked_ip_addresses', __('Locked IP addresses', 'all-in-one-wp-security-and-firewall'), array($this, 'widget_locked_ip_addresses'));
|
||||
|
||||
do_action('aiowps_dashboard_setup');
|
||||
$dashboard_widgets = apply_filters('aiowps_dashboard_widgets', array());
|
||||
|
||||
foreach ($dashboard_widgets as $widget_id) {
|
||||
$name = empty($wp_registered_widgets[$widget_id]['all_link']) ? $wp_registered_widgets[$widget_id]['name'] : $wp_registered_widgets[$widget_id]['name'] . " <a href='{$wp_registered_widgets[$widget_id]['all_link']}' class='edit-box open-box'>" . __('View all', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
wp_add_dashboard_widget($widget_id, $name, $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback']);
|
||||
}
|
||||
}
|
||||
|
||||
public function widget_security_strength_meter() {
|
||||
global $aiowps_feature_mgr;
|
||||
$total_site_security_points = $aiowps_feature_mgr->get_total_site_points();
|
||||
$total_security_points_achievable = $aiowps_feature_mgr->get_total_achievable_points();
|
||||
?>
|
||||
<script type='text/javascript'>
|
||||
var total_security_points_achievable = <?php echo (int) $total_security_points_achievable; ?>;
|
||||
var section = total_security_points_achievable / 8;
|
||||
|
||||
var config = {
|
||||
type: 'gauge',
|
||||
data: {
|
||||
datasets: [{
|
||||
value: <?php echo esc_js($total_site_security_points); ?>,
|
||||
minValue: 0,
|
||||
data: [section, section * 2, section * 3, section * 4, section * 5, section * 6, total_security_points_achievable],
|
||||
backgroundColor: ['#26ddfd', '#26ddfd', '#00b0ea', '#00b0ea', '#2680ca', '#2680ca', '#563c82'],
|
||||
borderWidth: 2.5
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
cutoutPercentage: 75,
|
||||
layout: {
|
||||
padding: {
|
||||
bottom: 20
|
||||
}
|
||||
},
|
||||
needle: {
|
||||
radiusPercentage: 5,
|
||||
widthPercentage: 6,
|
||||
lengthPercentage: 80,
|
||||
color: '#3e3e3e'
|
||||
},
|
||||
valueLabel: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.onload = function() {
|
||||
var ctx = document.getElementById('chart').getContext('2d');
|
||||
window.myGauge = new Chart(ctx, config);
|
||||
};
|
||||
</script>
|
||||
|
||||
<div id="canvas-holder">
|
||||
<canvas id="chart"></canvas>
|
||||
</div>
|
||||
|
||||
<h2 id="website-strength-text"><?php echo esc_html__('Website strength:', 'all-in-one-wp-security-and-firewall') . ' ' . '<strong>' . esc_html($total_site_security_points) . '</strong>'; ?></h2>
|
||||
|
||||
<div id='security_strength_chart_div'></div>
|
||||
<div class="aiowps_dashboard_widget_footer">
|
||||
<?php
|
||||
echo esc_html__('Total Achievable Points:', 'all-in-one-wp-security-and-firewall') . ' ' . '<strong>' . esc_html($total_security_points_achievable) . '</strong><br />';
|
||||
echo esc_html__('Current Score of Your Site:', 'all-in-one-wp-security-and-firewall') . ' ' . '<strong>' . esc_html($total_site_security_points) . '</strong>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function widget_security_points_breakdown() {
|
||||
global $aiowps_feature_mgr;
|
||||
$feature_mgr = $aiowps_feature_mgr;
|
||||
$feature_items = $feature_mgr->feature_items;
|
||||
$pt_src_chart_data = "";
|
||||
$pt_src_chart_data .= "['Feature Name', 'Points'],";
|
||||
foreach ($feature_items as $item) {
|
||||
if ($item->is_active()) {
|
||||
$pt_src_chart_data .= "['" . esc_html($item->feature_name) . "', " . esc_html($item->item_points) . "],";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- PCP error. Direct enqueue necessary. ?>
|
||||
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
|
||||
<script type="text/javascript">
|
||||
google.load("visualization", "1", {packages: ["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
var data = google.visualization.arrayToDataTable([
|
||||
<?php echo $pt_src_chart_data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JS array data. Variables escaped earlier. ?>
|
||||
]);
|
||||
|
||||
var options = {
|
||||
// height: '250',
|
||||
// width: '450',
|
||||
backgroundColor: 'F6F6F6',
|
||||
pieHole: 0.4,
|
||||
chartArea: {
|
||||
width: '95%',
|
||||
height: '95%',
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new google.visualization.PieChart(document.getElementById('points_source_breakdown_chart_div'));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id='points_source_breakdown_chart_div'></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function widget_spread_the_word() {
|
||||
?>
|
||||
<p><?php echo esc_html__('We are working hard to make your WordPress site more secure.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Please support us, here is how:', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<p><a href="https://x.com/TeamUpdraftWP" target="_blank"><?php esc_html_e('Follow us on', 'all-in-one-wp-security-and-firewall');?> X</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://x.com/intent/tweet?url=https://wordpress.org/plugins/all-in-one-wp-security-and-firewall&text=I love the All In One WP Security and Firewall plugin!"
|
||||
target="_blank" class="aio_tweet_link"><?php esc_html_e('Post to X', 'all-in-one-wp-security-and-firewall');?></a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="http://wordpress.org/support/view/plugin-reviews/all-in-one-wp-security-and-firewall/"
|
||||
target="_blank" class="aio_rate_us_link"><?php esc_html_e('Give us a good rating', 'all-in-one-wp-security-and-firewall');?></a>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function widget_know_developers() {
|
||||
?>
|
||||
<p><?php esc_html_e('Wanna know more about the developers behind this plugin?', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<p><a href="https://teamupdraft.com/" target="_blank">Team UpdraftPlus</a></p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* This outputs the critical feature status widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function widget_critical_feature_status() {
|
||||
global $aiowps_feature_mgr;
|
||||
|
||||
$critical_features = array(
|
||||
'user-accounts-change-admin-user' => array(
|
||||
'name' => __('Admin username', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => AIOWPSEC_USER_SECURITY_MENU_SLUG,
|
||||
),
|
||||
'user-login-login-lockdown' => array(
|
||||
'name' => __('Login lockout', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => AIOWPSEC_USER_SECURITY_MENU_SLUG . '&tab=login-lockout',
|
||||
),
|
||||
'filesystem-file-permissions' => array(
|
||||
'name' => __('File permission', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => AIOWPSEC_FILESYSTEM_MENU_SLUG,
|
||||
'feature_callback' => 'is_main_site'
|
||||
),
|
||||
'firewall-basic-rules' => array(
|
||||
'name' => __('Basic firewall', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => AIOWPSEC_FIREWALL_MENU_SLUG . '&tab=htaccess-rules',
|
||||
'feature_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess')
|
||||
),
|
||||
'db-security-db-prefix' => array(
|
||||
'name' => __('Database prefix', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => AIOWPSEC_DB_SEC_MENU_SLUG,
|
||||
'feature_callback' => 'is_main_site'
|
||||
),
|
||||
'filesystem-file-editing' => array(
|
||||
'name' => __('PHP file editing', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => AIOWPSEC_FILESYSTEM_MENU_SLUG . '&tab=file-protection',
|
||||
'feature_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin')
|
||||
),
|
||||
'bf-rename-login-page' => array(
|
||||
'name' => __('Renamed login page', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => AIOWPSEC_BRUTE_FORCE_MENU_SLUG,
|
||||
),
|
||||
'wp-generator-meta-tag' => array(
|
||||
'name' => __('Hidden WP meta info', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => AIOWPSEC_SETTINGS_MENU_SLUG . '&tab=wp-version-info',
|
||||
),
|
||||
);
|
||||
|
||||
$critical_features = apply_filters('aiowps_filter_critical_features_array', $critical_features);
|
||||
$critical_features = array_filter($critical_features, array($this, 'should_add_feature'));
|
||||
|
||||
esc_html_e('Below is the current status of the critical features that you should activate on your site to achieve a minimum level of recommended security', 'all-in-one-wp-security-and-firewall');
|
||||
echo '<div class="aiowps_features_grid">';
|
||||
foreach ($critical_features as $key => $feature) {
|
||||
$feature_item = $aiowps_feature_mgr->get_feature_item_by_id($key);
|
||||
|
||||
if (!$feature_item) continue;
|
||||
|
||||
echo '<a href="admin.php?page=' . esc_attr($feature['url']) . '" class="aiowps_critical_feature_link">';
|
||||
echo '<div class="aiowps_critical_feature_status_container">';
|
||||
echo '<div class="aiowps_critical_feature_status_name">' . esc_html($feature['name']) . '</div>';
|
||||
echo '<div class="aiowps_feature_status_circle">';
|
||||
if ($feature_item->is_active()) {
|
||||
echo '<div class="aiowps_feature_status_circle_on"></div>';
|
||||
} else {
|
||||
echo '<div class="aiowps_feature_status_circle_off"></div>';
|
||||
}
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
echo '</a>';
|
||||
}
|
||||
echo "</div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* This outputs the latest logins dashboard widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function widget_last_5_logins() {
|
||||
global $wpdb;
|
||||
$audit_log_table = AIOWPSEC_TBL_AUDIT_LOG;
|
||||
$where_sql = (is_super_admin()) ? '' : ' and site_id = '.get_current_blog_id().' ';
|
||||
|
||||
$last_days = 7;
|
||||
$days_before_time = strtotime('-'.$last_days.' days', time());
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP warning. Direct query necessary.
|
||||
$login_data_lastx_days = $wpdb->get_results(
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- pcp Warning. Ignore.
|
||||
$wpdb->prepare("SELECT id,created FROM $audit_log_table WHERE event_type = %s $where_sql and created > %s", 'successful_login', $days_before_time),
|
||||
ARRAY_A
|
||||
); // Get the last x days records
|
||||
|
||||
if (!empty($login_data_lastx_days)) {
|
||||
$chart_data = array();
|
||||
$chart_data['columns'] = array(__('Date', 'all-in-one-wp-security-and-firewall'), __('Logins', 'all-in-one-wp-security-and-firewall'));
|
||||
$chart_data['data'] = $login_data_lastx_days;
|
||||
$chart_data['last_days'] = $last_days;
|
||||
$chart_data['id'] = 'logins_last_'.$last_days.'days';
|
||||
$this->dashboard_widget_chart($chart_data, 'bar');
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery -- PCP Error. Ignore.
|
||||
$data = $wpdb->get_results(
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- PCP error. Ignore.
|
||||
$wpdb->prepare("SELECT * FROM $audit_log_table WHERE event_type = %s ORDER BY created DESC LIMIT %d", 'successful_login', 5),
|
||||
ARRAY_A
|
||||
); //Get the last 5 records
|
||||
|
||||
if (null == $data) {
|
||||
echo '<p>' . esc_html__('No data found.', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
} else {
|
||||
$login_summary_table_data = array();
|
||||
//$login_summary_table_data['title'] = __('Last 5 login summary:', 'all-in-one-wp-security-and-firewall');
|
||||
$login_summary_table_data['columns'] = array(__('User', 'all-in-one-wp-security-and-firewall'), __('Date', 'all-in-one-wp-security-and-firewall'), 'IP');
|
||||
foreach ($data as $entry) {
|
||||
$login_summary_table_data['data'][] = array($entry['username'], gmdate('Y-m-d H:i:s', $entry['created']), $entry['ip']);
|
||||
}
|
||||
$login_summary_table_data = apply_filters('aios_last5_logins_summary', $login_summary_table_data, $data);
|
||||
$this->dashboard_widget($login_summary_table_data);
|
||||
|
||||
// View all login logs
|
||||
echo '<p><a class="button" href="' . esc_url('admin.php?page=' . AIOWPSEC_MAIN_MENU_SLUG . '&tab=audit-logs&event-filter=successful_login') . '">' . esc_html__('View all', 'all-in-one-wp-security-and-firewall') . '</a></p>';
|
||||
}
|
||||
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
}
|
||||
|
||||
public function widget_maintenance_mode_status() {
|
||||
global $aio_wp_security;
|
||||
?>
|
||||
<p id="aiowpsec-dashboard-maintenance-mode-status-message">
|
||||
<?php
|
||||
if ('1' == $aio_wp_security->configs->get_value('aiowps_site_lockout')) {
|
||||
echo esc_html__('Maintenance mode is currently enabled.', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('Remember to disable it when you are done.', 'all-in-one-wp-security-and-firewall');
|
||||
} else {
|
||||
echo esc_html__('Maintenance mode is currently disabled.', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php esc_html_e('Enable maintenance mode', 'all-in-one-wp-security-and-firewall'); ?>:</th>
|
||||
<td>
|
||||
<div id="aiowpsec-dashboard-maintenance-mode-switch-container" class="aiowps_switch_container">
|
||||
<?php AIOWPSecurity_Utility_UI::setting_checkbox('', 'aiowps_site_lockout', '1' == $aio_wp_security->configs->get_value('aiowps_site_lockout')); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
echo '<a href="admin.php?page=' . esc_attr(AIOWPSEC_TOOLS_MENU_SLUG) . '&tab=visitor-lockout">' . esc_html__('Configure', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
}
|
||||
|
||||
public function widget_brute_force() {
|
||||
global $aio_wp_security;
|
||||
if ($aio_wp_security->configs->get_value('aiowps_enable_brute_force_attack_prevention') == '1') {
|
||||
$brute_force_login_feature_link = '<a href="admin.php?page=' . esc_attr(AIOWPSEC_BRUTE_FORCE_MENU_SLUG) . '&tab=cookie-based-brute-force-prevention" target="_blank">' . __('Cookie-based brute force', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
$brute_force_feature_secret_word = $aio_wp_security->configs->get_value('aiowps_brute_force_secret_word');
|
||||
echo '<div class="aio_yellow_box">';
|
||||
/* translators: %s: Brute Force Login URL */
|
||||
echo '<p>' . sprintf(esc_html__('The %s feature is currently active.', 'all-in-one-wp-security-and-firewall'), $brute_force_login_feature_link) . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above.
|
||||
echo '<p>' . esc_html__('Your new WordPress login URL is now:', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
echo '<p><strong>' . esc_url(AIOWPSEC_WP_URL) . '/?' . esc_html($brute_force_feature_secret_word) . '=1</strong></p>';
|
||||
echo '</div>'; //yellow box div
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
}// End if statement for Cookie Based Brute Prevention box
|
||||
|
||||
// Insert Rename Login Page feature box if this feature is active
|
||||
if ($aio_wp_security->configs->get_value('aiowps_enable_rename_login_page') == '1') {
|
||||
if (get_option('permalink_structure')) {
|
||||
$home_url = trailingslashit(home_url());
|
||||
} else {
|
||||
$home_url = trailingslashit(home_url()) . '?';
|
||||
}
|
||||
|
||||
$rename_login_feature_link = '<a href="admin.php?page=' . esc_attr(AIOWPSEC_BRUTE_FORCE_MENU_SLUG) . '&tab=rename-login" target="_blank">' . esc_html__('Rename login page', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
echo '<div class="aio_yellow_box">';
|
||||
/* translators: %s: Rename Login URL */
|
||||
echo '<p>' . sprintf(esc_html__('The %s feature is currently active.', 'all-in-one-wp-security-and-firewall'), $rename_login_feature_link) . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above.
|
||||
echo '<p>' . esc_html__('Your new WordPress login URL is now:', 'all-in-one-wp-security-and-firewall') . '</p>';
|
||||
echo '<p><strong>' . esc_url($home_url) . esc_html($aio_wp_security->configs->get_value('aiowps_login_page_slug')) . '</strong></p>';
|
||||
echo '</div>'; //yellow box div
|
||||
echo '<div class="aio_clear_float"></div>';
|
||||
} // End if statement for Rename Login box
|
||||
}
|
||||
|
||||
/**
|
||||
* This outputs the logged in users dashboard widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function widget_logged_in_users() {
|
||||
$users_online_link = '<a href="admin.php?page=' . AIOWPSEC_USER_SECURITY_MENU_SLUG . '&tab=logged-in-users">'.esc_html__('Logged in users', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
// default display messages
|
||||
$multiple_users_info_msg = esc_html__('Number of users currently logged into your site (including you) is:', 'all-in-one-wp-security-and-firewall');
|
||||
$single_user_info_msg = esc_html__('There are no other users currently logged in.', 'all-in-one-wp-security-and-firewall');
|
||||
|
||||
if (is_multisite()) {
|
||||
$current_blog_id = get_current_blog_id();
|
||||
$is_main = is_main_site($current_blog_id);
|
||||
|
||||
if (empty($is_main)) {
|
||||
// Subsite - only get logged in users for this blog_id
|
||||
$logged_in_users = AIOWPSecurity_User_Login::get_logged_in_users(false);
|
||||
} else {
|
||||
// Main site - get sitewide users
|
||||
$logged_in_users = AIOWPSecurity_User_Login::get_logged_in_users();
|
||||
|
||||
// If viewing AIOS from multisite main network dashboard, then display a different message
|
||||
$multiple_users_info_msg = __('Number of users currently logged in site-wide (including you) is:', 'all-in-one-wp-security-and-firewall');
|
||||
$single_user_info_msg = __('There are no other site-wide users currently logged in.', 'all-in-one-wp-security-and-firewall');
|
||||
}
|
||||
} else {
|
||||
$logged_in_users = AIOWPSecurity_User_Login::get_logged_in_users();
|
||||
}
|
||||
|
||||
if (empty($logged_in_users)) {
|
||||
$num_users = 0;
|
||||
} else {
|
||||
$num_users = count($logged_in_users);
|
||||
}
|
||||
if ($num_users > 1) {
|
||||
echo '<div class="aio_red_box"><p>' . esc_html($multiple_users_info_msg) . ' <strong>' . esc_html($num_users) . '</strong></p>';
|
||||
/* translators: %s: Users Online URL */
|
||||
$info_msg = '<p>' . sprintf(esc_html__('Go to the %s menu to see more details', 'all-in-one-wp-security-and-firewall'), $users_online_link) . '</p>';
|
||||
echo $info_msg . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above.
|
||||
} else {
|
||||
echo '<div class="aio_green_box"><p>' . esc_html($single_user_info_msg) . '</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
public function widget_locked_ip_addresses() {
|
||||
$locked_ips_link = '<a href="admin.php?page=' . esc_attr(AIOWPSEC_MAIN_MENU_SLUG) . '&tab=locked-ip">'. esc_html__('Locked IP addresses', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
|
||||
$locked_ips = AIOWPSecurity_Utility::get_locked_ips();
|
||||
if (false === $locked_ips) {
|
||||
echo '<div class="aio_green_box"><p>' . esc_html__('There are no IP addresses currently locked out.', 'all-in-one-wp-security-and-firewall') . '</p></div>';
|
||||
} else {
|
||||
$num_ips = count($locked_ips);
|
||||
echo '<div class="aio_red_box"><p>' . esc_html__('Number of temporarily locked out IP addresses:', 'all-in-one-wp-security-and-firewall') . ' ' . ' <strong>' . esc_html($num_ips) . '</strong></p>';
|
||||
/* translators: %s: Number of locked out IPs */
|
||||
$info_msg = '<p>' . sprintf(esc_html__('Go to the %s menu to see more details', 'all-in-one-wp-security-and-firewall'), $locked_ips_link) . '</p>';
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above.
|
||||
echo $info_msg . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a security feature should be activated based on its callback.
|
||||
*
|
||||
* This method checks if a feature should be added by evaluating its callback function.
|
||||
* If no callback is set, the feature is added by default. If a callback is set,
|
||||
* it must be callable and return a boolean value.
|
||||
*
|
||||
* @param array $feature An array containing feature details with the following keys:
|
||||
* 'name' => (string) Name of the feature
|
||||
* 'feature_callback' => (callable|null) Optional callback to determine if feature should be added
|
||||
*
|
||||
* @return bool True if the feature should be added, false otherwise
|
||||
*/
|
||||
public static function should_add_feature($feature) {
|
||||
if (empty($feature['feature_callback'])) {
|
||||
return true;
|
||||
} elseif (is_callable($feature['feature_callback'])) {
|
||||
return call_user_func($feature['feature_callback']);
|
||||
} else {
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Part of internal error reporting system.
|
||||
error_log("Callback function set but not callable (coding error). Feature: " . $feature['name']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function creates summary for dashboard widget in table format
|
||||
*
|
||||
* @param array $widget_data title, column names and row data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function dashboard_widget($widget_data) {
|
||||
global $aio_wp_security;
|
||||
$aio_wp_security->include_template('wp-admin/dashboard/widget-summary.php', false, array('widget_data' => $widget_data));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function creates chart for dashboard widget
|
||||
*
|
||||
* @param array $chart_data column names, chart data, last_days and id
|
||||
* @param string $type bar chart
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function dashboard_widget_chart($chart_data, $type = 'bar') {
|
||||
global $aio_wp_security;
|
||||
$aio_wp_security->include_template('wp-admin/dashboard/widget-'.$type.'-chart.php', false, array('chart_data' => $chart_data));
|
||||
}
|
||||
}
|
||||
Executable
+408
@@ -0,0 +1,408 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Database_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Database menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_DB_SEC_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Database security
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('Database security', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return installation or activation link of UpdraftPlus plugin
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
private function get_install_activate_link_of_updraft_plugin() {
|
||||
// If UpdraftPlus is activated, then return empty.
|
||||
if (class_exists('UpdraftPlus')) return '';
|
||||
|
||||
// Generally it is 'updraftplus/updraftplus.php',
|
||||
// but we can't assume that the user hasn't renamed the plugin folder - with 3 million UDP users and 1 million AIOWPS, there will be some who have.
|
||||
$updraftplus_plugin_file_rel_to_plugins_dir = $this->get_updraftplus_plugin_file_rel_to_plugins_dir();
|
||||
|
||||
// If UpdraftPlus is installed but not activated, then return activate link.
|
||||
if ($updraftplus_plugin_file_rel_to_plugins_dir) {
|
||||
$activate_url = add_query_arg(array(
|
||||
'_wpnonce' => wp_create_nonce('activate-plugin_'.$updraftplus_plugin_file_rel_to_plugins_dir),
|
||||
'action' => 'activate',
|
||||
'plugin' => $updraftplus_plugin_file_rel_to_plugins_dir,
|
||||
), network_admin_url('plugins.php'));
|
||||
|
||||
// If is network admin then add to link network activation.
|
||||
if (is_network_admin()) {
|
||||
$activate_url = add_query_arg(array('networkwide' => 1), $activate_url);
|
||||
}
|
||||
return sprintf('<a href="%s">%s</a>',
|
||||
$activate_url,
|
||||
__('UpdraftPlus is installed but currently not active.', 'all-in-one-wp-security-and-firewall') .' '. __('Follow this link to activate UpdraftPlus, to take a backup.', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
}
|
||||
|
||||
// If UpdraftPlus is not activated or installed, then return the installation link
|
||||
return '<a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=updraftplus'), 'install-plugin_updraftplus').'">'.__('Follow this link to install UpdraftPlus, to take a database backup.', 'all-in-one-wp-security-and-firewall').'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path to the UpdraftPlus plugin file relative to the plugins directory.
|
||||
*
|
||||
* @return String|false path to the UpdraftPlus plugin file relative to the plugins directory
|
||||
*/
|
||||
private function get_updraftplus_plugin_file_rel_to_plugins_dir() {
|
||||
if (!function_exists('get_plugins')) {
|
||||
include_once ABSPATH . '/wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
$installed_plugins = get_plugins();
|
||||
$installed_plugins_keys = array_keys($installed_plugins);
|
||||
foreach ($installed_plugins_keys as $plugin_file_rel_to_plugins_dir) {
|
||||
$temp_plugin_file_name = substr($plugin_file_rel_to_plugins_dir, strpos($plugin_file_rel_to_plugins_dir, '/') + 1);
|
||||
if ('updraftplus.php' == $temp_plugin_file_name) {
|
||||
return $plugin_file_rel_to_plugins_dir;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'database-prefix' => array(
|
||||
'title' => __('Database prefix', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_database_prefix'),
|
||||
'display_condition_callback' => 'is_main_site',
|
||||
),
|
||||
'database-backup' => array(
|
||||
'title' => __('Database backup', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_database_backup'),
|
||||
),
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's database prefix tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_database_prefix() {
|
||||
global $wpdb, $aio_wp_security, $aiowps_feature_mgr;
|
||||
$old_db_prefix = $wpdb->prefix;
|
||||
$new_db_prefix = '';
|
||||
$perform_db_change = false;
|
||||
|
||||
if (isset($_POST['aiowps_db_prefix_change'])) { // Do form submission tasks
|
||||
$nonce = $_REQUEST['_wpnonce'];
|
||||
if (!wp_verify_nonce($nonce, 'aiowpsec-db-prefix-change-nonce')) {
|
||||
$aio_wp_security->debug_logger->log_debug("Nonce check failed for DB prefix change operation.", 4);
|
||||
die(__('Nonce check failed for DB prefix change operation.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
// Let's first check if user's system allows writing to wp-config.php file. If plugin cannot write to wp-config we will not do the prefix change.
|
||||
$config_file = AIOWPSecurity_Utility_File::get_wp_config_file_path();
|
||||
$file_write = AIOWPSecurity_Utility_File::is_file_writable($config_file);
|
||||
if (!$file_write) {
|
||||
$this->show_msg_error(__('The plugin has detected that it cannot write to the wp-config.php file.', 'all-in-one-wp-security-and-firewall') . ' ' . __('This feature can only be used if the plugin can successfully write to the wp-config.php file.', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
if (isset($_POST['aiowps_enable_random_prefix'])) { // User has elected to generate a random DB prefix
|
||||
$string = AIOWPSecurity_Utility::generate_alpha_random_string('5');
|
||||
$new_db_prefix = $string . '_';
|
||||
$perform_db_change = true;
|
||||
} else {
|
||||
if (empty($_POST['aiowps_new_manual_db_prefix'])) {
|
||||
$this->show_msg_error(__('Please enter a value for the DB prefix.', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
// User has chosen their own DB prefix value
|
||||
$new_db_prefix = wp_strip_all_tags(trim($_POST['aiowps_new_manual_db_prefix']));
|
||||
if ($new_db_prefix !== $_POST['aiowps_new_manual_db_prefix']) {
|
||||
wp_die("<strong>".__('Error:', 'all-in-one-wp-security-and-firewall')."</strong> ".__('prefix contains HTML tags', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
if (preg_match('|[^a-z0-9_]|i', $new_db_prefix)) {
|
||||
wp_die("<strong>".__('Error:', 'all-in-one-wp-security-and-firewall')."</strong> ".__('prefix contains invalid characters, the prefix should only contain alphanumeric and underscore characters.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
$error = $wpdb->set_prefix($new_db_prefix); // validate the user chosen prefix
|
||||
if (is_wp_error($error)) {
|
||||
wp_die("<strong>".__('Error:', 'all-in-one-wp-security-and-firewall')."</strong> (".$error->get_error_code()."): ".$error->get_error_message());
|
||||
}
|
||||
$wpdb->set_prefix($old_db_prefix);
|
||||
$perform_db_change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($perform_db_change) {
|
||||
// Do the DB prefix change operations
|
||||
$this->change_db_prefix($old_db_prefix, $new_db_prefix);
|
||||
}
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/database-security/database-prefix.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'old_db_prefix' => $old_db_prefix));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's database backup tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_database_backup() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$updraftplus_admin = !empty($GLOBALS['updraftplus_admin']) ? $GLOBALS['updraftplus_admin'] : null;
|
||||
|
||||
if ($updraftplus_admin) {
|
||||
$updraftplus_admin->add_backup_scaffolding(__('Take a database backup using UpdraftPlus', 'all-in-one-wp-security-and-firewall'), array($updraftplus_admin, 'backupnow_modal_contents'));
|
||||
|
||||
}
|
||||
$install_activate_link = $this->get_install_activate_link_of_updraft_plugin();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/database-security/database-backup.php', false, array('install_activate_link' => $install_activate_link));
|
||||
}
|
||||
|
||||
/*
|
||||
* Changes the DB prefix
|
||||
*/
|
||||
/**
|
||||
* This function will change the DB prefix
|
||||
*
|
||||
* @param string $table_old_prefix - the old table prefix
|
||||
* @param string $table_new_prefix - the new table prefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function change_db_prefix($table_old_prefix, $table_new_prefix) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
$old_prefix_length = strlen($table_old_prefix);
|
||||
$error = 0;
|
||||
|
||||
// Config file path
|
||||
$config_file = AIOWPSecurity_Utility_File::get_wp_config_file_path();
|
||||
|
||||
// Get the table resource
|
||||
// $result = mysql_list_tables(DB_NAME);
|
||||
$result = $this->get_mysql_tables(DB_NAME); //Fix for deprecated php mysql_list_tables function
|
||||
|
||||
// Count the number of tables
|
||||
if (is_array($result) && count($result) > 0) {
|
||||
$num_rows = count($result);
|
||||
} else {
|
||||
echo '<div class="aio_red_box"><p>'.__('Error - Could not get tables or no tables found!', 'all-in-one-wp-security-and-firewall').'</p></div>';
|
||||
return;
|
||||
}
|
||||
$table_count = 0;
|
||||
$info_msg_string = '<p class="aio_info_with_icon">'.__('Starting DB prefix change operations.....', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
|
||||
$info_msg_string .= '<p class="aio_info_with_icon">'.sprintf(__('Your WordPress system has a total of %s tables and your new DB prefix will be: %s', 'all-in-one-wp-security-and-firewall'), '<strong>'.$num_rows.'</strong>', '<strong>'.$table_new_prefix.'</strong>').'</p>';
|
||||
echo $info_msg_string;
|
||||
|
||||
// Do a back of the config file
|
||||
if (!AIOWPSecurity_Utility_File::backup_and_rename_wp_config($config_file)) {
|
||||
echo '<div class="aio_red_box"><p>'.__('Failed to make a backup of the wp-config.php file.', 'all-in-one-wp-security-and-firewall') . ' ' .__('This operation will not go ahead.', 'all-in-one-wp-security-and-firewall').'</p></div>';
|
||||
return;
|
||||
} else {
|
||||
echo '<p class="aio_success_with_icon">'.__('A backup copy of your wp-config.php file was created successfully!', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
}
|
||||
|
||||
// Get multisite blog_ids if applicable
|
||||
if (is_multisite()) {
|
||||
$blog_ids = AIOWPSecurity_Utility::get_blog_ids();
|
||||
}
|
||||
|
||||
// Rename all the table names
|
||||
foreach ($result as $db_table) {
|
||||
// Get table name with old prefix
|
||||
$table_old_name = $db_table;
|
||||
|
||||
if (strpos($table_old_name, $table_old_prefix) === 0) {
|
||||
// Get table name with new prefix
|
||||
$table_new_name = AIOWPSecurity_Utility::backquote($table_new_prefix . substr($table_old_name, $old_prefix_length));
|
||||
$table_old_name = AIOWPSecurity_Utility::backquote($table_old_name);
|
||||
|
||||
// Write query to rename tables name
|
||||
$sql = "RENAME TABLE ".$table_old_name." TO ".$table_new_name;
|
||||
// $sql = "RENAME TABLE %s TO %s";
|
||||
|
||||
// Execute the query
|
||||
if (false === $wpdb->query($sql)) {
|
||||
$error = 1;
|
||||
echo '<p class="aio_error_with_icon">'.sprintf(__('%s table name update failed', 'all-in-one-wp-security-and-firewall'), '<strong>'.$table_old_name.'</strong>').'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("DB Security Feature - Unable to change prefix of table ".$table_old_name, 4);
|
||||
} else {
|
||||
$table_count++;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (1 == $error) {
|
||||
echo '<p class="aio_error_with_icon">'.sprintf(__('Please change the prefix manually for the above tables to: %s', 'all-in-one-wp-security-and-firewall'), '<strong>'.$table_new_prefix.'</strong>').'</p>';
|
||||
} else {
|
||||
echo '<p class="aio_success_with_icon">'.sprintf(__('%s tables had their prefix updated successfully!', 'all-in-one-wp-security-and-firewall'), '<strong>'.$table_count.'</strong>').'</p>';
|
||||
}
|
||||
|
||||
// Let's check for mysql tables of type "view"
|
||||
$this->alter_table_views($table_old_prefix, $table_new_prefix);
|
||||
|
||||
// Get wp-config.php file contents and modify it with new info
|
||||
$config_contents = file($config_file);
|
||||
$prefix_match_string = '$table_prefix='; //this is our search string for the wp-config.php file
|
||||
foreach ($config_contents as $line_num => $line) {
|
||||
$no_ws_line = preg_replace('/\s+/', '', $line); //Strip white spaces
|
||||
if (false !== strpos($no_ws_line, $prefix_match_string)) {
|
||||
$prefix_parts = explode("=", $line);
|
||||
$prefix_parts[1] = str_replace($table_old_prefix, $table_new_prefix, $prefix_parts[1]);
|
||||
$config_contents[$line_num] = implode("=", $prefix_parts);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Now let's modify the wp-config.php file
|
||||
if (AIOWPSecurity_Utility_File::write_content_to_file($config_file, $config_contents)) {
|
||||
echo '<p class="aio_success_with_icon">'. __('wp-config.php file was updated successfully!', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
} else {
|
||||
echo '<p class="aio_error_with_icon">'.sprintf(__('The "wp-config.php" file was not able to be modified.', 'all-in-one-wp-security-and-firewall').' '.__('Please modify this file manually using your favourite editor and search for variable "$table_prefix" and assign the following value to that variable: %s', 'all-in-one-wp-security-and-firewall'), '<strong>'.$table_new_prefix.'</strong>').'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("DB Security Feature - Unable to modify wp-config.php", 4);
|
||||
}
|
||||
|
||||
// Now let's update the options table
|
||||
$update_option_table_query = $wpdb->prepare("UPDATE " . $table_new_prefix . "options SET option_name = '".$table_new_prefix ."user_roles' WHERE option_name = %s LIMIT 1", $table_old_prefix."user_roles");
|
||||
|
||||
if (false === $wpdb->query($update_option_table_query)) {
|
||||
echo '<p class="aio_error_with_icon">'.sprintf(__('Update of table %s failed: unable to change %s to %s', 'all-in-one-wp-security-and-firewall'), $table_new_prefix.'options', $table_old_prefix.'user_roles', $table_new_prefix.'user_roles').'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("DB Security Feature - Error when updating the options table", 4);//Log the highly unlikely event of DB error
|
||||
} else {
|
||||
echo '<p class="aio_success_with_icon">'. __('The options table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall') .'</p>';
|
||||
}
|
||||
|
||||
// Now let's update the options tables for the multisite subsites if applicable
|
||||
if (is_multisite()) {
|
||||
if (!empty($blog_ids)) {
|
||||
$main_site_id = get_main_site_id();
|
||||
foreach ($blog_ids as $blog_id) {
|
||||
if ($blog_id == $main_site_id) continue;
|
||||
$new_pref_and_site_id = $table_new_prefix.$blog_id.'_';
|
||||
$old_pref_and_site_id = $table_old_prefix.$blog_id.'_';
|
||||
$update_ms_option_table_query = $wpdb->prepare("UPDATE " . $new_pref_and_site_id . "options SET option_name = '".$new_pref_and_site_id."user_roles' WHERE option_name = %s LIMIT 1", $old_pref_and_site_id."user_roles");
|
||||
if (false === $wpdb->query($update_ms_option_table_query)) {
|
||||
echo '<p class="aio_error_with_icon">'.sprintf(__('Update of table %s failed: unable to change %s to %s', 'all-in-one-wp-security-and-firewall'), $new_pref_and_site_id.'options', $old_pref_and_site_id.'user_roles', $new_pref_and_site_id.'user_roles').'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("DB change prefix feature - Error when updating the subsite options table: ".$new_pref_and_site_id.'options', 4);//Log the highly unlikely event of DB error
|
||||
} else {
|
||||
echo '<p class="aio_success_with_icon">'.sprintf(__('The %s table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall'), $new_pref_and_site_id.'options').'</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Now let's update the user meta table
|
||||
$custom_sql = "SELECT user_id, meta_key FROM " . $table_new_prefix . "usermeta WHERE meta_key LIKE '" . $table_old_prefix . "%'";
|
||||
|
||||
$meta_keys = $wpdb->get_results($custom_sql);
|
||||
|
||||
$error_update_usermeta = '';
|
||||
|
||||
// Update all meta_key field values which have the old table prefix in user_meta table
|
||||
foreach ($meta_keys as $meta_key) {
|
||||
// Create new meta key
|
||||
$new_meta_key = $table_new_prefix . substr($meta_key->meta_key, $old_prefix_length);
|
||||
|
||||
$update_user_meta_sql = $wpdb->prepare("UPDATE " . $table_new_prefix . "usermeta SET meta_key='" . $new_meta_key . "' WHERE meta_key=%s AND user_id=%s", $meta_key->meta_key, $meta_key->user_id);
|
||||
|
||||
if (false === $wpdb->query($update_user_meta_sql)) {
|
||||
$error_update_usermeta .= '<p class="aio_error_with_icon">'.sprintf(__('Error updating user_meta table where new meta_key = %s, old meta_key = %s and user_id = %s.', 'all-in-one-wp-security-and-firewall'), $new_meta_key, $meta_key->meta_key, $meta_key->user_id).'</p>';
|
||||
echo $error_update_usermeta;
|
||||
$aio_wp_security->debug_logger->log_debug("DB Security Feature - Error updating user_meta table where new meta_key = ".$new_meta_key." old meta_key = ".$meta_key->meta_key." and user_id = ".$meta_key->user_id, 4);//Log the highly unlikely event of DB error
|
||||
}
|
||||
}
|
||||
echo '<p class="aio_success_with_icon">'.__('The usermeta table records which had references to the old DB prefix were updated successfully!', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
// Display tasks finished message
|
||||
$tasks_finished_msg_string = '<p class="aio_info_with_icon">'. __('The database prefix change tasks have been completed.', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo $tasks_finished_msg_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an alternative to the deprecated "mysql_list_tables
|
||||
*
|
||||
* @param string $database - database name
|
||||
*
|
||||
* @returns array - an array of table names
|
||||
*/
|
||||
public function get_mysql_tables($database = '') {
|
||||
global $aio_wp_security;
|
||||
$tables = array();
|
||||
$list_tables_sql = "SHOW TABLES FROM `{$database}`;";
|
||||
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
|
||||
|
||||
if ($mysqli->connect_errno) {
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_Database_Menu->get_mysql_tables() - DB connection error.", 4);
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $mysqli->query($list_tables_sql, MYSQLI_USE_RESULT);
|
||||
if ($result) {
|
||||
//Alternative way to get the tables
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
foreach ($row as $value) {
|
||||
$tables[] = $value;
|
||||
}
|
||||
}
|
||||
$result->close();
|
||||
}
|
||||
$mysqli->close();
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will modify existing table view definitions to reflect the new DB prefix change
|
||||
*
|
||||
* @param string $old_db_prefix - old database prefix
|
||||
* @param string $new_db_prefix - new database prefix
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
private function alter_table_views($old_db_prefix, $new_db_prefix) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
$db_name = $wpdb->dbname;
|
||||
$info_msg_string = '<p class="aio_info_with_icon">'.__('Checking for MySQL tables of type "view".....', 'all-in-one-wp-security-and-firewall').'</p>';
|
||||
echo $info_msg_string;
|
||||
|
||||
// get tables which are views
|
||||
$query = "SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA LIKE '".$db_name."'";
|
||||
$res = $wpdb->get_results($query);
|
||||
if (empty($res)) return;
|
||||
$view_count = 0;
|
||||
foreach ($res as $item) {
|
||||
$old_def = $item->VIEW_DEFINITION;
|
||||
$new_def = AIOWPSecurity_Utility::str_replace_once($old_db_prefix, $new_db_prefix, $old_def);
|
||||
$new_def = AIOWPSecurity_Utility::backquote($new_def);
|
||||
|
||||
$view_name = AIOWPSecurity_Utility::backquote($item->TABLE_NAME);
|
||||
$chg_view_sql = "ALTER VIEW $view_name AS $new_def";
|
||||
$view_res = $wpdb->query($chg_view_sql);
|
||||
if (false === $view_res) {
|
||||
echo '<p class="aio_error_with_icon">'.sprintf(__('Update of the following MySQL view definition failed: %s', 'all-in-one-wp-security-and-firewall'), $old_def).'</p>';
|
||||
$aio_wp_security->debug_logger->log_debug("Update of the following MySQL view definition failed: ".$old_def, 4);//Log the highly unlikely event of DB error
|
||||
} else {
|
||||
$view_count++;
|
||||
}
|
||||
}
|
||||
if ($view_count > 0) {
|
||||
echo '<p class="aio_success_with_icon">'.sprintf(__('%s view definitions were updated successfully.', 'all-in-one-wp-security-and-firewall'), '<strong>'.$view_count.'</strong>').'</p>';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* AIOWPSecurity_Filescan_Menu class for scanning file changes, maleware and available updates.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
class AIOWPSecurity_Filescan_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* File scan menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_FILESCAN_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Scanner
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('Scanner', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'file-change-detect' => array(
|
||||
'title' => __('File change detection', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_file_change_detect'),
|
||||
),
|
||||
'malware-scan' => array(
|
||||
'title' => __('Malware scan', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_malware_scan'),
|
||||
),
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* File change detection on your system files.
|
||||
*
|
||||
* @global $wpdb
|
||||
* @global $aio_wp_security
|
||||
* @global $aiowps_feature_mgr
|
||||
*/
|
||||
protected function render_file_change_detect() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aios_commands = new AIOWPSecurity_Commands();
|
||||
|
||||
$scanner_data = $aios_commands->get_scanner_data();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/scanner/file-change-detect.php', false, $scanner_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Malware code scan on your system files.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_malware_scan() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/scanner/malware-scan.php', false, array());
|
||||
}
|
||||
}
|
||||
Executable
+144
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Prevent direct access to file
|
||||
}
|
||||
class AIOWPSecurity_Filesystem_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Filesystem menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_FILESYSTEM_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Filesystem security
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('File security', 'all-in-one-wp-security-and-firewall'));
|
||||
add_action('admin_footer', array($this, 'filesystem_menu_footer_code'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'file-permissions' => array(
|
||||
'title' => __('File permissions', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_file_permissions'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'file-protection' => array(
|
||||
'title' => __('File protection', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_file_protection'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'host-system-logs' => array(
|
||||
'title' => __('Host system logs', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_host_system_logs'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'copy-protection' => array(
|
||||
'title' => __('Copy protection', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_copy_protection'),
|
||||
),
|
||||
'frames' => array(
|
||||
'title' => __('Frames', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_frames'),
|
||||
),
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's file permissions tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_file_permissions() {
|
||||
// if this is the case there is no need to display a "fix permissions" button
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
$files_dirs_to_check = AIOWPSecurity_Utility_File::get_files_and_dirs_to_check();
|
||||
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/filesystem-security/file-permissions.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'files_dirs_to_check' => $files_dirs_to_check, 'file_utility' => new AIOWPSecurity_Utility_File()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's 'File protection' tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_file_protection() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$show_disallow_file_edit_warning = defined('DISALLOW_FILE_EDIT') && DISALLOW_FILE_EDIT && '1' != $aio_wp_security->configs->get_value('aiowps_disable_file_editing');
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/filesystem-security/file-protection.php', false, array('show_disallow_file_edit_warning' => $show_disallow_file_edit_warning));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's copy protection tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_copy_protection() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/filesystem-security/copy-protection.php', false, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's render frames tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_frames() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/filesystem-security/frames.php', false, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's host system logs tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_host_system_logs() {
|
||||
global $aio_wp_security;
|
||||
$sys_log_file = basename($aio_wp_security->configs->get_value('aiowps_system_log_file'));
|
||||
$aio_wp_security->include_template('wp-admin/filesystem-security/host-system-logs.php', false, array('sys_log_file' => $sys_log_file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called via filter admin_footer, this adds the needed javascript to page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filesystem_menu_footer_code() {
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
/* <![CDATA[ */
|
||||
jQuery(function($) {
|
||||
loading_span = $('.aiowps_loading_1');
|
||||
loading_span.hide(); //hide the spinner gif after page has successfully loaded
|
||||
$('.search-error-files').on("click",function(){
|
||||
loading_span.show();
|
||||
});
|
||||
});
|
||||
|
||||
function set_file_permission_tochange(path, recommended) {
|
||||
jQuery('#aiowps_permission_chg_file').val(path);
|
||||
jQuery('#aiowps_recommended_permissions').val(recommended);
|
||||
return true;
|
||||
}
|
||||
/* ]]> */
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
Executable
+188
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
use AIOWPS\Firewall\Allow_List;
|
||||
|
||||
class AIOWPSecurity_Firewall_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Firewall menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_FIREWALL_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Firewall
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('Firewall', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'php-rules' => array(
|
||||
'title' => __('PHP rules', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_php_rules'),
|
||||
),
|
||||
'htaccess-rules' => array(
|
||||
'title' => __('.htaccess rules', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_htaccess_rules'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess'),
|
||||
),
|
||||
'6g-firewall' => array(
|
||||
'title' => __('6G firewall rules', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_6g_firewall'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'5g-firewall' => array(
|
||||
'title' => __('5G legacy rules', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_5g_firewall'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility', 'render_5g_legacy_tab'),
|
||||
),
|
||||
'internet-bots' => array(
|
||||
'title' => __('Internet bots', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_internet_bots'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'block-and-allow-lists' => array(
|
||||
'title' => __('Block & allow lists', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_block_and_allow_lists'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'advanced-settings' => array(
|
||||
'title' => __('Advanced settings', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_advanced_settings'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
)
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the PHP Firewall settings tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_php_rules() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aios_commands = new AIOWPSecurity_Commands();
|
||||
|
||||
$php_firewall_data = $aios_commands->get_php_firewall_data();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/firewall/php-firewall-rules.php', false, compact('php_firewall_data'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the Htaccess Firewall tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_htaccess_rules() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aios_commands = new AIOWPSecurity_Commands();
|
||||
|
||||
$htaccess_rules_data = $aios_commands->get_htaccess_rules_data();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/firewall/htaccess-firewall-rules.php', false, compact('htaccess_rules_data'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the 6G Blacklist Firewall Rules tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_6g_firewall() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/general/moved.php', false, array('key' => '6g'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the 5G Blacklist Firewall Rules tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_5g_firewall() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/firewall/5g.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the Internet Bots tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_internet_bots() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/general/moved.php', false, array('key' => 'internet-bots'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders the Advanced settings tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_advanced_settings() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aios_commands = new AIOWPSecurity_Commands();
|
||||
|
||||
$advanced_settings_data = $aios_commands->get_firewall_advanced_settings_data();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/firewall/advanced-settings.php', false, compact('advanced_settings_data'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders ban user tab for blacklist IPs and user agents
|
||||
*
|
||||
* @global $aio_wp_security
|
||||
* @global $aiowps_feature_mgr
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_block_and_allow_lists() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aios_commands = new AIOWPSecurity_Commands();
|
||||
|
||||
$block_allowlist_data = $aios_commands->get_block_allow_lists_data();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/firewall/block-and-allow-lists.php', false, $block_allowlist_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates posted user agent list and set, save as config.
|
||||
*
|
||||
* @global $aio_wp_security
|
||||
* @global $aiowps_firewall_config
|
||||
*
|
||||
* @param string $banned_user_agents
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function validate_user_agent_list($banned_user_agents) {
|
||||
global $aio_wp_security;
|
||||
$aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG);
|
||||
$submitted_agents = AIOWPSecurity_Utility::splitby_newline_trim_filter_empty($banned_user_agents);
|
||||
$agents = array_unique(array_filter(array_map('sanitize_text_field', $submitted_agents), 'strlen'));
|
||||
$aio_wp_security->configs->set_value('aiowps_banned_user_agents', implode("\n", $agents));
|
||||
$aiowps_firewall_config->set_value('aiowps_blacklist_user_agents', $agents);
|
||||
$_POST['aiowps_banned_user_agents'] = ''; // Clear the post variable for the banned address list
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Executable
+646
@@ -0,0 +1,646 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; //Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Firewall_Setup_Notice {
|
||||
|
||||
/**
|
||||
* Holds reference to an instance of itself
|
||||
*
|
||||
* @var AIOWPSecurity_Firewall_Setup_Notice
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Holds our wp-config file wrapped in our manager class
|
||||
*
|
||||
* @var AIOWPSecurity_Block_WpConfig
|
||||
*/
|
||||
private $wpconfig;
|
||||
|
||||
/**
|
||||
* Holds our mu-plugin file wrapped in our manager class
|
||||
*
|
||||
* @var AIOWPSecurity_Block_Muplugin
|
||||
*/
|
||||
private $muplugin;
|
||||
|
||||
/**
|
||||
* Holds our bootstrap file wrapped in our manager class
|
||||
*
|
||||
* @var AIOWPSecurity_Block_Bootstrap
|
||||
*/
|
||||
private $bootstrap;
|
||||
|
||||
/**
|
||||
* Constants for the different notice types
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const NOTICE_BOOTSTRAP = 'manual_bootstrap';
|
||||
const NOTICE_MANUAL = 'manual';
|
||||
const NOTICE_INSTALLED = 'success';
|
||||
const NOTICE_DIRECTIVE_SET = 'userini_directive';
|
||||
|
||||
/**
|
||||
* Constructs our object by setting up our essential files
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->bootstrap = AIOWPSecurity_Utility_Firewall::get_bootstrap_file();
|
||||
$this->wpconfig = AIOWPSecurity_Utility_Firewall::get_wpconfig_file();
|
||||
$this->muplugin = AIOWPSecurity_Utility_Firewall::get_muplugin_file();
|
||||
AIOWPSecurity_Utility_Firewall::get_firewall_rules_path(true); // Creates the needed directories for the first time.
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point for the dashboard notice
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function start_firewall_setup() {
|
||||
|
||||
global $aio_wp_security;
|
||||
|
||||
$firewall_files = array(
|
||||
'server' => AIOWPSecurity_Utility_Firewall::get_server_file(),
|
||||
'bootstrap' => $this->bootstrap,
|
||||
'wpconfig' => $this->wpconfig,
|
||||
'muplugin' => $this->muplugin,
|
||||
);
|
||||
|
||||
//Check each file and update the contents if necessary
|
||||
foreach ($firewall_files as $name => $file) {
|
||||
${'is_firewall_in_'.$name} = false;
|
||||
|
||||
if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP === $file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
${'is_firewall_in_'.$name} = $file->contains_contents();
|
||||
|
||||
if (true === ${'is_firewall_in_'.$name}) {
|
||||
$file->update_contents();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$aio_wp_security->is_aiowps_admin_page()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (AIOWPSecurity_Utility_Firewall::is_firewall_setup()) {
|
||||
if (true !== $is_firewall_in_server) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- variable is set in the foreach loop
|
||||
$this->render_upgrade_protection_notice();
|
||||
}
|
||||
} else {
|
||||
$this->render_automatic_setup_notice();
|
||||
}
|
||||
|
||||
$this->render_notices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will execute when the user presses 'Set up now' button
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function do_setup() {
|
||||
|
||||
$is_inserted_firewall_file = false;
|
||||
|
||||
$is_inserted_bootstrap_file = $this->bootstrap->contains_contents();
|
||||
if (true !== $is_inserted_bootstrap_file) {
|
||||
$is_inserted_bootstrap_file = $this->bootstrap->insert_contents();
|
||||
|
||||
if (true !== $is_inserted_bootstrap_file) {
|
||||
$this->log_wp_error($is_inserted_bootstrap_file);
|
||||
$this->show_notice(self::NOTICE_BOOTSTRAP);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file();
|
||||
|
||||
if ($firewall_file instanceof AIOWPSecurity_Block_Userini) {
|
||||
|
||||
$directive = AIOWPSecurity_Utility_Firewall::get_already_set_directive($firewall_file);
|
||||
|
||||
if (!empty($directive)) {
|
||||
|
||||
if (AIOWPSecurity_Utility_Firewall::get_bootstrap_path() === $directive) {
|
||||
$is_inserted_firewall_file = true;
|
||||
} else {
|
||||
$this->show_notice(self::NOTICE_DIRECTIVE_SET, array('directive' => $directive));
|
||||
}
|
||||
|
||||
} else {
|
||||
$is_inserted_firewall_file = $firewall_file->insert_contents();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP !== $firewall_file) {
|
||||
$is_inserted_firewall_file = $firewall_file->insert_contents(); // attempts to insert firewall into required file
|
||||
}
|
||||
}
|
||||
|
||||
//Set up the firewall in the wp-config file
|
||||
$is_inserted_wpconfig = $this->wpconfig->contains_contents();
|
||||
if (true !== $is_inserted_wpconfig) {
|
||||
$is_inserted_wpconfig = $this->wpconfig->insert_contents();
|
||||
}
|
||||
$this->log_wp_error($is_inserted_wpconfig);
|
||||
|
||||
//Set up the firewall in the mu-plugin
|
||||
$is_inserted_muplugin = $this->muplugin->contains_contents();
|
||||
if (true !== $is_inserted_muplugin) {
|
||||
$is_inserted_muplugin = $this->muplugin->insert_contents();
|
||||
}
|
||||
if (false === $is_inserted_muplugin) {
|
||||
$this->log_wp_error(new \WP_Error(
|
||||
'file-mu-plugin-failed',
|
||||
'Unable to create the mu-plugin',
|
||||
$this->muplugin
|
||||
));
|
||||
}
|
||||
$this->log_wp_error($is_inserted_muplugin);
|
||||
|
||||
if (true === $is_inserted_firewall_file) {
|
||||
$this->show_notice(self::NOTICE_INSTALLED);
|
||||
} else {
|
||||
$this->log_wp_error($is_inserted_firewall_file);
|
||||
$this->show_notice(self::NOTICE_MANUAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the notice.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function do_dismiss() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->configs->set_value('aios_firewall_dismiss', true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the notice is dismissed
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function is_dismissed() {
|
||||
global $aio_wp_security;
|
||||
return (true === $aio_wp_security->configs->get_value('aios_firewall_dismiss'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the form submission for the 'Set up now' notice
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle_setup_form() {
|
||||
$nonce = isset($_POST['_wpnonce']) ? $_POST['_wpnonce'] : '';
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-setup');
|
||||
if (!is_wp_error($result)) {
|
||||
$this->do_setup();
|
||||
$this->do_redirect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the dismiss form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle_dismiss_form() {
|
||||
$nonce = isset($_POST['_wpnonce']) ? $_POST['_wpnonce'] : '';
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-setup-dismiss');
|
||||
if (!is_wp_error($result)) {
|
||||
$this->do_dismiss();
|
||||
$this->do_redirect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the form that downgrades the firewall's protection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle_downgrade_protection_form() {
|
||||
$nonce = isset($_POST['_wpnonce']) ? $_POST['_wpnonce'] : '';
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-downgrade');
|
||||
if (!is_wp_error($result)) {
|
||||
AIOWPSecurity_Utility_Firewall::remove_firewall();
|
||||
$this->do_redirect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the redirect
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function do_redirect() {
|
||||
|
||||
// Go back to the previous page and tab if set
|
||||
if (isset($_POST['_wp_http_referer'])) {
|
||||
|
||||
$matches = array();
|
||||
if (preg_match('/\?page='.AIOWPSEC_MENU_SLUG_PREFIX.'(?<page>.*)(&tab=(?<tab>.*))?$/m', $_POST['_wp_http_referer'], $matches)) {
|
||||
$url = 'admin.php?page='.AIOWPSEC_MENU_SLUG_PREFIX;
|
||||
|
||||
if (isset($matches['page'])) {
|
||||
$url .= sanitize_text_field($matches['page']);
|
||||
|
||||
if (isset($matches['tab'])) {
|
||||
$url .= '&tab='.sanitize_text_field($matches['tab']);
|
||||
}
|
||||
}
|
||||
|
||||
AIOWPSecurity_Utility::redirect_to_url(admin_url(sanitize_url($url)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AIOWPSecurity_Utility::redirect_to_url(admin_url('admin.php?page='.AIOWPSEC_MENU_SLUG_PREFIX));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function to log WP_Errors to debug log
|
||||
*
|
||||
* @param WP_Error $wp_error - Our error which gets logged
|
||||
* @return void
|
||||
*/
|
||||
private function log_wp_error($wp_error) {
|
||||
|
||||
if (is_wp_error($wp_error)) {
|
||||
global $aio_wp_security;
|
||||
|
||||
$error_message = $wp_error->get_error_message();
|
||||
$error_message .= ' - ';
|
||||
$error_message .= $wp_error->get_error_data();
|
||||
$aio_wp_security->debug_logger->log_debug($error_message, 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flags to show notices
|
||||
*
|
||||
* @param string $type - the type of notice we want to set
|
||||
* @param array $values - any values that need to be passed
|
||||
* @return void
|
||||
*/
|
||||
private function show_notice($type, $values = array()) {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->configs->set_value('firewall_notice_'.$type, true);
|
||||
|
||||
if (!empty($values)) {
|
||||
$aio_wp_security->configs->set_value('firewall_notice_values', $values);
|
||||
}
|
||||
|
||||
$aio_wp_security->configs->save_config();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders any necessary notices
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_notices() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$notices = array(
|
||||
self::NOTICE_BOOTSTRAP,
|
||||
self::NOTICE_MANUAL,
|
||||
self::NOTICE_INSTALLED,
|
||||
self::NOTICE_DIRECTIVE_SET,
|
||||
);
|
||||
|
||||
foreach ($notices as $notice) {
|
||||
if ($aio_wp_security->configs->get_value('firewall_notice_'.$notice)) {
|
||||
|
||||
switch ($notice) {
|
||||
case self::NOTICE_BOOTSTRAP:
|
||||
$this->render_bootstrap_notice();
|
||||
break;
|
||||
case self::NOTICE_MANUAL:
|
||||
if (!$this->any_pending_notices(self::NOTICE_MANUAL)) {
|
||||
$this->render_manual_setup_notice();
|
||||
}
|
||||
break;
|
||||
case self::NOTICE_INSTALLED:
|
||||
$this->render_firewall_installed_notice();
|
||||
break;
|
||||
case self::NOTICE_DIRECTIVE_SET:
|
||||
$values = $aio_wp_security->configs->get_value('firewall_notice_values');
|
||||
$this->render_userini_directive_set_notice($values['directive']);
|
||||
$aio_wp_security->configs->delete_value('firewall_notice_values');
|
||||
break;
|
||||
}
|
||||
|
||||
$aio_wp_security->configs->delete_value('firewall_notice_'.$notice);
|
||||
}
|
||||
}
|
||||
|
||||
$aio_wp_security->configs->save_config();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if we have any notices pending to display
|
||||
*
|
||||
* @param string ...$exclude - do not check the status of these notices
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function any_pending_notices(...$exclude) {
|
||||
global $aio_wp_security;
|
||||
|
||||
$notices = array(
|
||||
self::NOTICE_BOOTSTRAP,
|
||||
self::NOTICE_MANUAL,
|
||||
self::NOTICE_INSTALLED,
|
||||
self::NOTICE_DIRECTIVE_SET,
|
||||
);
|
||||
$notices = array_diff($notices, $exclude);
|
||||
|
||||
foreach ($notices as $notice) {
|
||||
if (true === $aio_wp_security->configs->get_value('firewall_notice_'.$notice)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice is shown if we are unable to write to the bootstrap file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_bootstrap_notice() {
|
||||
?>
|
||||
<div class="notice notice-error is-dismissible">
|
||||
<p>
|
||||
<strong><?php _e('All-In-One Security', 'all-in-one-wp-security-and-firewall'); ?></strong>
|
||||
</p>
|
||||
<p><?php _e('We were unable to create the file necessary to give you the highest level of protection.', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<p><?php _e('Your firewall will have reduced protection which means some of your firewall\'s functionality will be unavailable.', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<p><?php _e('If you would like to manually set up the necessary file, please follow these steps:', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<p>
|
||||
<?php
|
||||
/* translators: %s Bootstrap file name. */
|
||||
printf(__('1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:', 'all-in-one-wp-security-and-firewall'), pathinfo($this->bootstrap, PATHINFO_BASENAME));
|
||||
?>
|
||||
</p>
|
||||
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo esc_html($this->bootstrap); ?></pre>
|
||||
<p><?php _e('2. Paste in the following code:', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo htmlentities($this->bootstrap->get_contents()); ?></pre>
|
||||
<p><?php _e('3. Save the file and press the \'Try again\' button below:', 'all-in-one-wp-security-and-firewall');?></p>
|
||||
<?php
|
||||
$this->render_try_again_button();
|
||||
$this->render_manual_notice_footer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice is shown if auto_prepend_file directive is already set in user.ini
|
||||
*
|
||||
* @param string $directive_value
|
||||
* @return void
|
||||
*/
|
||||
private function render_userini_directive_set_notice($directive_value) {
|
||||
|
||||
$firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file();
|
||||
|
||||
$this->render_manual_notice_header();
|
||||
?>
|
||||
<p>
|
||||
<?php _e('1. Open the following file:', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<p><code><?php echo esc_html($firewall_file); ?></code></p>
|
||||
|
||||
<?php if (empty($directive_value)) {?>
|
||||
<p>
|
||||
<?php _e('2. Look for the auto_prepend_file directive.', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<?php } else {?>
|
||||
<p>
|
||||
<?php _e('2. Look for the following:', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo "auto_prepend_file='".esc_html($directive_value)."'";?></pre>
|
||||
<?php } ?>
|
||||
|
||||
<p>
|
||||
<?php _e('3. Change it to the following:', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo esc_html(AIOWPSecurity_Utility_Firewall::get_server_file()->get_contents()); ?></pre>
|
||||
<p>
|
||||
<?php echo __('4. Save the file and press the \'Try again\' button below:', 'all-in-one-wp-security-and-firewall').' '.__('You may have to wait up to 5 minutes before the settings take effect.', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<?php
|
||||
$this->render_try_again_button();
|
||||
$this->render_manual_notice_footer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows when the firewall has successfully installed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_firewall_installed_notice() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('notices/firewall-installed-notice.php', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the 'manual setup' dashboard notice
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_manual_setup_notice() {
|
||||
|
||||
$firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file();
|
||||
|
||||
if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP === $firewall_file) {
|
||||
//Show users how to manually add the firewall via php.ini if we can't detect their server
|
||||
$bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path();
|
||||
|
||||
$this->render_manual_notice_header();
|
||||
?>
|
||||
<p>
|
||||
<?php _e('1. Open your php.ini file.', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<p>
|
||||
<?php _e('2. Set the auto_prepend_file directive like below:', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo "auto_prepend_file='".esc_html($bootstrap_path)."'";?></pre>
|
||||
<p>
|
||||
<?php echo __('3. Restart the webserver and refresh the page', 'all-in-one-wp-security-and-firewall').' '.__('You may have to wait up to 5 minutes before the settings take effect.', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<?php
|
||||
$this->render_manual_notice_footer();
|
||||
} else {
|
||||
//Show users how to manually add the firewall via their own server file
|
||||
$this->render_manual_notice_header();
|
||||
$firewall_file_name = pathinfo($firewall_file, PATHINFO_BASENAME);
|
||||
?>
|
||||
<p>
|
||||
<?php
|
||||
/* translators: %s Firewall file name. */
|
||||
printf(__('1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:', 'all-in-one-wp-security-and-firewall'), $firewall_file_name);
|
||||
?>
|
||||
<p><code><?php echo esc_html($firewall_file); ?></code></p>
|
||||
</p>
|
||||
<p>
|
||||
<?php _e('2. Paste in the following directives:', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo htmlentities($firewall_file->get_contents()); ?></pre>
|
||||
<p>
|
||||
<?php echo __('3. Save the file and press the \'Try again\' button below:', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<?php
|
||||
$this->render_try_again_button();
|
||||
$this->render_manual_notice_footer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The header for notices that require manual intervention
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_manual_notice_header() {
|
||||
?>
|
||||
<div class="notice notice-warning is-dismissible">
|
||||
<p>
|
||||
<strong><?php _e('All-In-One Security', 'all-in-one-wp-security-and-firewall'); ?></strong>
|
||||
</p>
|
||||
<p>
|
||||
<?php echo __('We were unable to set up your firewall with the highest level of protection.', 'all-in-one-wp-security-and-firewall').' '.
|
||||
__('Your firewall will have reduced functionality.', 'all-in-one-wp-security-and-firewall');
|
||||
?>
|
||||
</p>
|
||||
<p>
|
||||
<?php _e('To give your site the highest level of protection, please follow these steps:', 'all-in-one-wp-security-and-firewall'); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* The footer for notices that require manual intervention
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_manual_notice_footer() {
|
||||
?>
|
||||
<p>
|
||||
<strong><?php _e('Note: if you\'re unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance.', 'all-in-one-wp-security-and-firewall'); ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Try again button.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_try_again_button() {
|
||||
?>
|
||||
<form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-firewall-setup'); ?>
|
||||
<input type="hidden" name="action" value="aiowps_firewall_setup">
|
||||
<div style="padding-top: 10px; padding-bottom: 10px;">
|
||||
<input class="button button-primary" type="submit" name="btn_try_again" value="<?php _e('Try again', 'all-in-one-wp-security-and-firewall'); ?>">
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the warning that users do not have the highest level of protection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_upgrade_protection_notice() {
|
||||
|
||||
if ($this->should_not_show_notice()) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="notice notice-warning">
|
||||
<form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="POST">
|
||||
<?php wp_nonce_field('aiowpsec-firewall-setup'); ?>
|
||||
<input type="hidden" name="action" value="aiowps_firewall_setup">
|
||||
<p>
|
||||
<?php _e('We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection.', 'all-in-one-wp-security-and-firewall');?>
|
||||
<?php echo ' ' . __('Your firewall will have reduced functionality until it has been upgraded.', 'all-in-one-wp-security-and-firewall');?>
|
||||
<div style="padding-top: 10px;">
|
||||
<input class="button button-primary" type="submit" name="btn_upgrade_now" value="<?php _e('Upgrade your protection now', 'all-in-one-wp-security-and-firewall'); ?>">
|
||||
</div>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the firewall notice should not be shown.
|
||||
*
|
||||
* @return boolean True if the firewall notice should not be shown otherwise false.
|
||||
*/
|
||||
private function should_not_show_notice() {
|
||||
if (!is_main_site()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->is_dismissed() && !AIOWPSecurity_Utility_Firewall::is_firewall_page()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->any_pending_notices()) {
|
||||
return true; //only display if there are no other notices waiting to be displayed
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the 'Set up now' dashboard notice
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_automatic_setup_notice() {
|
||||
global $aio_wp_security;
|
||||
|
||||
if ($this->should_not_show_notice()) {
|
||||
return;
|
||||
}
|
||||
$aio_wp_security->include_template('notices/firewall-setup-notice.php', false, array('show_dismiss' => !AIOWPSecurity_Utility_Firewall::is_firewall_page()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures only one instance of the class can be created (singleton)
|
||||
*
|
||||
* @return AIOWPSecurity_Firewall_Setup_Notice|null
|
||||
*/
|
||||
public static function get_instance() {
|
||||
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
||||
+362
@@ -0,0 +1,362 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_404 extends AIOWPSecurity_List_Table {
|
||||
|
||||
public function __construct() {
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns created column in datetime format as per user setting time zone.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the datetime
|
||||
*/
|
||||
public function column_created($item) {
|
||||
return AIOWPSecurity_Utility::convert_timestamp($item['created']);
|
||||
}
|
||||
|
||||
public function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns id column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - html string for column rendered
|
||||
*/
|
||||
public function column_id($item) {
|
||||
$ip = $item['ip_or_host'];
|
||||
|
||||
$is_locked = AIOWPSecurity_Utility::check_locked_ip($ip, '404');
|
||||
$blacklist_tab = 'blacklist';
|
||||
$is_blacklist = AIOWPSecurity_Utility::check_blacklist_ip($ip);
|
||||
$actions = array();
|
||||
$actions['delete'] = '<a class="aios-delete-404" data-id="' . esc_attr($item['id']) . '" data-message="' . esc_js(__('Are you sure you want to delete this item?', 'all-in-one-wp-security-and-firewall')) . '" href="#">' . __('Delete', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
|
||||
if ($is_locked) {
|
||||
// Build row actions for locked items
|
||||
$actions['unblock'] = '<a class="aios-unblock-404" data-ip="' . esc_attr($ip) . '" data-message="' . esc_js(__('Are you sure you want to unblock this item?', 'all-in-one-wp-security-and-firewall')) . '" href="#">' . __('Unblock', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
} elseif ($is_blacklist) {
|
||||
$unblock_url_nonce = wp_nonce_url(sprintf('admin.php?page=%s&tab=%s', AIOWPSEC_FIREWALL_MENU_SLUG, $blacklist_tab), "404_log_item_action", "aiowps_nonce");
|
||||
$actions = array(
|
||||
'unblock' => '<a href="'.$unblock_url_nonce.'" onclick="return confirm(\'' . esc_js(__('Are you sure you want to unblock this item?', 'all-in-one-wp-security-and-firewall')) . '\')">'.__('Unblock', 'all-in-one-wp-security-and-firewall').'</a>',
|
||||
);
|
||||
} else {
|
||||
// Build row actions for other items
|
||||
$actions['temp_block'] = '<a class="aios-temp-block-404" data-ip="' . esc_attr($ip) . '" data-message="' . esc_js(__('Are you sure you want to block this IP address?', 'all-in-one-wp-security-and-firewall')) . '" data-username="' . esc_attr($item['username']) . '" href="#">' . __('Temporarily block', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
$actions['blacklist_ip'] = '<a class="aios-blacklist-404" data-ip="' . esc_attr($ip) . '" data-message="' . esc_js(__('Are you sure you want to permanently block this IP address?', 'all-in-one-wp-security-and-firewall')) . '" href="#">' . __('Blacklist IP', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
}
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/* $1%s */ $item['id'],
|
||||
/* $2%s */ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns status column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - html string for column rendered
|
||||
*/
|
||||
public function column_status($item) {
|
||||
global $aio_wp_security;
|
||||
$ip = $item['ip_or_host'];
|
||||
//Check if this IP address is locked
|
||||
$is_locked = AIOWPSecurity_Utility::check_locked_ip($ip, '404');
|
||||
$blacklisted_string = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses');
|
||||
$banned = strpos($blacklisted_string, $ip);
|
||||
|
||||
if (false !== $banned) {
|
||||
return 'blacklisted';
|
||||
} elseif ($is_locked) {
|
||||
return 'temporarily blocked';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns checkbox column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - html string for column rendered
|
||||
*/
|
||||
public function column_cb($item) {
|
||||
return sprintf('<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/* $1%s */ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/* $2%s */ $item['id'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
public function get_columns() {
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'id' => 'ID',
|
||||
'event_type' => __('Event type', 'all-in-one-wp-security-and-firewall'),
|
||||
'ip_or_host' => __('IP address', 'all-in-one-wp-security-and-firewall'),
|
||||
'url' => __('Attempted URL', 'all-in-one-wp-security-and-firewall'),
|
||||
'referer_info' => __('Referer', 'all-in-one-wp-security-and-firewall'),
|
||||
'created' => __('Date and time', 'all-in-one-wp-security-and-firewall'),
|
||||
'status' => __('Lock status', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
$columns = apply_filters('list_404_get_columns', $columns);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'id' => array('id', false),
|
||||
'event_type' => array('event_type', false),
|
||||
'ip_or_host' => array('ip_or_host', false),
|
||||
'url' => array('url', false),
|
||||
'referer_info' => array('referer_info', false),
|
||||
'created' => array('created', false),
|
||||
);
|
||||
$sortable_columns = apply_filters('list_404_get_sortable_columns', $sortable_columns);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bulk actions for the current WordPress screen.
|
||||
*
|
||||
* @return array An associative array of bulk actions where the keys are action names
|
||||
* and the values are the corresponding action labels.
|
||||
*/
|
||||
public function get_bulk_actions() {
|
||||
return array(
|
||||
//'unlock' => 'Unlock',
|
||||
'bulk_block_ip' => __('Temporarily block IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'bulk_blacklist_ip' => __('Blacklist IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'delete' => __('Delete', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process bulk actions for the current WordPress screen.
|
||||
*
|
||||
* This method checks for the presence of a valid nonce and user capabilities,
|
||||
* then performs the appropriate action based on the selected bulk action.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function process_bulk_action() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. This is the nonce.
|
||||
if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return;
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. Ignore.
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items');
|
||||
if (is_wp_error($result)) return;
|
||||
|
||||
if ('bulk_block_ip' === $this->current_action()) {//Process delete bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning, ignore. Sanitized later.
|
||||
$this->block_ip(wp_unslash($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
|
||||
if ('bulk_blacklist_ip' === $this->current_action()) {//Process delete bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning, ignore. Sanitized later.
|
||||
$this->blacklist_ip_address(wp_unslash($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
if ('delete' === $this->current_action()) {//Process delete bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning, ignore. Sanitized later.
|
||||
$this->delete_404_event_records(wp_unslash($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. This is the nonce.
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks an IP address by adding it to the AIOWPSEC_TBL_LOGIN_LOCKOUT table.
|
||||
*
|
||||
* @param array|string $entries - ids that correspond to ip addresses in the AIOWPSEC_TBL_EVENTS table or a single ip address
|
||||
* @param string $username - (optional)username of user being locked
|
||||
*
|
||||
* @return boolean|void
|
||||
*/
|
||||
public function block_ip($entries, $username = '') {
|
||||
global $wpdb;
|
||||
if (is_array($entries)) {
|
||||
//lock multiple records
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",", $entries) .")"; //Create comma separate list for DB operation
|
||||
$events_table = AIOWPSEC_TBL_EVENTS;
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$results = $wpdb->get_col("SELECT ip_or_host FROM $events_table WHERE ID IN " . $id_list);
|
||||
if (empty($results)) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Could not process the request because the IP addresses for the selected entries could not be found.', 'all-in-one-wp-security-and-firewall'));
|
||||
return false;
|
||||
} else {
|
||||
foreach ($results as $entry) {
|
||||
if (filter_var($entry, FILTER_VALIDATE_IP)) {
|
||||
AIOWPSecurity_Utility::lock_IP($entry, '404', $username);
|
||||
}
|
||||
}
|
||||
}
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses are now temporarily blocked.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Permanently blocks an IP address by adding it to the blacklist and writing rules to the htaccess file.
|
||||
*
|
||||
* @param array|string $entries - ids that correspond to ip addresses in the AIOWPSEC_TBL_EVENTS table or a single ip address
|
||||
*
|
||||
* @return boolean|void
|
||||
*/
|
||||
public function blacklist_ip_address($entries) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
$aiowps_firewall_config = AIOS_Firewall_Resource::request(AIOS_Firewall_Resource::CONFIG);
|
||||
$bl_ip_addresses = $aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'); //get the currently saved blacklisted IPs
|
||||
$ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($bl_ip_addresses);
|
||||
|
||||
if (is_array($entries)) {
|
||||
//Get the selected IP addresses
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",", $entries) .")"; //Create comma separate list for DB operation
|
||||
$events_table = AIOWPSEC_TBL_EVENTS;
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$results = $wpdb->get_col("SELECT ip_or_host FROM $events_table WHERE ID IN " . $id_list);
|
||||
if (empty($results)) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Could not process the request because the IP addresses for the selected entries could not be found.', 'all-in-one-wp-security-and-firewall'));
|
||||
return false;
|
||||
} else {
|
||||
foreach ($results as $entry) {
|
||||
$ip_list_array[] = $entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$validated_ip_list_array = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'blacklist');
|
||||
if (is_wp_error($validated_ip_list_array)) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(nl2br($validated_ip_list_array->get_error_message()));
|
||||
} else {
|
||||
$banned_ip_data = implode("\n", $validated_ip_list_array);
|
||||
$aio_wp_security->configs->set_value('aiowps_enable_blacklisting', '1'); // Force blacklist feature to be enabled.
|
||||
$aio_wp_security->configs->set_value('aiowps_banned_ip_addresses', $banned_ip_data);
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
$aiowps_firewall_config->set_value('aiowps_blacklist_ips', $validated_ip_list_array);
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses have been added to the blacklist and will be permanently blocked.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes one or more records from the AIOWPSEC_TBL_EVENTS table.
|
||||
*
|
||||
* @param array|string|integer $entries - ids or a single id
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public function delete_404_event_records($entries) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
$events_table = AIOWPSEC_TBL_EVENTS;
|
||||
if (is_array($entries)) {
|
||||
//Delete multiple records
|
||||
$entries = array_map('esc_sql', $entries); //escape every array element
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" . implode(",", $entries) . ")"; //Create comma separate list for DB operation
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$result = $wpdb->query("DELETE FROM " . $events_table . " WHERE id IN " . $id_list);
|
||||
if ($result) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st();
|
||||
} else {
|
||||
// Error on bulk delete
|
||||
$aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Events table. Database error: '.$wpdb->last_error, 4);
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_not_deleted_st();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all items from AIOWPSEC_TBL_EVENTS according to a search term inside $_REQUEST['s'] and only '404' events if there is no search term. It then assigns to $this->items.
|
||||
*
|
||||
* @param Boolean $ignore_pagination - whether to not paginate
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function prepare_items($ignore_pagination = false) {
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. Nonce checked in previous function.
|
||||
$search_term = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : '';
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
$events_table_name = AIOWPSEC_TBL_EVENTS;
|
||||
|
||||
// Ordering parameters
|
||||
// Parameters that are going to be used to order the result
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$orderby = isset($_GET['orderby']) ? sanitize_text_field(wp_unslash($_GET['orderby'])) : '';
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$order = isset($_GET['order']) ? sanitize_text_field(wp_unslash($_GET['order'])) : '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'id';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
if (empty($search_term)) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM $events_table_name WHERE `event_type` = '404' ORDER BY $orderby $order", ARRAY_A);
|
||||
} else {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.LikeWildcardsInQueryWithPlaceholder, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$data = $wpdb->get_results($wpdb->prepare("SELECT * FROM $events_table_name WHERE `ip_or_host` LIKE '%%%s%%' OR `url` LIKE '%%%s%%' OR `referer_info` LIKE '%%%s%%' ORDER BY $orderby $order", $wpdb->esc_like($search_term), $wpdb->esc_like($search_term), $wpdb->esc_like($search_term)), ARRAY_A);
|
||||
}
|
||||
|
||||
if (!$ignore_pagination) {
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
|
||||
foreach ($data as $index => $row) {
|
||||
// Insert an empty status column - we will use later
|
||||
$data[$index]['status'] = '';
|
||||
}
|
||||
|
||||
$this->items = $data;
|
||||
}
|
||||
|
||||
}
|
||||
+527
@@ -0,0 +1,527 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Audit_Log extends AIOWPSecurity_Ajax_Data_Table {
|
||||
|
||||
/**
|
||||
* Constructs the table object and sets up its attributes.
|
||||
*
|
||||
* @param array $data - An array containing additional data for the table. Default is an empty array.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($data = array()) {
|
||||
|
||||
// Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', // singular name of the listed records
|
||||
'plural' => 'items', // plural name of the listed records
|
||||
'ajax' => true, // does this table support ajax?
|
||||
'data' => $data // Request data
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default column item
|
||||
*
|
||||
* @param object $item - item from which column data is returned
|
||||
* @param string $column_name - column name to be fetched from item
|
||||
* @return string
|
||||
*/
|
||||
public function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cb column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_cb($item) {
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/* $1%s */ $this->_args['singular'], // Let's simply repurpose the table's singular label
|
||||
/* $2%s */ $item['id'] // The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns created column html to be rendered.
|
||||
*
|
||||
* @param array $item Data for the columns on the current row.
|
||||
*
|
||||
* @return string The html to be rendered.
|
||||
*/
|
||||
public function column_created($item) {
|
||||
$actions = array(
|
||||
'delete' => '<a class="aios-delete-audit-log" data-id="' . esc_attr($item['id']) . '" data-message="' . esc_js(__('Are you sure you want to delete this item?', 'all-in-one-wp-security-and-firewall')) . '" href="">' . esc_html__('Delete', 'all-in-one-wp-security-and-firewall') . '</a>'
|
||||
);
|
||||
|
||||
return AIOWPSecurity_Utility::convert_timestamp($item['created']) . '<span style="color:silver"></span>' . $this->row_actions($actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ip column html to be rendered.
|
||||
*
|
||||
* @param array $item Data for the columns on the current row.
|
||||
*
|
||||
* @return string The html to be rendered.
|
||||
*/
|
||||
public function column_ip($item) {
|
||||
$ip = $item['ip'];
|
||||
|
||||
$unblacklist_ip_warning_translation = __('Are you sure you want to unblacklist this IP address?', 'all-in-one-wp-security-and-firewall');
|
||||
$unlock_ip_warning_translation = __('Are you sure you want to unlock this IP address?', 'all-in-one-wp-security-and-firewall');
|
||||
$lock_ip_warning_translation = __('Are you sure you want to temporarily lock this IP address?', 'all-in-one-wp-security-and-firewall');
|
||||
$blacklist_ip_warning_translation = __('Are you sure you want to blacklist this IP address?', 'all-in-one-wp-security-and-firewall');
|
||||
|
||||
// Build row actions.
|
||||
if (AIOWPSecurity_Utility_Permissions::is_main_site_and_super_admin() && AIOWPSecurity_Utility::check_blacklist_ip($ip)) {
|
||||
$actions = array(
|
||||
'unblacklist' => '<a class="aios-unblacklist-ip-button" data-ip="' . esc_attr($ip) . '" data-message="' . esc_js($unblacklist_ip_warning_translation) . '" href="">' . esc_html__('Unblacklist', 'all-in-one-wp-security-and-firewall') . '</a>',
|
||||
);
|
||||
} elseif (AIOWPSecurity_Utility::check_locked_ip($ip, 'audit-log')) {
|
||||
$actions = array(
|
||||
'unlock' => '<a class="aios-unlock-ip-button" data-ip="' . esc_attr($ip) . '" data-message="' . esc_js($unlock_ip_warning_translation) . '" href="">' . esc_html__('Unlock', 'all-in-one-wp-security-and-firewall') . '</a>',
|
||||
);
|
||||
} else {
|
||||
$actions = array(
|
||||
'lock_ip' => '<a class="aios-lock-ip-button" data-ip="' . esc_attr($ip) . '" data-message="' . esc_js($lock_ip_warning_translation) . '" href="">' . esc_html__('Lock IP', 'all-in-one-wp-security-and-firewall') . '</a>',
|
||||
);
|
||||
|
||||
if (AIOWPSecurity_Utility_Permissions::is_main_site_and_super_admin()) {
|
||||
$actions['blacklist_ip'] = '<a class="aios-blacklist-ip-button" data-ip="' . esc_attr($ip) . '" data-message="' . esc_js($blacklist_ip_warning_translation) . '" href="">' . esc_html__('Blacklist IP', 'all-in-one-wp-security-and-firewall') . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
return $ip . '<span style="color:silver"></span>' . $this->row_actions($actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns event type column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_event_type($item) {
|
||||
if (empty($item['event_type'])) return __('No event type available.', 'all-in-one-wp-security-and-firewall');
|
||||
|
||||
$output = isset(AIOWPSecurity_Audit_Events::$event_types[$item['event_type']]) ? AIOWPSecurity_Audit_Events::$event_types[$item['event_type']] : $item['event_type'];
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns details column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_details($item) {
|
||||
$details = json_decode($item['details'], true);
|
||||
|
||||
if (!is_array($details)) return $item['details'];
|
||||
|
||||
$key = array_keys($details)[0];
|
||||
|
||||
if (method_exists("AIOWPSecurity_Audit_Text_Handler", "{$key}_to_text")) {
|
||||
return call_user_func("AIOWPSecurity_Audit_Text_Handler::{$key}_to_text", $details[$key]);
|
||||
}
|
||||
|
||||
return $item['details'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns stack trace column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_stacktrace($item) {
|
||||
if (empty($item['stacktrace'])) return __('No stack trace available.', 'all-in-one-wp-security-and-firewall');
|
||||
|
||||
if (is_serialized($item['stacktrace'])) {
|
||||
$stacktrace = AIOWPSecurity_Utility::unserialize($item['stacktrace']);
|
||||
} else {
|
||||
$stacktrace = $item['stacktrace'];
|
||||
}
|
||||
ob_start();
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_dump -- Part of error reporting system.
|
||||
var_dump($stacktrace);
|
||||
$stacktrace_output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$output = sprintf('<a href="#TB_inline?&inlineId=trace-%s" title="%s" class="thickbox">%s</a>', $item['id'], esc_html__('Stack trace', 'all-in-one-wp-security-and-firewall'), esc_html__('Show trace', 'all-in-one-wp-security-and-firewall'));
|
||||
$output .= sprintf('<div id="trace-%s" style="display: none"><pre>%s</pre></div>', $item['id'], htmlspecialchars($stacktrace_output));
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the columns for the table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox">', //Render a checkbox
|
||||
'created' => __('Date and time', 'all-in-one-wp-security-and-firewall'),
|
||||
'level' => __('Level', 'all-in-one-wp-security-and-firewall'),
|
||||
'network_id' => __('Network ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'site_id' => __('Site ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'username' => __('Username', 'all-in-one-wp-security-and-firewall'),
|
||||
'ip' => __('IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'event_type' => __('Event', 'all-in-one-wp-security-and-firewall'),
|
||||
'details' => __('Details', 'all-in-one-wp-security-and-firewall'),
|
||||
'stacktrace' => __('Stack trace', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
$columns = apply_filters('list_auditlogs_get_columns', $columns);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets which of the columns the table data can be sorted by
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'created' => array('created', false),
|
||||
'network_id' => array('network_id', false),
|
||||
'site_id' => array('site_id', false),
|
||||
'level' => array('level', false),
|
||||
'username' => array('username', false),
|
||||
'ip' => array('ip', false),
|
||||
'event_type' => array('event_type', false),
|
||||
'details' => array('details', false),
|
||||
'stacktrace' => array('stacktrace', false)
|
||||
);
|
||||
$sortable_columns = apply_filters('list_auditlogs_get_sortable_columns', $sortable_columns);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will display a list of bulk actions for the list table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_bulk_actions() {
|
||||
$actions = array(
|
||||
'delete_all' => __('Delete all', 'all-in-one-wp-security-and-firewall'),
|
||||
'delete_selected' => __('Delete selected', 'all-in-one-wp-security-and-firewall'),
|
||||
'delete_filtered' => __('Delete filtered', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will process the bulk action request, $search_term and $filters are only used if the user is trying to bulk delete the filtered items
|
||||
*
|
||||
* @param string $search_term - The search term used for filtering records.
|
||||
* @param array $filters - An array containing filters applied to the records.
|
||||
* @param string $action - The bulk action to be performed.
|
||||
* @param array $items - An array of record IDs on which the action will be performed. Default is an empty array.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function process_bulk_action($search_term, $filters, $action, $items = array()) {
|
||||
global $wpdb;
|
||||
|
||||
if ('delete_selected' === $action) { // Process delete bulk actions
|
||||
if (!isset($items)) {
|
||||
AIOS_Helper::set_message('aios_list_message', __('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'), 'error');
|
||||
} else {
|
||||
$this->delete_audit_event_records($items);
|
||||
}
|
||||
} elseif ('delete_filtered' === $action) {
|
||||
if (!empty($filters) || '' !== $search_term) {
|
||||
$audit_log_tbl = AIOWPSEC_TBL_AUDIT_LOG;
|
||||
$where_sql = $this->get_audit_list_where_sql($search_term, $filters);
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$results = $wpdb->get_results("SELECT id FROM {$audit_log_tbl} {$where_sql}", 'ARRAY_A');
|
||||
$items = array_column($results, 'id');
|
||||
$this->delete_audit_event_records($items);
|
||||
} else {
|
||||
AIOS_Helper::set_message('aios_list_message', __('Please select the level or the event type filter or filter by a search term', 'all-in-one-wp-security-and-firewall'), 'error');
|
||||
}
|
||||
} elseif ('delete_all' === $action) {
|
||||
$this->delete_audit_event_records(null, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs extra controls to be displayed between bulk actions and pagination
|
||||
*
|
||||
* @param string $which - where we are outputting content (top or bottom)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function extra_tablenav($which) {
|
||||
switch ($which) {
|
||||
case 'top':
|
||||
?>
|
||||
<div class="alignleft actions">
|
||||
<select name="level-filter" class="audit-filter-level">
|
||||
<?php $selected = !isset($this->_args['data']['level-filter']) ? ' selected = "selected"' : ''; ?>
|
||||
<?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- No user input to escape. ?>
|
||||
<option value="-1" <?php echo $selected; ?>><?php esc_html_e('All levels', 'all-in-one-wp-security-and-firewall'); ?></option>
|
||||
<?php
|
||||
foreach (AIOWPSecurity_Audit_Events::$log_levels as $level) {
|
||||
$selected = isset($this->_args['data']['level-filter']) && $this->_args['data']['level-filter'] == $level ? ' selected = "selected"' : '';
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- No user input to escape.
|
||||
echo '<option value="'. esc_attr($level) .'" '. $selected .'>'. esc_html($level) .'</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name="event-filter" class="audit-filter-event">
|
||||
<?php $selected = !isset($this->_args['data']['event-filter']) ? ' selected = "selected"' : ''; ?>
|
||||
<?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- No user input to escape. ?>
|
||||
<option value="-1" <?php echo $selected; ?>><?php esc_html_e('All events', 'all-in-one-wp-security-and-firewall'); ?></option>
|
||||
<?php
|
||||
foreach (AIOWPSecurity_Audit_Events::$event_types as $event_type => $event) {
|
||||
$selected = isset($this->_args['data']['event-filter']) && $this->_args['data']['event-filter'] == $event_type ? ' selected = "selected"' : '';
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- No user input to escape.
|
||||
echo '<option value="'. esc_attr($event_type) .'" '. $selected .'>'. esc_html($event) .'</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<?php submit_button(esc_html__('Filter', 'all-in-one-wp-security-and-firewall'), 'action', '', false); ?>
|
||||
</div>
|
||||
<?php
|
||||
break;
|
||||
case 'bottom':
|
||||
submit_button(esc_html__('Export to CSV', 'all-in-one-wp-security-and-firewall'), 'primary', 'aiowps_export_audit_event_logs_to_csv', false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will process the delete request for the audit event records
|
||||
*
|
||||
* @param integer|array $entries - an ID or array of IDs to be deleted
|
||||
* @param boolean $delete_all - indicates if all entries should be deleted or not (if true, then $entries will be ignored)
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public function delete_audit_event_records($entries, $delete_all = false) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
|
||||
$audit_log_tbl = AIOWPSEC_TBL_AUDIT_LOG;
|
||||
$result = false;
|
||||
|
||||
if ($delete_all) {
|
||||
// Delete all records
|
||||
$site_id_where_sql = (!is_super_admin()) ? ' WHERE site_id = ' . get_current_blog_id() : '';
|
||||
$delete_command = "DELETE FROM " . $audit_log_tbl . $site_id_where_sql;
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$result = $wpdb->query($delete_command);
|
||||
} elseif (is_array($entries)) {
|
||||
// Delete multiple records
|
||||
$entries = array_map('esc_sql', $entries); // Escape every array element
|
||||
$entries = array_filter($entries, 'is_numeric'); // Discard non-numeric ID values
|
||||
$chunks = array_chunk($entries, 1000);
|
||||
|
||||
$site_id_where_sql = (!is_super_admin()) ? ' AND site_id = ' . get_current_blog_id() : '';
|
||||
|
||||
// Processing each chunk
|
||||
foreach ($chunks as $chunk) {
|
||||
$id_list = "(" . implode(",", $chunk) . ")"; // Create comma separate list for DB operation
|
||||
$delete_command = "DELETE FROM " . $audit_log_tbl . " WHERE id IN " . $id_list . $site_id_where_sql;
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$result = $wpdb->query($delete_command);
|
||||
if (!$result) {
|
||||
$aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Audit log table. Database error: '.$wpdb->last_error, 4);
|
||||
AIOS_Helper::set_message('aios_list_message', __('The selected record(s) have failed to delete.', 'all-in-one-wp-security-and-firewall'), 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
} elseif (!empty($entries)) {
|
||||
// Delete single record
|
||||
$site_id_where_sql = (!is_super_admin()) ? ' AND site_id = ' . get_current_blog_id() : '';
|
||||
$delete_command = "DELETE FROM " . $audit_log_tbl . " WHERE id = '" . absint($entries) . "'" . $site_id_where_sql;
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$result = $wpdb->query($delete_command);
|
||||
}
|
||||
|
||||
if ($result || 0 < $result) {
|
||||
$aios_list_message = __('The selected record(s) has been deleted successfully.', 'all-in-one-wp-security-and-firewall');
|
||||
AIOS_Helper::set_message('aios_list_message', $aios_list_message);
|
||||
} else {
|
||||
$aios_list_message = __('The selected record(s) have failed to delete.', 'all-in-one-wp-security-and-firewall');
|
||||
$aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Audit log table. Database error: '.$wpdb->last_error, 4);
|
||||
AIOS_Helper::set_message('aios_list_message', $aios_list_message, 'error');
|
||||
}
|
||||
|
||||
return $aios_list_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will build and return the SQL WHERE statement
|
||||
*
|
||||
* @param string $search_term - the search term applied
|
||||
* @param array $filters - the filters applied
|
||||
*
|
||||
* @return string - the SQL WHERE statement
|
||||
*/
|
||||
private function get_audit_list_where_sql($search_term, $filters) {
|
||||
|
||||
$where_sql = '';
|
||||
|
||||
if ('' == $search_term) {
|
||||
$where_sql = (!is_super_admin()) ? 'WHERE site_id = '.get_current_blog_id() : '';
|
||||
$extra_where = '';
|
||||
|
||||
if (!empty($filters)) {
|
||||
$where_sql = empty($where_sql) ? 'WHERE ' : $where_sql . ' AND ';
|
||||
foreach ($filters as $filter => $value) {
|
||||
if (!empty($extra_where)) $extra_where .= ' AND ';
|
||||
$extra_where .= "`{$filter}` = '".esc_sql($value)."'";
|
||||
}
|
||||
}
|
||||
|
||||
$where_sql .= $extra_where;
|
||||
} else {
|
||||
$where_sql = (!is_super_admin()) ? 'WHERE site_id = '.get_current_blog_id().' AND ' : 'WHERE ';
|
||||
$extra_where = '';
|
||||
|
||||
if (!empty($filters)) {
|
||||
foreach ($filters as $filter => $value) {
|
||||
if (!empty($extra_where)) $extra_where .= ' AND ';
|
||||
$extra_where .= "`{$filter}` = '".esc_sql($value)."'";
|
||||
}
|
||||
$where_sql .= $extra_where . ' AND (';
|
||||
$extra_where = '';
|
||||
}
|
||||
|
||||
// We don't use FILTER_VALIDATE_IP here as we want to be able to search for partial IP's
|
||||
if (preg_match('/^[0-9a-f:\.]+$/i', $search_term)) {
|
||||
$extra_where .= "`ip` LIKE '".esc_sql($search_term)."%'";
|
||||
}
|
||||
|
||||
if (in_array($search_term, AIOWPSecurity_Audit_Events::$log_levels) && !isset($filters['level'])) {
|
||||
if (!empty($extra_where)) $extra_where .= ' OR ';
|
||||
$extra_where .= "`level` = '".esc_sql($search_term)."'";
|
||||
}
|
||||
|
||||
if (!empty($extra_where)) $extra_where .= ' OR ';
|
||||
if (isset($filters['event_type'])) {
|
||||
$extra_where .= "`username` LIKE '".esc_sql($search_term)."%'";
|
||||
} else {
|
||||
$extra_where .= "(`username` LIKE '".esc_sql($search_term)."%' or `event_type` LIKE '%".esc_sql($search_term)."%')";
|
||||
}
|
||||
if (!empty($filters)) $extra_where .= ')';
|
||||
|
||||
$where_sql .= $extra_where;
|
||||
}
|
||||
|
||||
return $where_sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the data from database and handles the pagination
|
||||
*
|
||||
* @param boolean $ignore_pagination - whether to not paginate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepare_items($ignore_pagination = false) {
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
$no_action = -1;
|
||||
$per_page = defined('AIOWPSEC_AUDIT_LOG_PER_PAGE') ? absint(AIOWPSEC_AUDIT_LOG_PER_PAGE) : 100;
|
||||
$per_page = empty($per_page) ? 100 : $per_page;
|
||||
$current_page = $this->get_pagenum();
|
||||
$offset = (!$ignore_pagination && $per_page > 0) ? ($current_page - 1) * $per_page : 0;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array('id'); // we really don't need the IDs of the log entries displayed
|
||||
if (!is_multisite()) {
|
||||
$hidden[] = 'network_id';
|
||||
$hidden[] = 'site_id';
|
||||
}
|
||||
$sortable = $this->get_sortable_columns();
|
||||
$filters = array();
|
||||
if (isset($this->_args['data']['level-filter']) && $no_action != $this->_args['data']['level-filter']) $filters['level'] = sanitize_text_field($this->_args['data']['level-filter']);
|
||||
if (isset($this->_args['data']['event-filter']) && $no_action != $this->_args['data']['event-filter']) $filters['event_type'] = sanitize_text_field($this->_args['data']['event-filter']);
|
||||
$search_term = isset($this->_args['data']['s']) ? sanitize_text_field(stripslashes($this->_args['data']['s'])) : '';
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$items = array();
|
||||
|
||||
if (isset($this->_args['data']['items'])) {
|
||||
if (is_array($this->_args['data']['items'])) {
|
||||
foreach ($this->_args['data']['items'] as $item) {
|
||||
$sanitized_item = sanitize_text_field($item);
|
||||
$items[] = $sanitized_item;
|
||||
}
|
||||
} else {
|
||||
$sanitized_item = sanitize_text_field($this->_args['data']['items']);
|
||||
$items[] = $sanitized_item;
|
||||
}
|
||||
} else {
|
||||
$items = null;
|
||||
}
|
||||
|
||||
if (isset($this->_args['data']['action'])) $action = sanitize_text_field($this->_args['data']['action']);
|
||||
else $action = $no_action;
|
||||
|
||||
if (isset($action) && $no_action !== $action) {
|
||||
$this->process_bulk_action($search_term, $filters, $action, $items);
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$audit_log_tbl = AIOWPSEC_TBL_AUDIT_LOG;
|
||||
|
||||
// Parameters that are going to be used to order the result
|
||||
isset($this->_args['data']["orderby"]) ? $orderby = wp_strip_all_tags($this->_args['data']["orderby"]) : $orderby = '';
|
||||
isset($this->_args['data']["order"]) ? $order = wp_strip_all_tags($this->_args['data']["order"]) : $order = '';
|
||||
// By default show the most recent audit log entries.
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'created';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
$orderby = sanitize_sql_orderby($orderby);
|
||||
$order = sanitize_sql_orderby($order);
|
||||
|
||||
$where_sql = $this->get_audit_list_where_sql($search_term, $filters);
|
||||
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$audit_log_tbl} {$where_sql}");
|
||||
if ($ignore_pagination) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM {$audit_log_tbl} {$where_sql} ORDER BY {$orderby} {$order}", 'ARRAY_A');
|
||||
} else {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM {$audit_log_tbl} {$where_sql} ORDER BY {$orderby} {$order} LIMIT {$per_page} OFFSET {$offset}", 'ARRAY_A');
|
||||
}
|
||||
|
||||
// Filter the 'details' section
|
||||
foreach ($data as $key => $entry) {
|
||||
$details = json_decode($entry['details'], true);
|
||||
$details = is_null($details) ? $entry['details'] : $details; // check if the decode worked, if not pass the json string
|
||||
$data[$key]['details'] = wp_json_encode(apply_filters('aios_audit_filter_details', $details, $entry['event_type']));
|
||||
}
|
||||
|
||||
$this->items = $data;
|
||||
|
||||
if ($ignore_pagination) return;
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, // We have to calculate the total number of items
|
||||
'per_page' => $per_page, // We have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) // We have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
}
|
||||
wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-list-comment-spammer-ip.php
Executable
+221
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Comment_Spammer_IP extends AIOWPSecurity_List_Table {
|
||||
|
||||
public function __construct() {
|
||||
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', // singular name of the listed records
|
||||
'plural' => 'items', // plural name of the listed records
|
||||
'ajax' => false // does this table support ajax?
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
public function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
public function column_comment_author_IP($item) {
|
||||
//Build row actions
|
||||
if (!is_main_site() || 'blocked' === $item['status']) {
|
||||
//Suppress the block link if site is a multi site AND not the main site or the status is blocked
|
||||
$actions = array(); //blank array
|
||||
} else {
|
||||
//Add IP to block URL
|
||||
$ip = $item['comment_author_IP'];
|
||||
$actions = array(
|
||||
'block' => '<a class="aios-block-author-ip" data-ip="'.esc_attr($ip).'" data-message="'.esc_js(__('Are you sure you want to permanently block this IP address?', 'all-in-one-wp-security-and-firewall')).'" href="">'.__('Block', 'all-in-one-wp-security-and-firewall').'</a>',
|
||||
);
|
||||
}
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['comment_author_IP'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function column_cb($item) {
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/ esc_attr($item['comment_author_IP']) //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
public function get_columns() {
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'comment_author_IP' => __('Spammer IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'amount' => __('Number of spam comments from this IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'status' => __('Status', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
'comment_author_IP' => array('comment_author_IP',false),
|
||||
'amount' => array('amount',false),
|
||||
'status' => array('status',false),
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
public function get_bulk_actions() {
|
||||
if (!is_main_site()) {
|
||||
//Suppress the block link if site is a multi site AND not the main site
|
||||
$actions = array(); //blank array
|
||||
} else {
|
||||
$actions = array(
|
||||
'block' => __('Block', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles bulk actions on the table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function process_bulk_action() {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This IS the nonce check.
|
||||
if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return;
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput -- This IS the nonce check.
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items');
|
||||
if (is_wp_error($result)) return;
|
||||
|
||||
|
||||
if ('block' === $this->current_action()) {
|
||||
//Process block bulk actions
|
||||
if (!isset($_REQUEST['item'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce already checked above.
|
||||
$error_msg = '<div id="message" class="error"><p><strong>';
|
||||
$error_msg .= esc_html__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall');
|
||||
$error_msg .= '</strong></p></div>';
|
||||
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- PCP error. Output already escaped.
|
||||
echo $error_msg;
|
||||
} else {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce already checked above.
|
||||
$this->block_spammer_ip_records((filter_var(wp_unslash($_REQUEST['item']), FILTER_VALIDATE_IP)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function will add the selected IP addresses to the blacklist.
|
||||
*
|
||||
* @param int|array $entries - either an array of IDs or a single ID of ip to be blocked
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function block_spammer_ip_records($entries) {
|
||||
if (is_array($entries)) {
|
||||
$entries = array_map('esc_sql', $entries); // Escape every array element
|
||||
//Bulk selection using checkboxes were used
|
||||
foreach ($entries as $ip_add) {
|
||||
AIOWPSecurity_Blocking::add_ip_to_block_list($ip_add, 'spam');
|
||||
}
|
||||
}
|
||||
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP addresses are now permanently blocked.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function prepare the items rendered on the table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepare_items() {
|
||||
//First, lets decide how many records per page to show
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
global $aio_wp_security;
|
||||
$minimum_comments_per_ip = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments');
|
||||
if (empty($minimum_comments_per_ip)) {
|
||||
$minimum_comments_per_ip = 5;
|
||||
}
|
||||
// Ordering parameters
|
||||
//Parameters that are going to be used to order the result
|
||||
isset($_GET["orderby"]) ? $orderby = wp_strip_all_tags(wp_unslash($_GET["orderby"])) : $orderby = ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check.
|
||||
isset($_GET["order"]) ? $order = wp_strip_all_tags(wp_unslash($_GET["order"])) : $order = ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No nonce to check.
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'amount';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
// status is not a key in the database so we don't want to sort the database results, but sort the array later
|
||||
if ('status' == $orderby) {
|
||||
$sql = $wpdb->prepare("SELECT comment_author_IP, COUNT(*) AS amount
|
||||
FROM $wpdb->comments
|
||||
WHERE comment_approved = 'spam'
|
||||
GROUP BY comment_author_IP
|
||||
HAVING amount >= %d
|
||||
", $minimum_comments_per_ip);
|
||||
} else {
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orderby cannot be prepared.
|
||||
$sql = $wpdb->prepare("SELECT comment_author_IP, COUNT(*) AS amount
|
||||
FROM $wpdb->comments
|
||||
WHERE comment_approved = 'spam'
|
||||
GROUP BY comment_author_IP
|
||||
HAVING amount >= %d
|
||||
ORDER BY $orderby $order
|
||||
", $minimum_comments_per_ip);
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orderby cannot be prepared.
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- Preparing done in conditional above.
|
||||
$data = $wpdb->get_results($sql, ARRAY_A);
|
||||
|
||||
// Get all permanently blocked IP addresses
|
||||
$block_list = AIOWPSecurity_Blocking::get_list_blocked_ips();
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (in_array($value['comment_author_IP'], $block_list)) {
|
||||
$data[$key]['status'] = 'blocked';
|
||||
} else {
|
||||
$data[$key]['status'] = 'not blocked';
|
||||
}
|
||||
}
|
||||
|
||||
if ('status' == $orderby) {
|
||||
$keys = array_column($data, 'status');
|
||||
if ('asc' == $order) {
|
||||
array_multisort($keys, SORT_ASC, SORT_STRING, $data);
|
||||
} else {
|
||||
array_multisort($keys, SORT_DESC, SORT_STRING, $data);
|
||||
}
|
||||
}
|
||||
|
||||
$current_page = $this->get_pagenum();
|
||||
$total_items = count($data);
|
||||
$data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
|
||||
$this->items = $data;
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;//Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Debug_Log extends AIOWPSecurity_List_Table {
|
||||
|
||||
/**
|
||||
* Sets up some table attributes (i.e: the plurals and whether it's ajax or not)
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'entry', //singular name of the listed records
|
||||
'plural' => 'entries', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns logtime column in datetime format as per user setting time zone.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the datetime
|
||||
*/
|
||||
public function column_logtime($item) {
|
||||
return AIOWPSecurity_Utility::convert_timestamp($item['logtime']);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function renders a default column item
|
||||
*
|
||||
* @param array $item - Item object
|
||||
* @param string $column_name - Column name to be rendered from item object
|
||||
*
|
||||
* @return mixed - data to be rendered for column
|
||||
*/
|
||||
public function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the columns for the table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'logtime' => __('Date and time', 'all-in-one-wp-security-and-firewall'),
|
||||
'level' => __('Level', 'all-in-one-wp-security-and-firewall'),
|
||||
'network_id' => __('Network ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'site_id' => __('Site ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'message' => __('Message', 'all-in-one-wp-security-and-firewall'),
|
||||
'type' => __('Type', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets which of the columns the table data can be sorted by
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_sortable_columns() {
|
||||
return array(
|
||||
'logtime' => array('logtime', false),
|
||||
'level' => array('level', false),
|
||||
'network_id' => array('network_id', false),
|
||||
'site_id' => array('site_id', false),
|
||||
'message'=>array('message', false),
|
||||
'type' => array('type', false)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the data from database and handles the pagination
|
||||
*
|
||||
* @param boolean $ignore_pagination - whether to not paginate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepare_items($ignore_pagination = false) {
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
if (defined('AIOWPSEC_DEBUG_LOG_PER_PAGE')) {
|
||||
$per_page = absint(AIOWPSEC_DEBUG_LOG_PER_PAGE);
|
||||
}
|
||||
|
||||
$per_page = empty($per_page) ? 15 : $per_page;
|
||||
$current_page = $this->get_pagenum();
|
||||
$offset = ($current_page - 1) * $per_page;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array('id'); // we really don't need the IDs of the log entries displayed
|
||||
if (!is_multisite()) {
|
||||
$hidden[] = 'network_id';
|
||||
$hidden[] = 'site_id';
|
||||
}
|
||||
$sortable = $this->get_sortable_columns();
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$debug_log_tbl = AIOWPSEC_TBL_DEBUG_LOG;
|
||||
|
||||
/* -- Ordering parameters -- */
|
||||
|
||||
//Parameters that are going to be used to order the result
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
isset($_GET["orderby"]) ? $orderby = sanitize_text_field(wp_unslash($_GET["orderby"])) : $orderby = '';
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
isset($_GET["order"]) ? $order = sanitize_text_field(wp_unslash($_GET["order"])) : $order = '';
|
||||
|
||||
// By default show the most recent debug log entries.
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'logtime';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
$orderby = sanitize_sql_orderby($orderby);
|
||||
$order = sanitize_sql_orderby($order);
|
||||
|
||||
$where_sql = (!is_super_admin()) ? 'WHERE site_id = '.get_current_blog_id() : '';
|
||||
|
||||
if ($ignore_pagination) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM {$debug_log_tbl}$where_sql ORDER BY $orderby $order", 'ARRAY_A');
|
||||
} else {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM {$debug_log_tbl} $where_sql ORDER BY $orderby $order LIMIT $per_page OFFSET $offset", 'ARRAY_A');
|
||||
}
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$debug_log_tbl} $where_sql");
|
||||
$this->items = $data;
|
||||
|
||||
if ($ignore_pagination) return;
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
}
|
||||
Executable
+318
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Locked_IP extends AIOWPSecurity_List_Table {
|
||||
|
||||
public function __construct() {
|
||||
|
||||
|
||||
// Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns created column in datetime format as per user setting time zone.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the datetime
|
||||
*/
|
||||
public function column_created($item) {
|
||||
return AIOWPSecurity_Utility::convert_timestamp($item['created']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns released column in datetime format as per user setting time zone.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the datetime
|
||||
*/
|
||||
public function column_released($item) {
|
||||
return AIOWPSecurity_Utility::convert_timestamp($item['released']);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function renders a column
|
||||
*
|
||||
* @param array $item - Item object
|
||||
* @param string $column_name - Column name to be rendered from item object
|
||||
*
|
||||
* @return string - data to be rendered for column_name
|
||||
*/
|
||||
public function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to populate the locked ip actions column in the table
|
||||
*
|
||||
* @param array $item - Contains the current item data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function column_failed_login_ip($item) {
|
||||
$actions = array(
|
||||
'unlock' => '<a href="" data-ip="'.esc_attr($item['failed_login_ip']).'" data-message="'.esc_js(__('Are you sure you want to unlock this address range?', 'all-in-one-wp-security-and-firewall')).'" class="aios-unlock-ip-button">'.esc_html__('Unlock', 'all-in-one-wp-security-and-firewall').'</a>',
|
||||
'delete' => '<a href="" data-id="'.esc_attr($item['id']).'" data-message="'.esc_js(__('Are you sure you want to delete this item?', 'all-in-one-wp-security-and-firewall')).'" class="aios-delete-locked-ip-record">'.esc_html__('Delete', 'all-in-one-wp-security-and-firewall').'</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['failed_login_ip'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function renders the checkbox column
|
||||
*
|
||||
* @param array $item - item object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function column_cb($item) {
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/ $item['id'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ip_lookup_result column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_ip_lookup_result($item) {
|
||||
if (empty($item['ip_lookup_result'])) return __('There is no IP lookup result available.', 'all-in-one-wp-security-and-firewall');
|
||||
|
||||
$ip_lookup_result = json_decode($item['ip_lookup_result'], true);
|
||||
|
||||
// check that the json decode worked
|
||||
if (null === $ip_lookup_result) return __('There is no IP lookup result available.', 'all-in-one-wp-security-and-firewall');
|
||||
|
||||
foreach ($ip_lookup_result as $key => $value) {
|
||||
$ip_lookup_result[$key] = empty($value) ? __('Not Found', 'all-in-one-wp-security-and-firewall') : $value;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r -- PCP warning. Part of error reporting system.
|
||||
$ip_lookup_result = print_r($ip_lookup_result, true);
|
||||
|
||||
$output = sprintf('<a href="#TB_inline?&inlineId=trace-%s" title="%s" class="thickbox">%s</a>', esc_attr($item['id']), esc_html__('IP lookup result', 'all-in-one-wp-security-and-firewall'), esc_html__('Show result', 'all-in-one-wp-security-and-firewall'));
|
||||
$output .= sprintf('<div id="trace-%s" style="display: none"><pre>%s</pre></div>', esc_attr($item['id']), esc_html($ip_lookup_result));
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the columns for the table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'failed_login_ip' => __('Locked IP/range', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_id' => __('User ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_login' => __('Username', 'all-in-one-wp-security-and-firewall'),
|
||||
'lock_reason' => __('Reason', 'all-in-one-wp-security-and-firewall'),
|
||||
'created' => __('Date locked', 'all-in-one-wp-security-and-firewall'),
|
||||
'released' => __('Release date', 'all-in-one-wp-security-and-firewall'),
|
||||
'ip_lookup_result' => __('IP lookup result', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns sortable columns
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function get_sortable_columns() {
|
||||
return array(
|
||||
'failed_login_ip' => array('failed_login_ip',false),
|
||||
'user_id' => array('user_id',false),
|
||||
'user_login' => array('user_login',false),
|
||||
'lock_reason' => array('lock_reason',false),
|
||||
'created' => array('created',false),
|
||||
'released' => array('released',false)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the bulk actions for the table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_bulk_actions() {
|
||||
return array(
|
||||
'unlock' => __('Unlock', 'all-in-one-wp-security-and-firewall'),
|
||||
'delete' => __('Delete', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process bulk actions.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function process_bulk_action() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. This is the nonce.
|
||||
if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return;
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. This is the nonce.
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items');
|
||||
if (is_wp_error($result)) return;
|
||||
|
||||
if ('delete' == $this->current_action()) { // Process delete bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. Sanitized later.
|
||||
$this->delete_lockout_records(wp_unslash($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
|
||||
if ('unlock' == $this->current_action()) { //Process unlock bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. Sanitized later.
|
||||
$this->unlock_ips((wp_unslash($_REQUEST['item'])));
|
||||
}
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. This is the nonce.
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks multiple IP addresses by modifying the released column of records in the AIOWPSEC_TBL_LOGIN_LOCKOUT table.
|
||||
*
|
||||
* @param array $entries IDs that correspond to IP addresses in the AIOWPSEC_TBL_LOGIN_LOCKOUT table.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unlock_ips($entries) {
|
||||
global $wpdb;
|
||||
|
||||
$lockout_table = AIOWPSEC_TBL_LOGIN_LOCKOUT;
|
||||
|
||||
// Unlock multiple records
|
||||
$entries = array_filter($entries, 'is_numeric'); // Discard non-numeric ID values
|
||||
$id_list = '(' .implode(',', $entries) .')'; // Create comma separate list for DB operation
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$result = $wpdb->query("UPDATE $lockout_table SET `released` = UNIX_TIMESTAMP() WHERE `id` IN $id_list");
|
||||
|
||||
if (null != $result) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected IP entries were unlocked successfully.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes one or more records from the AIOWPSEC_TBL_LOGIN_LOCKOUT table.
|
||||
*
|
||||
* @param array|string|integer $entries - ids or a single id
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public function delete_lockout_records($entries) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
$lockout_table = AIOWPSEC_TBL_LOGIN_LOCKOUT;
|
||||
if (is_array($entries)) {
|
||||
// Delete multiple records
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" .implode(",", $entries) .")"; //Create comma separate list for DB operation
|
||||
$delete_command = "DELETE FROM ".$lockout_table." WHERE id IN ".$id_list;
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$result = $wpdb->query($delete_command);
|
||||
if ($result) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st();
|
||||
} else {
|
||||
// Error on bulk delete
|
||||
$aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from login lockout table. Database error: '.$wpdb->last_error, 4);
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_not_deleted_st();
|
||||
}
|
||||
} elseif (null != $entries) {
|
||||
// Delete single record
|
||||
$delete_command = "DELETE FROM ".$lockout_table." WHERE id = '".absint($entries)."'";
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$result = $wpdb->query($delete_command);
|
||||
if ($result) {
|
||||
return AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st(true);
|
||||
} elseif (false === $result) {
|
||||
// Error on single delete
|
||||
$aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from login lockout table. Database error: '.$wpdb->last_error, 4);
|
||||
return AIOWPSecurity_Admin_Menu::show_msg_record_not_deleted_st(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all items from AIOWPSEC_TBL_LOGIN_LOCKOUT. It may paginate and then assigns to $this->items.
|
||||
*
|
||||
* @param Boolean $ignore_pagination - whether to not paginate
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function prepare_items($ignore_pagination = false) {
|
||||
global $wpdb;
|
||||
|
||||
$lockout_table = AIOWPSEC_TBL_LOGIN_LOCKOUT;
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
// How many records per page to show
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
// Parameters that are going to be used to order the result
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$orderby = isset($_GET['orderby']) ? sanitize_text_field(wp_unslash($_GET['orderby'])) : '';
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$order = isset($_GET['order']) ? sanitize_text_field(wp_unslash($_GET['order'])) : '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'created';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
$current_page = $this->get_pagenum();
|
||||
$offset = ($current_page - 1) * $per_page;
|
||||
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$lockout_table} WHERE `released` > UNIX_TIMESTAMP()");
|
||||
|
||||
if ($ignore_pagination) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM {$lockout_table} WHERE `released` > UNIX_TIMESTAMP() ORDER BY {$orderby} {$order}", 'ARRAY_A');
|
||||
} else {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM {$lockout_table} WHERE `released` > UNIX_TIMESTAMP() ORDER BY {$orderby} {$order} LIMIT {$per_page} OFFSET {$offset}", 'ARRAY_A');
|
||||
}
|
||||
|
||||
$this->items = $data;
|
||||
|
||||
if ($ignore_pagination) return;
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, // WE have to calculate the total number of items
|
||||
'per_page' => $per_page, // WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) // WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+260
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Logged_In_Users extends AIOWPSecurity_List_Table {
|
||||
|
||||
public function __construct() {
|
||||
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
public function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user id column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_user_id($item) {
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'logout' => '<a class="aios-force-logout-user" data-user-id="'.esc_attr($item['user_id']).'" data-message="'.esc_js(__('Are you sure you want to force this user to be logged out of this session?', 'all-in-one-wp-security-and-firewall')).'" href="">'.__('Force logout', 'all-in-one-wp-security-and-firewall').'</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['user_id'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the columns for the table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox">',
|
||||
'user_id' => __('User ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'username' => __('Login name', 'all-in-one-wp-security-and-firewall'),
|
||||
'ip_address' => __('IP address', 'all-in-one-wp-security-and-firewall'),
|
||||
'site_id' => __('Site ID', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cb column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_cb($item) {
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/* $1%s */ $this->_args['singular'], // Let's simply repurpose the table's singular label
|
||||
/* $2%s */ $item['user_id'] // The value of the checkbox should be the record's id and its ip address
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets which of the columns the table data can be sorted by
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_sortable_columns() {
|
||||
return array(
|
||||
'user_id' => array('user_id',false),
|
||||
'username' => array('username',false),
|
||||
'ip_address' => array('ip_address',false),
|
||||
'site_id' => array('site_id',false),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a bulk action user interface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_bulk_actions() {
|
||||
return array(
|
||||
'force_logout_all' => __('Logout all', 'all-in-one-wp-security-and-firewall'),
|
||||
'force_logout_selected' => __('Logout selected', 'all-in-one-wp-security-and-firewall'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Bulk action from menu
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function process_bulk_action() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput -- PCP warning. Nonce used.
|
||||
if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return;
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items');
|
||||
if (is_wp_error($result)) return;
|
||||
|
||||
if ('force_logout_all' === $this->current_action()) {
|
||||
$this->force_user_logout(array(), true);
|
||||
} elseif ('force_logout_selected' === $this->current_action()) {
|
||||
if (isset($_REQUEST['item'])) {
|
||||
|
||||
if (is_array($_REQUEST['item'])) $this->force_user_logout(wp_unslash($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. Nonce used.
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will force selected user(s) to be logged out.
|
||||
*
|
||||
* @param int|array $users - id of selected user or array of user ids to be logged out
|
||||
* @param bool $logout_all - Boolean to show if all users should be logged out
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public function force_user_logout($users, $logout_all = false) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
|
||||
$logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS;
|
||||
|
||||
if ($logout_all) {
|
||||
// get all user_id(except for the admin) in the table and make it an array for users
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$users = $wpdb->get_col("SELECT user_id FROM $logged_in_users_table");
|
||||
}
|
||||
|
||||
if (is_array($users)) {
|
||||
|
||||
if (empty($users)) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_not_deleted_st();
|
||||
return;
|
||||
}
|
||||
|
||||
$errors = 0;
|
||||
|
||||
// Escape the user IDs for security
|
||||
$users = array_map('esc_sql', $users);
|
||||
|
||||
foreach ($users as $user_id) {
|
||||
if (is_numeric($user_id) && !is_super_admin($user_id) && AIOWPSecurity_Utility::is_user_member_of_blog($user_id)) {
|
||||
if ($aio_wp_security->user_login_obj->delete_logged_in_user($user_id)) {
|
||||
$this->logout_user($user_id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$errors++;
|
||||
}
|
||||
|
||||
if ($errors > 0) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__("Some users were not logged out due to the ID being invalid, or them being a super admin or a member of a different subsite on a multisite", 'all-in-one-wp-security-and-firewall'));
|
||||
return;
|
||||
}
|
||||
|
||||
AIOWPSecurity_Admin_Menu::show_msg_record_deleted_st();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function handles logging out a user using user_id
|
||||
*
|
||||
* @param int $user_id - id of user being logged out
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function logout_user($user_id) {
|
||||
$user_id = absint($user_id);
|
||||
$manager = WP_Session_Tokens::get_instance($user_id);
|
||||
$manager->destroy_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the items for the logged in users table
|
||||
*
|
||||
* @param bool $ignore_pagination - this is to check if data should be paginated or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepare_items($ignore_pagination = false) {
|
||||
global $wpdb;
|
||||
|
||||
//First, lets decide how many records per page to show
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
$logged_in_users_table = AIOWPSEC_TBL_LOGGED_IN_USERS;
|
||||
$current_page = $this->get_pagenum();
|
||||
$offset = ($current_page - 1) * $per_page;
|
||||
|
||||
// Parameters that are going to be used to order the result
|
||||
// phpcs:disable -- Rule won't be silenced any other way. No nonce.
|
||||
$orderby = isset($_GET["orderby"]) ? sanitize_text_field(wp_unslash($_GET["orderby"])) : '';
|
||||
$order = isset($_GET["order"]) ? sanitize_text_field(wp_unslash($_GET["order"])) : '';
|
||||
// phpcs:enable -- Rule won't be silenced any other way. No nonce.
|
||||
|
||||
// By default show the most recent logged in user entries.
|
||||
$orderby = empty($orderby) ? 'created' : esc_sql($orderby);
|
||||
$order = empty($order) ? 'DESC' : esc_sql($order);
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
$orderby = sanitize_sql_orderby($orderby);
|
||||
$order = sanitize_sql_orderby($order);
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action(); // Process bulk actions
|
||||
|
||||
$where_sql = $this->get_where_sql();
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$total_items = $wpdb->get_var("SELECT COUNT(*) FROM `{$logged_in_users_table}` $where_sql");
|
||||
|
||||
if ($ignore_pagination) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM `{$logged_in_users_table}` $where_sql ORDER BY $orderby $order", 'ARRAY_A');
|
||||
} else {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM `{$logged_in_users_table}` $where_sql ORDER BY $orderby $order LIMIT $per_page OFFSET $offset", 'ARRAY_A');
|
||||
}
|
||||
|
||||
$this->items = $data;
|
||||
|
||||
if ($ignore_pagination) return;
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will build and return the SQL WHERE statement
|
||||
*
|
||||
* @return string - the SQL WHERE statement
|
||||
*/
|
||||
private function get_where_sql() {
|
||||
if (is_main_site() && is_super_admin()) return '';
|
||||
|
||||
return is_multisite() ? sprintf("WHERE site_id = %d", get_current_blog_id()) : '';
|
||||
}
|
||||
}
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Blocked_IP extends AIOWPSecurity_List_Table {
|
||||
|
||||
public function __construct() {
|
||||
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns created column in datetime format as per user setting time zone.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the datetime
|
||||
*/
|
||||
public function column_created($item) {
|
||||
return AIOWPSecurity_Utility::convert_timestamp($item['created']);
|
||||
}
|
||||
|
||||
public function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to populate the permanent blocked ip actions column in the table
|
||||
*
|
||||
* @param array $item - Contains the current item data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function column_id($item) {
|
||||
$actions = array(
|
||||
'unblock' => '<a href="" class="aios-unblock-permanent-ip" data-id="'.esc_attr($item['id']).'" data-message="'.esc_js(__('Are you sure you want to unblock this IP address?', 'all-in-one-wp-security-and-firewall')).'">Unblock</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/
|
||||
$item['id'],
|
||||
/*$2%s*/
|
||||
$this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function column_cb($item) {
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/
|
||||
$this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/
|
||||
$item['id'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'cb' => '<input type="checkbox" />', //Render a checkbox
|
||||
'id' => 'ID',
|
||||
'blocked_ip' => __('Blocked IP', 'all-in-one-wp-security-and-firewall'),
|
||||
'block_reason' => __('Reason', 'all-in-one-wp-security-and-firewall'),
|
||||
'created' => __('Date and Time', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
}
|
||||
|
||||
public function get_sortable_columns() {
|
||||
return array(
|
||||
'id' => array('id', false),
|
||||
'blocked_ip' => array('blocked_ip', false),
|
||||
'block_reason' => array('block_reason', false),
|
||||
'created' => array('created', false)
|
||||
);
|
||||
}
|
||||
|
||||
public function get_bulk_actions() {
|
||||
return array(
|
||||
'unblock' => __('Unblock', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
}
|
||||
|
||||
private function process_bulk_action() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- PCP warning. It IS the nonce. Ignore.
|
||||
if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return;
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- PCP warning. Ignore.
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items');
|
||||
if (is_wp_error($result)) return;
|
||||
|
||||
if ('unblock' === $this->current_action()) { // Process unlock bulk actions
|
||||
if (!isset($_REQUEST['item'])) {
|
||||
AIOS_Helper::set_message('aios_list_message', __('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'), 'error');
|
||||
} else {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- PCP warning. Sanitized later
|
||||
$this->unblock_ip_address(wp_unslash($_REQUEST['item']));
|
||||
}
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. It IS the nonce. Ignore.
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes one or more records from the AIOWPSEC_TBL_PERM_BLOCK table.
|
||||
*
|
||||
* @param array|string|integer $entries - ids or a single id
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public function unblock_ip_address($entries) {
|
||||
global $wpdb, $aio_wp_security;
|
||||
if (is_array($entries)) {
|
||||
// multiple records
|
||||
|
||||
$entries = array_filter($entries, 'is_numeric'); //discard non-numeric ID values
|
||||
$id_list = "(" . implode(",", $entries) . ")"; //Create comma separate list for DB operation
|
||||
$delete_command = "DELETE FROM " . AIOWPSEC_TBL_PERM_BLOCK . " WHERE id IN " . $id_list; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $id_list cannot be prepared.
|
||||
$result = $wpdb->query($delete_command);
|
||||
if ($result) {
|
||||
AIOS_Helper::set_message('aios_list_message', __('Successfully unblocked and deleted the selected record(s).', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
// Error on bulk delete
|
||||
$aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Perm Block table. Database error: '.$wpdb->last_error, 4);
|
||||
AIOS_Helper::set_message('aios_list_message', __('Failed to unblock and delete the selected record(s).', 'all-in-one-wp-security-and-firewall'), 'error');
|
||||
}
|
||||
} elseif (!empty($entries)) {
|
||||
//Delete single record
|
||||
$delete_command = "DELETE FROM " . AIOWPSEC_TBL_PERM_BLOCK . " WHERE id = %d";
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$result = $wpdb->query($wpdb->prepare($delete_command, absint($entries)));
|
||||
if (false === $result) {
|
||||
// Error on single delete
|
||||
$aio_wp_security->debug_logger->log_debug('Database error occurred when deleting rows from Perm Block table. Database error: '.$wpdb->last_error, 4);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will build and return the SQL WHERE statement
|
||||
*
|
||||
* @param string $search_term - the search term applied
|
||||
*
|
||||
* @return string - the SQL WHERE statement
|
||||
*/
|
||||
private function get_permanent_blocked_ip_list_where_sql($search_term) {
|
||||
$where = '';
|
||||
if (!empty($search_term)) {
|
||||
$where = " WHERE";
|
||||
|
||||
// We don't use FILTER_VALIDATE_IP here as we want to be able to search for partial IP's
|
||||
if (preg_match('/^[0-9a-f:\.]+$/i', $search_term)) {
|
||||
$where .= " `blocked_ip` LIKE '%".esc_sql($search_term)."%' OR";
|
||||
}
|
||||
|
||||
$where .= " `block_reason` LIKE '%".esc_sql($search_term)."%'";
|
||||
$where .= " OR `country_origin` LIKE '%".esc_sql($search_term)."%'";
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the data from database and handles the pagination
|
||||
*
|
||||
* @param boolean $ignore_pagination - whether to not paginate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepare_items($ignore_pagination = false) {
|
||||
/**
|
||||
* First, lets decide how many records per page to show
|
||||
*/
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$search = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : '';
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
global $wpdb;
|
||||
$block_table_name = AIOWPSEC_TBL_PERM_BLOCK;
|
||||
|
||||
// Ordering parameters
|
||||
// Parameters that are going to be used to order the result
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$orderby = isset($_GET["orderby"]) ? sanitize_text_field(wp_unslash($_GET["orderby"])) : '';
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$order = isset($_GET["order"]) ? sanitize_text_field(wp_unslash($_GET["order"])) : '';
|
||||
|
||||
$orderby = !empty($orderby) ? esc_sql($orderby) : 'id';
|
||||
$order = !empty($order) ? esc_sql($order) : 'DESC';
|
||||
|
||||
$orderby = AIOWPSecurity_Utility::sanitize_value_by_array($orderby, $sortable);
|
||||
$order = AIOWPSecurity_Utility::sanitize_value_by_array($order, array('DESC' => '1', 'ASC' => '1'));
|
||||
|
||||
$current_page = $this->get_pagenum();
|
||||
$offset = ($current_page - 1) * $per_page;
|
||||
|
||||
|
||||
$search_query = $this->get_permanent_blocked_ip_list_where_sql($search);
|
||||
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$total_items = $wpdb->get_var("SELECT COUNT(*) FROM {$block_table_name}{$search_query}");
|
||||
|
||||
if ($ignore_pagination) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM {$block_table_name} {$search_query} ORDER BY $orderby$order", 'ARRAY_A');
|
||||
} else {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP warning. Ignore.
|
||||
$data = $wpdb->get_results("SELECT * FROM {$block_table_name}{$search_query} ORDER BY $orderby $order LIMIT $per_page OFFSET $offset", 'ARRAY_A');
|
||||
}
|
||||
|
||||
$this->items = $data;
|
||||
|
||||
if ($ignore_pagination) return;
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
}
|
||||
Executable
+355
@@ -0,0 +1,355 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_List_Registered_Users extends AIOWPSecurity_List_Table {
|
||||
|
||||
public function __construct() {
|
||||
|
||||
|
||||
//Set parent defaults
|
||||
parent::__construct(array(
|
||||
'singular' => 'item', //singular name of the listed records
|
||||
'plural' => 'items', //plural name of the listed records
|
||||
'ajax' => false //does this table support ajax?
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
public function column_default($item, $column_name) {
|
||||
return $item[$column_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ID column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_ID($item) {
|
||||
//Build row actions
|
||||
$actions = array(
|
||||
'view' => '<a href="user-edit.php?user_id='.$item['ID'].'" target="_blank">'.__('View', 'all-in-one-wp-security-and-firewall').'</a>',
|
||||
'approve_acct' => '<a class="aios-approve-user-acct" href="" data-id="'.esc_attr($item['ID']).'" data-message="'.esc_js(__('Are you sure you want to approve this account?', 'all-in-one-wp-security-and-firewall')).'">'. __('Approve', 'all-in-one-wp-security-and-firewall') . '</a>',
|
||||
'delete_acct' => '<a class="aios-delete-user-acct" href="" data-id="'.esc_attr($item['ID']).'" data-message="'.esc_js(__('Are you sure you want to delete this account?', 'all-in-one-wp-security-and-firewall')).'">'. __('Delete', 'all-in-one-wp-security-and-firewall') . '</a>',
|
||||
'block_ip' => '<a class="aios-block-ip" href="" data-ip="'.esc_attr($item['ip_address']).'" data-message="'.esc_js(__('Are you sure you want to block this IP address?', 'all-in-one-wp-security-and-firewall')).'">'. __('Block IP', 'all-in-one-wp-security-and-firewall') . '</a>',
|
||||
);
|
||||
|
||||
//Return the user_login contents
|
||||
return sprintf('%1$s <span style="color:silver"></span>%2$s',
|
||||
/*$1%s*/ $item['ID'],
|
||||
/*$2%s*/ $this->row_actions($actions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns IP address column html to be rendered.
|
||||
*
|
||||
* @param array $item - data for the columns on the current row
|
||||
*
|
||||
* @return string - the html to be rendered
|
||||
*/
|
||||
public function column_ip_address($item) {
|
||||
if (AIOWPSecurity_Blocking::is_ip_blocked($item['ip_address'])) {
|
||||
return $item['ip_address'].'<br /><span class="aiowps-label aiowps-label-success">'.__('blocked', 'all-in-one-wp-security-and-firewall').'</span>';
|
||||
} else {
|
||||
return $item['ip_address'];
|
||||
}
|
||||
}
|
||||
|
||||
public function column_cb($item) {
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
/*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
|
||||
/*$2%s*/ $item['ID'] //The value of the checkbox should be the record's id
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns array of columns to be rendered.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox">', // Render a checkbox
|
||||
'ID' => __('User ID', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_login' => __('Login name', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_email' => __('Email', 'all-in-one-wp-security-and-firewall'),
|
||||
'user_registered' => __('Register date', 'all-in-one-wp-security-and-firewall'),
|
||||
'account_status' => __('Account status', 'all-in-one-wp-security-and-firewall'),
|
||||
'ip_address' => __('IP address', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function get_sortable_columns() {
|
||||
$sortable_columns = array(
|
||||
// 'ID' => array('ID',false),
|
||||
// 'user_login' => array('user_login',false),
|
||||
// 'user_email' => array('user_email',false),
|
||||
// 'user_registered' => array('user_registered',false),
|
||||
// 'account_status' => array('account_status',false),
|
||||
);
|
||||
return $sortable_columns;
|
||||
}
|
||||
|
||||
public function get_bulk_actions() {
|
||||
$actions = array(
|
||||
'approve' => __('Approve', 'all-in-one-wp-security-and-firewall'),
|
||||
'delete' => __('Delete', 'all-in-one-wp-security-and-firewall'),
|
||||
'block' => __('Block IP', 'all-in-one-wp-security-and-firewall')
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process bulk actions.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function process_bulk_action() {
|
||||
if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap(sanitize_text_field(wp_unslash($_REQUEST['_wpnonce'])), 'bulk-items'); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
if (is_wp_error($result)) return;
|
||||
|
||||
if ('approve' == $this->current_action()) { //Process approve bulk actions
|
||||
if (!isset($_REQUEST['item'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
$this->approve_selected_accounts(array_map('sanitize_text_field', wp_unslash($_REQUEST['item']))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
}
|
||||
}
|
||||
|
||||
if ('delete' == $this->current_action()) { //Process delete bulk actions
|
||||
if (!isset($_REQUEST['item'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
$this->delete_selected_accounts(array_map('sanitize_text_field', wp_unslash($_REQUEST['item']))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
}
|
||||
}
|
||||
|
||||
if ('block' == $this->current_action()) { //Process block bulk actions
|
||||
if (!isset($_REQUEST['item'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall'));
|
||||
} else {
|
||||
$this->block_selected_ips(array_map('sanitize_text_field', wp_unslash($_REQUEST['item']))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function approves selected user accounts
|
||||
*
|
||||
* @param array|int $entries - this is an array of users or user_id to be approved
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public function approve_selected_accounts($entries) {
|
||||
global $aio_wp_security;
|
||||
$meta_key = 'aiowps_account_status';
|
||||
$meta_value = 'approved'; // set account status
|
||||
$failed_accts = ''; // string to store comma separated accounts which failed to update
|
||||
$at_least_one_updated = false;
|
||||
if (is_array($entries)) {
|
||||
$entries = array_map('esc_sql', $entries); // Escape every array element
|
||||
//Let's go through each entry and approve
|
||||
foreach ($entries as $user_id) {
|
||||
$result = update_user_meta($user_id, $meta_key, $meta_value);
|
||||
if (false === $result) {
|
||||
$failed_accts .= ' '.$user_id.', ';
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::approve_selected_accounts() - could not approve account ID: $user_id", 4);
|
||||
} else {
|
||||
$at_least_one_updated = true;
|
||||
$user = get_user_by('id', $user_id);
|
||||
if (false === $user) {
|
||||
//don't send mail
|
||||
} else {
|
||||
$this->send_email_upon_account_activation($user);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($at_least_one_updated) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected accounts were approved successfully.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
if ('' != $failed_accts) {
|
||||
//display any failed account updates
|
||||
rtrim($failed_accts);
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('The following accounts failed to update successfully:', 'all-in-one-wp-security-and-firewall') . ' ' . $failed_accts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sends an email to an approved user
|
||||
*
|
||||
* @param WP_User $user - the object for the approved user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function send_email_upon_account_activation($user) {
|
||||
global $aio_wp_security;
|
||||
if (!($user instanceof WP_User)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$to_email_address = $user->user_email;
|
||||
$email_msg = '';
|
||||
$subject = '['.network_site_url().'] '. __('Your account is now active', 'all-in-one-wp-security-and-firewall');
|
||||
/* translators: %s: Username */
|
||||
$email_msg .= sprintf(__('Your account with username: %s is now active', 'all-in-one-wp-security-and-firewall'), $user->user_login) . "\n";
|
||||
$subject = apply_filters('aiowps_register_approval_email_subject', $subject);
|
||||
$email_msg = apply_filters('aiowps_register_approval_email_msg', $email_msg, $user); //also pass the WP_User object
|
||||
|
||||
$sendMail = wp_mail($to_email_address, $subject, $email_msg);
|
||||
if (false === $sendMail) {
|
||||
$aio_wp_security->debug_logger->log_debug("Manual account approval notification email failed to send to " . $to_email_address, 4);
|
||||
}
|
||||
return $sendMail;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function deletes selected entries pending approval
|
||||
*
|
||||
* @param array|int $entries - this is an array of users or single user to be deleted
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public function delete_selected_accounts($entries) {
|
||||
global $aio_wp_security;
|
||||
if (is_array($entries)) {
|
||||
$entries = array_map('esc_sql', $entries); // Escape every array element
|
||||
//Let's go through each entry and delete account
|
||||
foreach ($entries as $user_id) {
|
||||
$result = wp_delete_user($user_id);
|
||||
if (true !== $result) {
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::delete_selected_accounts() - could not delete account ID: $user_id", 4);
|
||||
}
|
||||
}
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The selected accounts were deleted successfully.', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function blocks selected ip
|
||||
*
|
||||
* @param array|int $entries - this is an array of ips or ip to be blocked
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public function block_selected_ips($entries) {
|
||||
global $aio_wp_security;
|
||||
if (is_array($entries)) {
|
||||
$entries = array_filter($entries, function ($entry) {
|
||||
return AIOWPSecurity_Utility_IP::get_user_ip_address() != $entry;
|
||||
});
|
||||
|
||||
if (empty($entries)) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Only invalid IP addresses were provided: you can not block your own IP address', 'all-in-one-wp-security-and-firewall'));
|
||||
return;
|
||||
}
|
||||
$entries = array_map('esc_sql', $entries); // Escape every array element
|
||||
//Let's go through each entry and block IP
|
||||
$total_success = 0;
|
||||
foreach ($entries as $id) {
|
||||
$ip_address = get_user_meta($id, 'aiowps_registrant_ip', true);
|
||||
$result = AIOWPSecurity_Blocking::add_ip_to_block_list($ip_address, 'registration_spam');
|
||||
if (false === $result) {
|
||||
if (AIOWPSecurity_Utility_IP::get_user_ip_address() == $ip_address) {
|
||||
AIOWPSecurity_Admin_Menu::show_msg_error_st(__('You cannot block your own IP address:', 'all-in-one-wp-security-and-firewall') . ' ' . $ip_address);
|
||||
}
|
||||
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_List_Registered_Users::block_selected_ips() - could not block IP : $ip_address", 4);
|
||||
} else {
|
||||
$total_success++;
|
||||
}
|
||||
}
|
||||
if ($total_success > 0) {
|
||||
$msg = __('The selected IP addresses were successfully added to the permanent block list.', 'all-in-one-wp-security-and-firewall');
|
||||
$msg .= ' <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>';
|
||||
AIOWPSecurity_Admin_Menu::show_msg_updated_st($msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the data from database and handles the pagination
|
||||
*
|
||||
* @param boolean $ignore_pagination - whether to not paginate
|
||||
* @return void
|
||||
*/
|
||||
public function prepare_items($ignore_pagination = false) {
|
||||
//First, lets decide how many records per page to show
|
||||
$per_page = 100;
|
||||
$columns = $this->get_columns();
|
||||
$current_page = $this->get_pagenum();
|
||||
$offset = ($current_page - 1) * $per_page;
|
||||
$hidden = array();
|
||||
$sortable = $this->get_sortable_columns();
|
||||
$search = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- pcp check ingore this
|
||||
|
||||
$this->_column_headers = array($columns, $hidden, $sortable);
|
||||
|
||||
$this->process_bulk_action();
|
||||
|
||||
//Get registered users which have the special 'aiowps_account_status' meta key set to 'pending'
|
||||
if ($ignore_pagination) {
|
||||
$result = $this->get_registered_user_data('pending', $search);
|
||||
} else {
|
||||
$result = $this->get_registered_user_data('pending', $search, $per_page, $offset);
|
||||
}
|
||||
|
||||
$total_items = $result['total'];
|
||||
$this->items = $result['data'];
|
||||
|
||||
if ($ignore_pagination) return;
|
||||
|
||||
$this->set_pagination_args(array(
|
||||
'total_items' => $total_items, //WE have to calculate the total number of items
|
||||
'per_page' => $per_page, //WE have to determine how many items to show on a page
|
||||
'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all users who have the special 'aiowps_account_status' meta key
|
||||
*
|
||||
* @param string $status - the status we want to search for
|
||||
* @param string $search - the search query
|
||||
* @param null $per_page - how many results per page
|
||||
* @param int $offset - the page offset
|
||||
*
|
||||
* @return array - an array of users that match the search
|
||||
*/
|
||||
public function get_registered_user_data($status = '', $search = '', $per_page = null, $offset = 0) {
|
||||
$user_fields = array( 'ID', 'user_login', 'user_email', 'user_registered');
|
||||
$user_query = new WP_User_Query(array('meta_key' => 'aiowps_account_status', 'meta_value' => $status, 'fields' => $user_fields, 'number' => $per_page, 'offset' => $offset)); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key, WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- ignore this
|
||||
$user_results = $user_query->results;
|
||||
$user_total = $user_query->get_total();
|
||||
|
||||
$final_data = array();
|
||||
foreach ($user_results as $user) {
|
||||
$temp_array = get_object_vars($user); //Turn the object into array
|
||||
$temp_array['account_status'] = get_user_meta($temp_array['ID'], 'aiowps_account_status', true);
|
||||
$ip = get_user_meta($temp_array['ID'], 'aiowps_registrant_ip', true);
|
||||
$temp_array['ip_address'] = empty($ip) ? '' : $ip;
|
||||
if (empty($search)) {
|
||||
$final_data[] = $temp_array;
|
||||
} else {
|
||||
$input = preg_quote($search, '~'); // don't forget to quote input string!
|
||||
|
||||
$result = preg_grep('~' . $input . '~', $temp_array);
|
||||
if (!empty($result)) $final_data[] = $temp_array;
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'data' => $final_data,
|
||||
'total' => $user_total,
|
||||
);
|
||||
}
|
||||
}
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
if (!class_exists('AIOWPSecurity_Reset_Settings')) :
|
||||
|
||||
/**
|
||||
* Reset Settings various methods
|
||||
*/
|
||||
class AIOWPSecurity_Reset_Settings {
|
||||
|
||||
/**
|
||||
* Delete config option.
|
||||
*
|
||||
* @return boolean true if the aio_wp_security_configs option deleted successfully.
|
||||
*/
|
||||
public static function reset_options() {
|
||||
$result_delete_option = false === get_option('aio_wp_security_configs', false) || delete_option('aio_wp_security_configs');
|
||||
$result_reset_settings = AIOWPSecurity_Configure_Settings::set_default_settings();
|
||||
return $result_delete_option && $result_reset_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete htaccess rules.
|
||||
*
|
||||
* @param string $section - section used to find AIOS rules in .htaccess file
|
||||
*
|
||||
* @return boolean true if the aio_wp_security_configs option deleted successfully.
|
||||
*/
|
||||
public static function delete_htaccess($section = 'All In One WP Security') {
|
||||
$htaccess = ABSPATH . '.htaccess';
|
||||
|
||||
if (!file_exists($htaccess)) {
|
||||
return false;
|
||||
}
|
||||
// phpcs:disable WordPress.WP.AlternativeFunctions -- Cannot use wp_filesystem in the firewall.
|
||||
$ht_contents = preg_split('/\r\n|\r|\n/', file_get_contents($htaccess));
|
||||
if ($ht_contents) { // as long as there are lines in the file
|
||||
$state = true;
|
||||
$f = @fopen($htaccess, 'w+');
|
||||
if (!$f) {
|
||||
@chmod($htaccess, 0644);
|
||||
$f = @fopen($htaccess, 'w+');
|
||||
if (!$f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($ht_contents as $markerline) { // for each line in the file
|
||||
if (strpos($markerline, '# BEGIN ' . $section) !== false) { // if we're at the beginning of the section
|
||||
$state = false;
|
||||
}
|
||||
if (true == $state) { // as long as we're not in the section keep writing
|
||||
fwrite($f, trim($markerline) . "\n");
|
||||
}
|
||||
if (strpos($markerline, '# END ' . $section) !== false) { // see if we're at the end of the section
|
||||
$state = true;
|
||||
}
|
||||
}
|
||||
@fclose($f);
|
||||
return true;
|
||||
}
|
||||
// phpcs:enable WordPress.WP.AlternativeFunctions -- Cannot use wp_filesystem in the firewall.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete database tables
|
||||
*
|
||||
* @return boolean true
|
||||
*/
|
||||
public static function reset_db_tables() {
|
||||
// Reset (TRUNCATE) all the db tables of the plugin.
|
||||
global $wpdb;
|
||||
$wpdb->query('TRUNCATE ' . $wpdb->prefix . 'aiowps_login_lockdown');
|
||||
$wpdb->query('TRUNCATE ' . $wpdb->prefix . 'aiowps_global_meta');
|
||||
$wpdb->query('TRUNCATE ' . $wpdb->prefix . 'aiowps_events');
|
||||
$wpdb->query('TRUNCATE ' . $wpdb->prefix . 'aiowps_permanent_block');
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Ignore.
|
||||
if (is_main_site()) {
|
||||
$wpdb->query('TRUNCATE ' . AIOWPSEC_TBL_LOGGED_IN_USERS);
|
||||
$wpdb->query('TRUNCATE ' . AIOWPSEC_TBL_MESSAGE_STORE);
|
||||
$wpdb->query('TRUNCATE ' . AIOWPSEC_TBL_DEBUG_LOG);
|
||||
$wpdb->query('TRUNCATE ' . AIOWPSEC_TBL_AUDIT_LOG);
|
||||
}
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared -- PCP error. Ignore.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
Executable
+157
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access.');
|
||||
|
||||
/**
|
||||
* AIOWPSecurity_Settings_Menu class for setting configs.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
class AIOWPSecurity_Settings_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Settings menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_SETTINGS_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Settings
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('Settings', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'general-settings' => array(
|
||||
'title' => __('General settings', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_general_settings'),
|
||||
),
|
||||
'htaccess-file-operations' => array(
|
||||
'title' => '.htaccess '.__('file', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_htaccess_file_operations'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'wp-config-file-operations' => array(
|
||||
'title' => 'wp-config.php '.__('file', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_wp_config_file_operations'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'delete-plugin-settings' => array(
|
||||
'title' => __('Delete plugin settings', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_delete_plugin_settings_tab')
|
||||
),
|
||||
'wp-version-info' => array(
|
||||
'title' => __('WP version info', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_wp_version_info'),
|
||||
),
|
||||
'settings-file-operations' => array(
|
||||
'title' => __('Import/Export', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_settings_file_operations'),
|
||||
),
|
||||
'advanced-settings' => array(
|
||||
'title' => __('Advanced settings', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_advanced_settings'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
);
|
||||
|
||||
$menu_tabs = apply_filters('aiowpsecurity_setting_tabs', $menu_tabs);
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's general settings tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_general_settings() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/settings/general-settings.php', false, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's htaccess file operations tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_htaccess_file_operations() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/settings/htaccess-file-operations.php', false, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's wp config file operations tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_wp_config_file_operations() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/settings/wp-config-file-operations.php', false, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's delete plugin settings tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_delete_plugin_settings_tab() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/settings/delete-plugin-settings.php', false, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's wp version info tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_wp_version_info() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/settings/wp-version-info.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's settings file operations tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_settings_file_operations() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$events_table_name = AIOWPSEC_TBL_EVENTS;
|
||||
AIOWPSecurity_Utility::cleanup_table($events_table_name, 500);
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/settings/settings-file-operations.php', false, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders advanced settings tab.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_advanced_settings() {
|
||||
if (!is_main_site()) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $aio_wp_security;
|
||||
|
||||
$aios_commands = new AIOWPSecurity_Commands();
|
||||
|
||||
$advanced_settings_data = $aios_commands->get_ip_address_detection_data();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/settings/advanced-settings.php', false, $advanced_settings_data);
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Spam_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Spam menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_SPAM_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Spam prevention
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('Spam prevention', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'comment-spam' => array(
|
||||
'title' => __('Comment spam', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_comment_spam'),
|
||||
),
|
||||
'comment-spam-ip-monitoring' => array(
|
||||
'title' => __('Comment spam IP monitoring', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_comment_spam_ip_monitoring'),
|
||||
),
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's comment spam ip monitoring tab body.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_comment_spam() {
|
||||
global $aiowps_feature_mgr, $aio_wp_security;
|
||||
$aio_wp_security->include_template('wp-admin/spam-prevention/comment-spam.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's comment spam ip monitoring tab body.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_comment_spam_ip_monitoring() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr, $wpdb;
|
||||
include_once 'wp-security-list-comment-spammer-ip.php'; // For rendering the AIOWPSecurity_List_Table in tab2
|
||||
$spammer_ip_list = new AIOWPSecurity_List_Comment_Spammer_IP();
|
||||
|
||||
$block_comments_output = '';
|
||||
|
||||
$min_block_comments = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments_block');
|
||||
if (!empty($min_block_comments)) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- PCP error. Ignore.
|
||||
$total_res = $wpdb->get_results($wpdb->prepare('SELECT * FROM '.AIOWPSEC_TBL_PERM_BLOCK.' WHERE block_reason=%s', 'spam'));
|
||||
$block_comments_output = '<div class="aio_yellow_box">';
|
||||
if (empty($total_res)) {
|
||||
$block_comments_output .= '<p><strong>'.esc_html__('You currently have no IP addresses permanently blocked due to spam.', 'all-in-one-wp-security-and-firewall').'</strong></p></div>';
|
||||
} else {
|
||||
$total_count = count($total_res);
|
||||
$todays_blocked_count = 0;
|
||||
foreach ($total_res as $blocked_item) {
|
||||
$now_date_time = new DateTime('now', new DateTimeZone('UTC'));
|
||||
$blocked_date = new DateTime('@'.$blocked_item->created); //@ with timestamp creates correct DateTime
|
||||
if ($blocked_date->format('Y-m-d') == $now_date_time->format('Y-m-d')) {
|
||||
//there was an IP added to permanent block list today
|
||||
++$todays_blocked_count;
|
||||
}
|
||||
}
|
||||
$block_comments_output .= '<p><strong>'.esc_html__('Spammer IPs added to permanent block list today:', 'all-in-one-wp-security-and-firewall'). ' ' . esc_html($todays_blocked_count).'</strong></p>'.'<hr><p><strong>'.esc_html__('All time total:', 'all-in-one-wp-security-and-firewall'). ' ' .esc_html($total_count).'</strong></p>'.'<p><a class="button" href="admin.php?page='.esc_attr(AIOWPSEC_MAIN_MENU_SLUG).'&tab=permanent-block" target="_blank">'.esc_html__('View blocked IPs', 'all-in-one-wp-security-and-firewall').'</a></p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : '';
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- PCP warning. No nonce.
|
||||
$tab = isset($_REQUEST['tab']) ? sanitize_text_field(wp_unslash($_REQUEST['tab'])) : '';
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/spam-prevention/comment-spam-ip-monitoring.php', false, array('spammer_ip_list' => $spammer_ip_list, 'aiowps_feature_mgr' => $aiowps_feature_mgr, 'block_comments_output' => $block_comments_output, 'page' => $page, 'tab' => $tab));
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_Tools_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Tools menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_TOOLS_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for Tools
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('Tools', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will setup the menus tabs by setting the array $menu_tabs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'password-tool' => array(
|
||||
'title' => __('Password tool', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_password_tool'),
|
||||
),
|
||||
'whois-lookup' => array(
|
||||
'title' => __('WHOIS lookup', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_whois_lookup_tab'),
|
||||
),
|
||||
'custom-rules' => array(
|
||||
'title' => __('Custom .htaccess rules', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_custom_rules'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility', 'allow_to_write_to_htaccess'),
|
||||
),
|
||||
'visitor-lockout' => array(
|
||||
'title' => __('Visitor lockout', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_visitor_lockout'),
|
||||
),
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the 'Custom (htaccess) rules' tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_custom_rules() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/tools/custom-htaccess.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's password tool tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_password_tool() {
|
||||
global $aio_wp_security;
|
||||
|
||||
wp_enqueue_script('aiowpsec-pw-tool-js');
|
||||
$aio_wp_security->include_template('wp-admin/tools/password-tool.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's whois-lookup tab body.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_whois_lookup_tab() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/tools/whois-lookup.php', false, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's visitor lockout tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_visitor_lockout() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/tools/visitor-lockout.php', false, array());
|
||||
}
|
||||
|
||||
} // End of class
|
||||
Executable
+296
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class AIOWPSecurity_User_Security_Menu extends AIOWPSecurity_Admin_Menu {
|
||||
|
||||
/**
|
||||
* User Security menu slug
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $menu_page_slug = AIOWPSEC_USER_SECURITY_MENU_SLUG;
|
||||
|
||||
/**
|
||||
* Constructor adds menu for User Security
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(__('User Security', 'all-in-one-wp-security-and-firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates $menu_tabs array.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function setup_menu_tabs() {
|
||||
$menu_tabs = array(
|
||||
'wp-user_accounts' => array(
|
||||
'title' => __('User accounts', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_wp_user_account'),
|
||||
),
|
||||
'login-lockout' => array(
|
||||
'title' => __('Login lockout', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_login_lockout'),
|
||||
),
|
||||
'force-logout' => array(
|
||||
'title' => __('Force logout', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_force_logout'),
|
||||
),
|
||||
'logged-in-users' => array(
|
||||
'title' => __('Logged in users', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_logged_in_users'),
|
||||
),
|
||||
'manual-approval' => array(
|
||||
'title' => __('Manual approval', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_manual_approval'),
|
||||
),
|
||||
'salt' => array(
|
||||
'title' => __('Salt', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_salt_tab'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'http-authentication' => array(
|
||||
'title' => __('HTTP authentication', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_http_authentication'),
|
||||
),
|
||||
'hibp' => array(
|
||||
'title' => __('HIBP', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_hibp'),
|
||||
'display_condition_callback' => array('AIOWPSecurity_Utility_Permissions', 'is_main_site_and_super_admin'),
|
||||
),
|
||||
'additional' => array(
|
||||
'title' => __('Additional settings', 'all-in-one-wp-security-and-firewall'),
|
||||
'render_callback' => array($this, 'render_additional'),
|
||||
),
|
||||
);
|
||||
|
||||
$this->menu_tabs = array_filter($menu_tabs, array($this, 'should_display_tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's WP User Account tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_wp_user_account() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
if (is_multisite()) { // Multi-site: get admin accounts for current site
|
||||
$blog_id = get_current_blog_id();
|
||||
$user_accounts = $this->get_all_admin_accounts($blog_id);
|
||||
} else {
|
||||
$user_accounts = $this->get_all_admin_accounts();
|
||||
}
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/user-accounts.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'user_accounts' => $user_accounts, 'AIOWPSecurity_User_Security_Menu' => $this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will retrieve all user accounts which have 'administrator' role and will return html code with results in a table
|
||||
*
|
||||
* @param string $blog_id - the blog we want to get the user account information from
|
||||
*
|
||||
* @return string - the html from the result
|
||||
*/
|
||||
private function get_all_admin_accounts($blog_id = '') {
|
||||
// TODO: Have included the "blog_id" variable for future use for cases where people want to search particular blog (eg, multi-site)
|
||||
if ($blog_id) {
|
||||
$admin_users = get_users('blog_id='.$blog_id.'&orderby=login&role=administrator');
|
||||
} else {
|
||||
$admin_users = get_users('orderby=login&role=administrator');
|
||||
}
|
||||
// now let's put the results in an HTML table
|
||||
$account_output = "";
|
||||
if (!empty($admin_users)) {
|
||||
$account_output .= '<table>';
|
||||
$account_output .= '<tr><th>'.esc_html(__('Account login name', 'all-in-one-wp-security-and-firewall')).'</th></tr>';
|
||||
foreach ($admin_users as $entry) {
|
||||
$account_output .= '<tr>';
|
||||
if (strtolower($entry->user_login) == 'admin') {
|
||||
$account_output .= '<td style="color:red; font-weight: bold;">'.esc_html($entry->user_login).'</td>';
|
||||
} else {
|
||||
$account_output .= '<td>'.esc_html($entry->user_login).'</td>';
|
||||
}
|
||||
$user_acct_edit_link = admin_url('user-edit.php?user_id=' . $entry->ID);
|
||||
$account_output .= '<td><a href="'.esc_url($user_acct_edit_link).'" target="_blank">'.esc_html(__('Edit user', 'all-in-one-wp-security-and-firewall')).'</a></td>';
|
||||
$account_output .= '</tr>';
|
||||
}
|
||||
$account_output .= '</table>';
|
||||
}
|
||||
return $account_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login Lockout configuration to set.
|
||||
*
|
||||
* @global AIO_WP_Security $aio_wp_security
|
||||
* @global AIOWPSecurity_Feature_Item_Manager $aiowps_feature_mgr
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_login_lockout() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
include_once 'wp-security-list-locked-ip.php'; // For rendering the AIOWPSecurity_List_Table in tab1
|
||||
$locked_ip_list = new AIOWPSecurity_List_Locked_IP(); // For rendering the AIOWPSecurity_List_Table in tab1
|
||||
|
||||
$aiowps_lockdown_allowed_ip_addresses = $aio_wp_security->configs->get_value('aiowps_lockdown_allowed_ip_addresses');
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/login-lockout.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr, 'locked_ip_list' => $locked_ip_list, "aiowps_lockdown_allowed_ip_addresses" => $aiowps_lockdown_allowed_ip_addresses));
|
||||
}
|
||||
|
||||
/**
|
||||
* Force logged user to logout after x minutes.
|
||||
*
|
||||
* @global AIO_WP_Security $aio_wp_security
|
||||
* @global AIOWPSecurity_Feature_Item_Manager $aiowps_feature_mgr
|
||||
* @return void
|
||||
*/
|
||||
protected function render_force_logout() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/force-logout.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Logged in users list.
|
||||
*
|
||||
* @global AIO_WP_Security $aio_wp_security
|
||||
* @return void
|
||||
*/
|
||||
protected function render_logged_in_users() {
|
||||
global $aio_wp_security;
|
||||
|
||||
include_once 'wp-security-list-logged-in-users.php'; // For rendering the AIOWPSecurity_List_Table
|
||||
$user_list = new AIOWPSecurity_List_Logged_In_Users();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/logged-in-users.php', false, array('user_list' => $user_list));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's manual approval tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_manual_approval() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
include_once 'wp-security-list-registered-users.php'; // For rendering the AIOWPSecurity_List_Table
|
||||
$user_list = new AIOWPSecurity_List_Registered_Users();
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/manual-approval.php', false, array('user_list' => $user_list, 'aiowps_feature_mgr' => $aiowps_feature_mgr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's salt tab
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
protected function render_salt_tab() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/salt.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's http authentication tab.
|
||||
*
|
||||
* @global AIO_WP_Security $aio_wp_security
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_http_authentication() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
if (isset($_POST['aiowps_save_http_authentication_settings'])) {
|
||||
$nonce_user_cap_result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_POST['_wpnonce'], 'aiowpsec-http-authentication-settings-nonce');
|
||||
|
||||
if (is_wp_error($nonce_user_cap_result)) {
|
||||
$aio_wp_security->debug_logger->log_debug($nonce_user_cap_result->get_error_message(), 4);
|
||||
die($nonce_user_cap_result->get_error_message());
|
||||
}
|
||||
|
||||
$error = false;
|
||||
|
||||
$aio_wp_security->configs->set_value('aiowps_http_authentication_admin', '');
|
||||
|
||||
if (isset($_POST['aiowps_http_authentication_admin'])) {
|
||||
if (!is_ssl()) {
|
||||
$this->show_msg_error(__('Failed to save \'Enable for WordPress dashboard\'.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Your site is currently not using https.', 'all-in-one-wp-security-and-firewall'));
|
||||
$error = true;
|
||||
} else {
|
||||
$aio_wp_security->configs->set_value('aiowps_http_authentication_admin', '1');
|
||||
}
|
||||
}
|
||||
|
||||
$aio_wp_security->configs->set_value('aiowps_http_authentication_frontend', '');
|
||||
|
||||
if (isset($_POST['aiowps_http_authentication_frontend'])) {
|
||||
if (!is_ssl()) {
|
||||
$this->show_msg_error(__('Failed to save \'Enable for frontend\'.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Your site is currently not using https.', 'all-in-one-wp-security-and-firewall'));
|
||||
$error = true;
|
||||
} else {
|
||||
$aio_wp_security->configs->set_value('aiowps_http_authentication_frontend', '1');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($_POST['aiowps_http_authentication_username'])) {
|
||||
$this->show_msg_error(__('Failed to save \'Username\'.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Please enter a value for the HTTP authentication username.', 'all-in-one-wp-security-and-firewall'));
|
||||
$error = true;
|
||||
} else {
|
||||
$aio_wp_security->configs->set_value('aiowps_http_authentication_username', sanitize_text_field($_POST['aiowps_http_authentication_username']));
|
||||
}
|
||||
|
||||
if (empty($_POST['aiowps_http_authentication_password'])) {
|
||||
$this->show_msg_error(__('Failed to save \'Password\'.', 'all-in-one-wp-security-and-firewall') . ' ' . __('Please enter a value for the HTTP authentication password.', 'all-in-one-wp-security-and-firewall'));
|
||||
$error = true;
|
||||
} else {
|
||||
$aio_wp_security->configs->set_value('aiowps_http_authentication_password', sanitize_text_field($_POST['aiowps_http_authentication_password']));
|
||||
}
|
||||
|
||||
$aio_wp_security->configs->set_value('aiowps_http_authentication_failure_message', htmlentities(stripslashes($_POST['aiowps_http_authentication_failure_message']), ENT_COMPAT, 'UTF-8'));
|
||||
|
||||
$aio_wp_security->configs->save_config();
|
||||
|
||||
// Recalculate points after the feature status/options have been altered.
|
||||
$aiowps_feature_mgr->check_feature_status_and_recalculate_points();
|
||||
|
||||
if (!$error) {
|
||||
$this->show_msg_settings_updated();
|
||||
}
|
||||
}
|
||||
|
||||
wp_enqueue_script('aiowpsec-pw-tool-js');
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/http-authentication.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the submenu's hibp tab.
|
||||
*
|
||||
* @global AIO_WP_Security $aio_wp_security
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function render_hibp() {
|
||||
global $aio_wp_security;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/hibp.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows additional tab and field for the disable application password and saves on submit.
|
||||
*
|
||||
* @global AIO_WP_Security $aio_wp_security
|
||||
* @global AIOWPSecurity_Feature_Item_Manager $aiowps_feature_mgr
|
||||
* @return void
|
||||
*/
|
||||
protected function render_additional() {
|
||||
global $aio_wp_security, $aiowps_feature_mgr;
|
||||
|
||||
$aio_wp_security->include_template('wp-admin/user-security/additional.php', false, array('aiowps_feature_mgr' => $aiowps_feature_mgr));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user