新增功能: - ACL: 访问控制列表(91行) - Auth: 用户认证(41行) - Monitor: 监控和日志(113行) - CLI命令:user/stats/logs 功能验证: - ✅ stats命令显示连接统计 - ✅ user add生成权限配置 - ✅ logs命令显示访问日志 - ✅ 编译成功(0 errors) 总代码量:512行(Phase 1-3完整) Phase 1: 212行(基础配置) Phase 2: 132行(权限控制) Phase 3: 113行(监控日志) 下一步:用户手动启用SMB服务测试
112 lines
2.9 KiB
Rust
112 lines
2.9 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use std::time::{Duration, SystemTime};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ConnectionStats {
|
|
pub total_connections: u64,
|
|
pub active_connections: u32,
|
|
pub read_operations: u64,
|
|
pub write_operations: u64,
|
|
pub errors: u64,
|
|
pub bytes_transferred: u64,
|
|
pub uptime_seconds: u64,
|
|
}
|
|
|
|
impl Default for ConnectionStats {
|
|
fn default() -> Self {
|
|
ConnectionStats {
|
|
total_connections: 0,
|
|
active_connections: 0,
|
|
read_operations: 0,
|
|
write_operations: 0,
|
|
errors: 0,
|
|
bytes_transferred: 0,
|
|
uptime_seconds: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct AccessLogEntry {
|
|
pub timestamp: String,
|
|
pub username: String,
|
|
pub action: String,
|
|
pub path: String,
|
|
pub success: bool,
|
|
pub bytes: u64,
|
|
pub duration_ms: u64,
|
|
}
|
|
|
|
impl AccessLogEntry {
|
|
pub fn new(username: String, action: String, path: String, success: bool, bytes: u64, duration: Duration) -> Self {
|
|
let timestamp = SystemTime::now()
|
|
.duration_since(SystemTime::UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_secs();
|
|
|
|
AccessLogEntry {
|
|
timestamp: timestamp.to_string(),
|
|
username,
|
|
action,
|
|
path,
|
|
success,
|
|
bytes,
|
|
duration_ms: duration.as_millis() as u64,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct SMBMonitor {
|
|
stats: ConnectionStats,
|
|
logs: Vec<AccessLogEntry>,
|
|
start_time: SystemTime,
|
|
}
|
|
|
|
impl SMBMonitor {
|
|
pub fn new() -> Self {
|
|
SMBMonitor {
|
|
stats: ConnectionStats::default(),
|
|
logs: Vec::new(),
|
|
start_time: SystemTime::now(),
|
|
}
|
|
}
|
|
|
|
pub fn log_access(&mut self, entry: AccessLogEntry) {
|
|
self.logs.push(entry.clone());
|
|
|
|
if entry.success {
|
|
if entry.action == "read" {
|
|
self.stats.read_operations += 1;
|
|
} else if entry.action == "write" {
|
|
self.stats.write_operations += 1;
|
|
}
|
|
self.stats.bytes_transferred += entry.bytes;
|
|
} else {
|
|
self.stats.errors += 1;
|
|
}
|
|
}
|
|
|
|
pub fn connection_opened(&mut self) {
|
|
self.stats.total_connections += 1;
|
|
self.stats.active_connections += 1;
|
|
}
|
|
|
|
pub fn connection_closed(&mut self) {
|
|
self.stats.active_connections -= 1;
|
|
}
|
|
|
|
pub fn get_stats(&self) -> ConnectionStats {
|
|
let uptime = SystemTime::now()
|
|
.duration_since(self.start_time)
|
|
.unwrap()
|
|
.as_secs();
|
|
|
|
let mut stats = self.stats.clone();
|
|
stats.uptime_seconds = uptime;
|
|
stats
|
|
}
|
|
|
|
pub fn get_logs(&self, limit: usize) -> Vec<AccessLogEntry> {
|
|
self.logs.iter().rev().take(limit).cloned().collect()
|
|
}
|
|
} |