Go 1.27.1 (Gin+GORM) + Vue 3 文件快传服务: - 安全审计全部修复(docs/security-audit-2026-09-05.md): bcrypt 密码哈希与自动升级、presign 直传服务端大小/内容校验、 全局请求体上限、依赖升级(govulncheck 0 命中)、janitor 后台清理、 管理端审计动作落库、/admin CORS 收紧、通知内容白名单净化、 会话默认 7 天、限流缓存故障降级、robots.txt 端点等 - 前端:取件链接复制修复(不再重复拼接提取码)、markdown 净化器加固 - Redis 支持库号(FCB_REDIS_DB / redis://…/db URL) - 文档:docs/api/* 与 openapi.yaml 同步最新行为(robots.txt、 提码 5 位起、chunk 32MiB 上限、admin 审计动作等) 验证:gofmt/go vet/go test 全绿;二进制端到端冒烟通过
85 lines
2.5 KiB
Go
85 lines
2.5 KiB
Go
package audit
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// DeviceInfo 从 User-Agent 解析出的设备信息。
|
|
type DeviceInfo struct {
|
|
OS string // Windows/macOS/Android/iOS/Linux/Unknown
|
|
Browser string // Chrome/Firefox/Safari/Edge/Other
|
|
Type string // desktop/mobile/tablet/bot/other
|
|
}
|
|
|
|
// 动作常量。
|
|
const (
|
|
ActionUpload = "upload"
|
|
ActionDownload = "download"
|
|
// ActionAdmin 管理端敏感操作(登录/登出/配置/密码/引擎切换/文件删除等),
|
|
// L5:纳入审计以便追溯登录失败与配置变更。
|
|
ActionAdmin = "admin"
|
|
)
|
|
|
|
// 角色常量。
|
|
const (
|
|
ActorAdmin = "admin"
|
|
ActorGuest = "guest"
|
|
)
|
|
|
|
// botKeywords 常见爬虫/机器人标识。
|
|
var botKeywords = []string{"bot", "spider", "crawl", "slurp", "curl/", "wget", "python-requests", "go-http-client"}
|
|
|
|
// ParseUserAgent 解析 User-Agent 为设备信息(轻量规则,避免引入重依赖)。
|
|
func ParseUserAgent(ua string) DeviceInfo {
|
|
ua = strings.TrimSpace(ua)
|
|
lower := strings.ToLower(ua)
|
|
if ua == "" {
|
|
return DeviceInfo{OS: "Unknown", Browser: "Other", Type: "other"}
|
|
}
|
|
for _, kw := range botKeywords {
|
|
if strings.Contains(lower, kw) {
|
|
return DeviceInfo{OS: "Unknown", Browser: "Other", Type: "bot"}
|
|
}
|
|
}
|
|
|
|
info := DeviceInfo{OS: "Unknown", Browser: "Other", Type: "desktop"}
|
|
|
|
// 操作系统
|
|
switch {
|
|
case strings.Contains(lower, "windows"):
|
|
info.OS = "Windows"
|
|
case strings.Contains(lower, "iphone"), strings.Contains(lower, "ipod"):
|
|
info.OS = "iOS"
|
|
info.Type = "mobile"
|
|
case strings.Contains(lower, "ipad"):
|
|
info.OS = "iOS"
|
|
info.Type = "tablet"
|
|
case strings.Contains(lower, "mac os x"), strings.Contains(lower, "macintosh"):
|
|
info.OS = "macOS"
|
|
case strings.Contains(lower, "android"):
|
|
info.OS = "Android"
|
|
info.Type = "mobile"
|
|
if strings.Contains(lower, "tablet") || !strings.Contains(lower, "mobile") {
|
|
info.Type = "tablet"
|
|
}
|
|
case strings.Contains(lower, "linux"), strings.Contains(lower, "ubuntu"), strings.Contains(lower, "fedora"):
|
|
info.OS = "Linux"
|
|
}
|
|
|
|
// 浏览器(顺序重要:Edge/OPR 必须在 Chrome 之前判断)
|
|
switch {
|
|
case strings.Contains(lower, "edg/"), strings.Contains(lower, "edge/"):
|
|
info.Browser = "Edge"
|
|
case strings.Contains(lower, "opr/"), strings.Contains(lower, "opera"):
|
|
info.Browser = "Opera"
|
|
case strings.Contains(lower, "chrome/"), strings.Contains(lower, "crios/"):
|
|
info.Browser = "Chrome"
|
|
case strings.Contains(lower, "firefox/"), strings.Contains(lower, "fxios/"):
|
|
info.Browser = "Firefox"
|
|
case strings.Contains(lower, "safari/"):
|
|
info.Browser = "Safari"
|
|
}
|
|
|
|
return info
|
|
}
|