346 lines
11 KiB
PHP
346 lines
11 KiB
PHP
<?php
|
|
|
|
if (!defined('ABSPATH')) die('No direct access allowed');
|
|
|
|
if (trait_exists('AIOWPSecurity_Log_Commands_Trait')) return;
|
|
|
|
trait AIOWPSecurity_Log_Commands_Trait {
|
|
|
|
/**
|
|
* Deletes an audit log.
|
|
*
|
|
* @param array $data Contains the ID of the log to be deleted.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function delete_audit_log($data) {
|
|
|
|
if (!isset($data['id'])) {
|
|
return $this->handle_response(false, AIOWPSecurity_Admin_Menu::show_msg_error_st(__('No audit log ID provided.', 'all-in-one-wp-security-and-firewall'), true));
|
|
}
|
|
|
|
include_once AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php';
|
|
$audit_log_list = new AIOWPSecurity_List_Audit_Log();
|
|
|
|
return $this->handle_response(true, $audit_log_list->delete_audit_event_records($data['id']));
|
|
}
|
|
|
|
/**
|
|
* Deletes an IP lockout record.
|
|
*
|
|
* @param array $data Contains the ID of the entry in the AIOWPSEC_TBL_LOGIN_LOCKOUT table.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function delete_locked_ip_record($data) {
|
|
|
|
if (!isset($data['id'])) {
|
|
return $this->handle_response(false, AIOWPSecurity_Admin_Menu::show_msg_error_st(__('No locked IP record ID provided.', 'all-in-one-wp-security-and-firewall'), true));
|
|
}
|
|
|
|
include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-list-locked-ip.php';
|
|
|
|
$locked_ip_list = new AIOWPSecurity_List_Locked_IP();
|
|
$result = $locked_ip_list->delete_lockout_records($data['id']);
|
|
return $this->handle_response(true, $result);
|
|
}
|
|
|
|
/**
|
|
* Clear debug logs
|
|
*
|
|
* @return array
|
|
*/
|
|
public function clear_debug_logs() {
|
|
global $aio_wp_security;
|
|
|
|
$ret = $aio_wp_security->debug_logger->clear_logs();
|
|
|
|
if (is_wp_error($ret)) {
|
|
return $this->handle_response(false, AIOWPSecurity_Admin_Menu::show_msg_error_st(esc_html($ret->get_error_message()).'<p>'.esc_html($ret->get_error_data()).'</p>', true));
|
|
} else {
|
|
return $this->handle_response(true, AIOWPSecurity_Admin_Menu::show_msg_updated_st(__('The debug logs have been cleared.', 'all-in-one-wp-security-and-firewall'), true));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders the audit log tab content.
|
|
*
|
|
* This function handles the rendering of the audit log tab content based on the
|
|
* provided data via AJAX request. The data is used to filter the audit log or perform actions
|
|
*
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function render_audit_log_tab() {
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. Nonce checked in previous function.
|
|
if (empty($_POST['data'])) return;
|
|
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput -- PCP warning. Nonce checked in previous function and sanitization done at later.
|
|
$data = wp_unslash($_POST['data']);
|
|
|
|
// Needed for rendering the audit log table
|
|
include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php');
|
|
$audit_log_list = new AIOWPSecurity_List_Audit_Log($data);
|
|
$audit_log_list->ajax_response();
|
|
}
|
|
|
|
/**
|
|
* Exports the audit logs as a CSV file and sends the data as an AJAX response.
|
|
*
|
|
* This function retrieves audit log data, prepares it for export, and generates a CSV string.
|
|
* The CSV data is then sent back as part of an AJAX response, along with the filename for the CSV file.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function export_audit_logs() {
|
|
|
|
// Needed for rendering the audit log table
|
|
include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php');
|
|
$audit_log_list = new AIOWPSecurity_List_Audit_Log();
|
|
|
|
$audit_log_list->prepare_items(true);
|
|
$export_keys = array(
|
|
'id' => 'ID',
|
|
'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')
|
|
);
|
|
|
|
$title = 'audit_event_logs.csv';
|
|
ob_start();
|
|
AIOWPSecurity_Admin_Init::aiowps_output_csv($audit_log_list->items, $export_keys, $title);
|
|
|
|
$data = ob_get_clean();
|
|
|
|
return array(
|
|
'title' => $title,
|
|
'data' => $data
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Initializing the WP List API, since UDC commands do not load all parts of WP.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function init_wp_list() {
|
|
if (!function_exists('submit_button')) {
|
|
require_once(ABSPATH . 'wp-admin/includes/template.php');
|
|
}
|
|
|
|
if (!function_exists('render_screen_reader_content')) {
|
|
require_once(ABSPATH . 'wp-admin/includes/class-wp-screen.php');
|
|
}
|
|
|
|
if (!function_exists('get_column_headers')) {
|
|
require_once(ABSPATH . 'wp-admin/includes/screen.php');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the data for downloading the audit log.
|
|
*
|
|
* @return array|WP_Error
|
|
*/
|
|
public function process_audit_log_export() {
|
|
if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
|
|
return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall'));
|
|
}
|
|
|
|
$this->init_wp_list();
|
|
|
|
return $this->export_audit_logs();
|
|
}
|
|
|
|
/**
|
|
* Returns the HTML for the audit log.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_audit_log_contents() {
|
|
global $aio_wp_security;
|
|
|
|
$this->init_wp_list();
|
|
|
|
// Needed for rendering the audit log table
|
|
include_once AIO_WP_SECURITY_PATH . '/admin/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($_GET["tab"]) ? sanitize_text_field(wp_unslash($_GET["tab"])) : '';
|
|
$page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
|
|
// phpcs:enable WordPress.Security.NonceVerification.Recommended -- PCP warning. Processing form data without nonce verification. No nonce.
|
|
|
|
$content = $aio_wp_security->include_template('wp-admin/dashboard/audit-logs.php', true, array('audit_log_list' => $audit_log_list, 'page' => $page, 'tab' => $tab));
|
|
|
|
return array(
|
|
'status' => 'success',
|
|
'content' => $content,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Deletes entry from audit log.
|
|
*
|
|
* @param array $data Table config data.
|
|
*
|
|
* @return array|WP_Error
|
|
*/
|
|
public function do_delete_audit_log($data) {
|
|
if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
|
|
return new WP_Error(esc_html__('Sorry, you do not have enough privilege to execute the requested action.', 'all-in-one-wp-security-and-firewall'));
|
|
}
|
|
|
|
$this->init_wp_list();
|
|
|
|
if (!class_exists('AIOWPSecurity_Admin_Menu')) {
|
|
include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-admin-menu.php';
|
|
}
|
|
|
|
return $this->delete_audit_log($data);
|
|
}
|
|
|
|
/**
|
|
* Renders audit log after actions (delete/orderby, block/unblock, etc.)
|
|
*
|
|
* @param array $data Table config data.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function do_render_audit_log_tab($data) {
|
|
$this->init_wp_list();
|
|
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. Nonce checked in previous function.
|
|
if (empty($data)) return array();
|
|
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput -- PCP warning. Nonce checked in previous function and sanitization done at later.
|
|
$data = wp_unslash($data);
|
|
|
|
if (!class_exists('AIOWPSecurity_Admin_Menu')) {
|
|
include_once AIO_WP_SECURITY_PATH . '/admin/wp-security-admin-menu.php';
|
|
}
|
|
|
|
// Needed for rendering the audit log table
|
|
include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php');
|
|
$audit_log_list = new AIOWPSecurity_List_Audit_Log($data);
|
|
|
|
return $audit_log_list->ajax_response(true);
|
|
}
|
|
|
|
/**
|
|
* Parses raw audit log data for human-readable output.
|
|
*
|
|
* @param AIOWPSecurity_List_Audit_Log $audit_log_list Audit log object.
|
|
* @param array $data Raw audit log data.
|
|
*
|
|
* @return array
|
|
*/
|
|
private function parse_audit_log_data($audit_log_list, $data) {
|
|
$items = array();
|
|
|
|
foreach ($data as $db_item) {
|
|
if (empty($db_item)) {
|
|
continue;
|
|
}
|
|
|
|
$item = array();
|
|
|
|
foreach ($db_item as $key => $value) {
|
|
switch ($key) {
|
|
case 'created':
|
|
$item[$key] = AIOWPSecurity_Utility::convert_timestamp($value);
|
|
break;
|
|
case 'event_type':
|
|
$item[$key] = $audit_log_list->column_event_type($db_item);
|
|
break;
|
|
case 'details':
|
|
$item[$key] = $audit_log_list->column_details($db_item);
|
|
break;
|
|
case 'stacktrace':
|
|
$item[$key] = $audit_log_list->column_stacktrace($db_item);
|
|
break;
|
|
default:
|
|
$item[$key] = $value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
$items[] = $item;
|
|
}
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Returns the data for the audit log table.
|
|
*
|
|
* @param array $data Configuration data.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_audit_log_data($data) {
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput -- PCP warning. Nonce checked in previous function and sanitization done at later.
|
|
$data = isset($data) ? wp_unslash($data) : array();
|
|
|
|
$data = isset($data['data']) ? $data['data'] : $data;
|
|
|
|
$this->init_wp_list();
|
|
$final_column = array();
|
|
|
|
// Needed for rendering the audit log table
|
|
include_once(AIO_WP_SECURITY_PATH.'/admin/wp-security-list-audit.php');
|
|
$audit_log_list = new AIOWPSecurity_List_Audit_Log($data);
|
|
|
|
$audit_log_list->prepare_items();
|
|
|
|
list($columns, $hidden) = $audit_log_list->get_column_info();
|
|
|
|
foreach ($columns as $column_key => $column_display_name) {
|
|
if ('cb' !== $column_key) {
|
|
if (!in_array($column_key, $hidden, true)) {
|
|
$final_column[$column_key] = array('label' => $column_display_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
$audit_log_items = isset($audit_log_list->items) ? $audit_log_list->items : array();
|
|
|
|
foreach ($audit_log_items as $key => $item) {
|
|
$ip = isset($item['ip']) ? $item['ip'] : '';
|
|
|
|
if ('' !== $ip) {
|
|
$audit_log_items[$key]['is_ip_locked'] = AIOWPSecurity_Utility::check_locked_ip($ip, 'audit-log');
|
|
$audit_log_items[$key]['is_ip_blacklisted'] = AIOWPSecurity_Utility::check_blacklist_ip($ip);
|
|
}
|
|
}
|
|
|
|
$items = $this->parse_audit_log_data($audit_log_list, $audit_log_items);
|
|
|
|
$bulk_actions = $audit_log_list->get_bulk_actions();
|
|
|
|
$paged = !empty($data['paged']) ? (int) $data['paged'] : 1;
|
|
|
|
AIOWPSecurity_Audit_Events::setup_event_types();
|
|
|
|
return array(
|
|
'audit_log_data' => array(
|
|
'bulk_actions' => $bulk_actions,
|
|
'event_types' => AIOWPSecurity_Audit_Events::$event_types,
|
|
'log_levels' => AIOWPSecurity_Audit_Events::$log_levels,
|
|
'columns' => $final_column,
|
|
'items' => $items,
|
|
'is_multisite' => is_multisite(),
|
|
'pagination' => array('page' => $paged, 'pages' => $audit_log_list->get_pagination_arg('total_pages'), 'results' => $audit_log_list->get_pagination_arg('total_items')),
|
|
),
|
|
);
|
|
}
|
|
}
|