use std::collections::VecDeque;
use std::sync::LazyLock;
use std::sync::Mutex;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Instant;
#[cfg(feature = "permission")]
use crate::access::PermissionAction;
const BYPASS_RING_CAPACITY: usize = 1000;
#[cfg(feature = "permission")]
pub(crate) const BYPASS_KIND_ADMIN: &str = "admin_bypass";
pub(crate) const BYPASS_KIND_DEFAULT_ADMIN_ROLE: &str = "default_admin_role";
#[derive(Debug, Clone)]
pub struct BypassEvent {
pub kind: &'static str,
pub role: String,
pub table: String,
pub operation: String,
pub at: Instant,
}
static BYPASS_RING: LazyLock<Mutex<VecDeque<BypassEvent>>> =
LazyLock::new(|| Mutex::new(VecDeque::new()));
static BYPASS_TOTAL: AtomicU64 = AtomicU64::new(0);
#[cfg(feature = "permission")]
pub(super) fn audit_admin_bypass(role: &str, table: &str, operation: &PermissionAction) {
record_admin_bypass(BYPASS_KIND_ADMIN, role, table, &format!("{operation:?}"));
}
pub fn warn_if_default_admin_role_used(admin_role: &str) -> bool {
admin_role == "admin"
}
pub(super) fn warn_and_record_default_admin_role(admin_role: &str) {
if warn_if_default_admin_role_used(admin_role) {
record_admin_bypass(BYPASS_KIND_DEFAULT_ADMIN_ROLE, admin_role, "-", "PoolInit");
}
}
pub(crate) fn record_admin_bypass(kind: &'static str, role: &str, table: &str, operation: &str) {
let event = BypassEvent {
kind,
role: role.to_string(),
table: table.to_string(),
operation: operation.to_string(),
at: Instant::now(),
};
let mut ring = BYPASS_RING.lock().unwrap_or_else(|e| e.into_inner());
push_bypass_event(&mut ring, &BYPASS_TOTAL, event);
}
fn push_bypass_event(ring: &mut VecDeque<BypassEvent>, total: &AtomicU64, event: BypassEvent) {
if ring.len() >= BYPASS_RING_CAPACITY {
ring.pop_front();
}
ring.push_back(event);
total.fetch_add(1, Ordering::Relaxed);
}
pub fn admin_bypass_count() -> u64 {
BYPASS_TOTAL.load(Ordering::Relaxed)
}
pub fn take_admin_bypass_events() -> Vec<BypassEvent> {
let mut ring = BYPASS_RING.lock().unwrap_or_else(|e| e.into_inner());
ring.drain(..).collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vuln_0001_warn_default_admin_role() {
assert!(
warn_if_default_admin_role_used("admin"),
"default admin_role 'admin' should trigger warning"
);
}
#[test]
fn test_vuln_0001_custom_admin_role_no_warning() {
assert!(
!warn_if_default_admin_role_used("super-admin-2026"),
"custom admin_role should not trigger warning"
);
}
#[test]
fn test_bypass_ring_drops_oldest_when_full() {
let total = AtomicU64::new(0);
let mut ring: VecDeque<BypassEvent> = VecDeque::new();
for i in 0..(BYPASS_RING_CAPACITY + 10) {
push_bypass_event(
&mut ring,
&total,
BypassEvent {
kind: BYPASS_KIND_DEFAULT_ADMIN_ROLE,
role: "admin".to_string(),
table: format!("t{i}"),
operation: "Select".to_string(),
at: Instant::now(),
},
);
}
assert_eq!(ring.len(), BYPASS_RING_CAPACITY);
assert_eq!(
total.load(Ordering::Relaxed),
(BYPASS_RING_CAPACITY + 10) as u64
);
assert_eq!(ring.front().unwrap().table, format!("t{}", 10));
assert_eq!(
ring.back().unwrap().table,
format!("t{}", BYPASS_RING_CAPACITY + 9)
);
}
#[test]
fn test_record_admin_bypass_count_take_and_clear() {
let marker = "record-take-marker";
let before = admin_bypass_count();
record_admin_bypass(BYPASS_KIND_DEFAULT_ADMIN_ROLE, marker, "tbl-a", "Select");
record_admin_bypass(BYPASS_KIND_DEFAULT_ADMIN_ROLE, marker, "tbl-b", "Insert");
record_admin_bypass(BYPASS_KIND_DEFAULT_ADMIN_ROLE, marker, "tbl-c", "Delete");
assert!(admin_bypass_count() >= before + 3);
let events = take_admin_bypass_events();
let mine: Vec<_> = events.iter().filter(|e| e.role == marker).collect();
assert_eq!(mine.len(), 3);
assert_eq!(mine[0].table, "tbl-a");
assert_eq!(mine[0].operation, "Select");
assert_eq!(mine[1].operation, "Insert");
assert_eq!(mine[2].table, "tbl-c");
assert!(mine[0].at <= mine[2].at, "事件应按记录顺序保存");
assert!(take_admin_bypass_events().iter().all(|e| e.role != marker));
}
#[test]
fn test_warn_and_record_default_admin_role() {
let before = admin_bypass_count();
warn_and_record_default_admin_role("admin");
assert!(
admin_bypass_count() > before,
"默认 admin 角色应触发审计记录"
);
let events = take_admin_bypass_events();
assert!(
events
.iter()
.any(|e| e.kind == BYPASS_KIND_DEFAULT_ADMIN_ROLE
&& e.table == "-"
&& e.operation == "PoolInit"),
"应存在 default_admin_role 类别的池初始化事件"
);
}
#[cfg(feature = "permission")]
#[test]
fn test_vuln_0001_audit_admin_bypass_records_event() {
let marker = "bypass-audit-marker";
let before = admin_bypass_count();
audit_admin_bypass(marker, "users", &PermissionAction::Select);
audit_admin_bypass(marker, "users", &PermissionAction::Insert);
audit_admin_bypass(marker, "orders", &PermissionAction::Delete);
assert!(admin_bypass_count() >= before + 3);
let events = take_admin_bypass_events();
let mine: Vec<_> = events.iter().filter(|e| e.role == marker).collect();
assert_eq!(mine.len(), 3);
assert_eq!(mine[0].kind, BYPASS_KIND_ADMIN);
assert_eq!(mine[0].table, "users");
assert_eq!(mine[0].operation, "Select");
assert_eq!(mine[2].table, "orders");
assert_eq!(mine[2].operation, "Delete");
assert!(take_admin_bypass_events().iter().all(|e| e.role != marker));
}
#[test]
fn test_observation_api_reachable_via_full_public_path() {
use crate::database::pool::audit as public_audit;
let before = public_audit::admin_bypass_count();
record_admin_bypass(
BYPASS_KIND_DEFAULT_ADMIN_ROLE,
"public-path-marker",
"-",
"PoolInit",
);
assert!(public_audit::admin_bypass_count() > before);
let events = public_audit::take_admin_bypass_events();
let marker_events: Vec<_> = events
.iter()
.filter(|e| e.role == "public-path-marker")
.collect();
assert_eq!(marker_events.len(), 1);
assert_eq!(marker_events[0].kind, "default_admin_role");
let _ = format!("{:?}", marker_events[0]);
let _cloned = marker_events[0].clone();
assert!(
public_audit::take_admin_bypass_events()
.iter()
.all(|e| e.role != "public-path-marker")
);
}
}