added additional plugins

This commit is contained in:
Rodolfo Martinez 2025-12-12 19:05:48 -05:00
parent c85895d306
commit 00e60ec1b7
132 changed files with 27514 additions and 0 deletions

View file

@ -0,0 +1,370 @@
<?php
/**
* Ticket Tailor Security Logger
*
* Logs security events and sends alerts
* SECURITY ENHANCEMENT: Complete audit trail for compliance
*/
// Exit if accessed directly
if (!defined('ABSPATH')) {
exit;
}
class Ticket_Tailor_Security_Logger {
/**
* Table name
*/
private $table;
/**
* Constructor
*/
public function __construct() {
global $wpdb;
$this->table = $wpdb->prefix . 'ticket_tailor_security_log';
// Create table if needed
$this->maybe_create_table();
}
/**
* Create security log table
*/
private function maybe_create_table() {
global $wpdb;
// Check if table already exists
$table_exists = $wpdb->get_var($wpdb->prepare(
"SHOW TABLES LIKE %s",
$this->table
));
if ($table_exists) {
return;
}
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS {$this->table} (
id bigint(20) NOT NULL AUTO_INCREMENT,
event_type varchar(50) NOT NULL,
user_id bigint(20) DEFAULT 0,
ip_address varchar(45) NOT NULL,
details longtext,
timestamp datetime NOT NULL,
PRIMARY KEY (id),
KEY event_type (event_type),
KEY timestamp (timestamp),
KEY ip_address (ip_address)
) {$charset_collate};";
// Only require upgrade.php if we actually need to create the table
if (!function_exists('dbDelta')) {
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
}
dbDelta($sql);
}
/**
* Log security event
*/
public function log_event($event_type, $details = array()) {
global $wpdb;
$wpdb->insert(
$this->table,
array(
'event_type' => sanitize_key($event_type),
'user_id' => get_current_user_id(),
'ip_address' => $this->get_ip(),
'details' => wp_json_encode($details),
'timestamp' => current_time('mysql', 1),
),
array('%s', '%d', '%s', '%s', '%s')
);
}
/**
* Log failed webhook
*/
public function log_failed_webhook($ip, $reason) {
$this->log_event('webhook_failed', array(
'ip' => $ip,
'reason' => $reason,
));
// Check for multiple failures
$recent_failures = $this->count_recent_events('webhook_failed', 300);
if ($recent_failures >= 5) {
$this->send_security_alert('Multiple Failed Webhook Attempts', array(
'count' => $recent_failures,
'ip' => $ip,
'timeframe' => '5 minutes',
));
}
}
/**
* Log successful webhook
*/
public function log_successful_webhook($ip, $event_type) {
$this->log_event('webhook_success', array(
'ip' => $ip,
'webhook_type' => $event_type,
));
}
/**
* Log API key change
*/
public function log_api_key_change($old_key_hash, $new_key_hash) {
$this->log_event('api_key_changed', array(
'old_hash' => substr($old_key_hash, 0, 10),
'new_hash' => substr($new_key_hash, 0, 10),
'user' => wp_get_current_user()->user_login,
));
$this->send_security_alert('API Key Changed', array(
'changed_by' => wp_get_current_user()->user_login,
'ip' => $this->get_ip(),
));
}
/**
* Log settings change
*/
public function log_settings_change($setting_name, $old_value = null, $new_value = null) {
$this->log_event('settings_changed', array(
'setting' => $setting_name,
'changed_by' => wp_get_current_user()->user_login,
'has_old' => !is_null($old_value),
'has_new' => !is_null($new_value),
));
}
/**
* Log failed login attempt
*/
public function log_failed_login($username) {
$this->log_event('login_failed', array(
'username' => $username,
));
// Check for brute force
$recent_failures = $this->count_recent_events('login_failed', 900, $this->get_ip());
if ($recent_failures >= 5) {
$this->send_security_alert('Multiple Failed Login Attempts', array(
'count' => $recent_failures,
'ip' => $this->get_ip(),
'username' => $username,
));
}
}
/**
* Log rate limit exceeded
*/
public function log_rate_limit_exceeded($ip, $context = 'webhook') {
$this->log_event('rate_limit_exceeded', array(
'ip' => $ip,
'context' => $context,
));
}
/**
* Log unauthorized access attempt
*/
public function log_unauthorized_access($resource) {
$this->log_event('unauthorized_access', array(
'resource' => $resource,
'user_id' => get_current_user_id(),
));
}
/**
* Count recent events
*/
private function count_recent_events($event_type, $seconds, $ip = null) {
global $wpdb;
$time_threshold = gmdate('Y-m-d H:i:s', time() - $seconds);
if ($ip) {
return $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$this->table}
WHERE event_type = %s AND timestamp > %s AND ip_address = %s",
$event_type,
$time_threshold,
$ip
));
} else {
return $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$this->table}
WHERE event_type = %s AND timestamp > %s",
$event_type,
$time_threshold
));
}
}
/**
* Send security alert email
*/
public function send_security_alert($event_type, $details) {
// Check if alerts are enabled
if (!get_option('ticket_tailor_security_alerts', true)) {
return;
}
$admin_email = get_option('admin_email');
$site_name = get_bloginfo('name');
$site_url = get_bloginfo('url');
$subject = sprintf(
'[%s] Security Alert: %s',
$site_name,
$event_type
);
$message = sprintf(
"Security Event Detected on %s\n\n" .
"Event Type: %s\n" .
"Time: %s UTC\n" .
"IP Address: %s\n" .
"User: %s\n\n" .
"Details:\n%s\n\n" .
"---\n" .
"This is an automated security alert from Ticket Tailor plugin.\n" .
"To disable these alerts, go to: %s/wp-admin/admin.php?page=ticket-tailor-settings",
$site_name,
$event_type,
current_time('Y-m-d H:i:s'),
$this->get_ip(),
wp_get_current_user()->user_login ?: 'Guest',
$this->format_details($details),
$site_url
);
wp_mail($admin_email, $subject, $message);
}
/**
* Format details for email
*/
private function format_details($details) {
$formatted = '';
foreach ($details as $key => $value) {
$formatted .= ' ' . ucfirst(str_replace('_', ' ', $key)) . ': ' . $value . "\n";
}
return $formatted;
}
/**
* Get client IP
*/
private function get_ip() {
$ip_keys = array(
'HTTP_CF_CONNECTING_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_REAL_IP',
'REMOTE_ADDR',
);
foreach ($ip_keys as $key) {
if (!empty($_SERVER[$key])) {
$ip = $_SERVER[$key];
if (strpos($ip, ',') !== false) {
$ip = trim(explode(',', $ip)[0]);
}
if (filter_var($ip, FILTER_VALIDATE_IP)) {
return $ip;
}
}
}
return '0.0.0.0';
}
/**
* Get recent security events
*/
public function get_recent_events($limit = 50, $event_type = null) {
global $wpdb;
if ($event_type) {
return $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$this->table}
WHERE event_type = %s
ORDER BY timestamp DESC
LIMIT %d",
$event_type,
$limit
));
} else {
return $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$this->table}
ORDER BY timestamp DESC
LIMIT %d",
$limit
));
}
}
/**
* Clean old logs (older than 90 days)
*/
public function cleanup_old_logs() {
global $wpdb;
$threshold = gmdate('Y-m-d H:i:s', time() - (90 * DAY_IN_SECONDS));
$wpdb->query($wpdb->prepare(
"DELETE FROM {$this->table} WHERE timestamp < %s",
$threshold
));
}
/**
* Get security statistics
*/
public function get_statistics($days = 30) {
global $wpdb;
$threshold = gmdate('Y-m-d H:i:s', time() - ($days * DAY_IN_SECONDS));
$stats = array();
// Total events
$stats['total_events'] = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$this->table} WHERE timestamp > %s",
$threshold
));
// Events by type
$stats['by_type'] = $wpdb->get_results($wpdb->prepare(
"SELECT event_type, COUNT(*) as count
FROM {$this->table}
WHERE timestamp > %s
GROUP BY event_type
ORDER BY count DESC",
$threshold
), ARRAY_A);
// Top IPs
$stats['top_ips'] = $wpdb->get_results($wpdb->prepare(
"SELECT ip_address, COUNT(*) as count
FROM {$this->table}
WHERE timestamp > %s
GROUP BY ip_address
ORDER BY count DESC
LIMIT 10",
$threshold
), ARRAY_A);
return $stats;
}
}