Smail/backend/services/runtimelog/scope.go
smail fd475cd88d
Some checks are pending
Security Checks / security (push) Waiting to run
保存角色权限分层改造续审现场
2026-09-09 20:27:50 +08:00

61 lines
2.3 KiB
Go

package runtimelog
import (
"encoding/json"
"regexp"
"strings"
)
var scopedHeader = regexp.MustCompile(`^(\[[^\]\r\n]+\]\s+\[(?:trace|debug|info|warn|warning|error|fatal|panic)\]\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\])`)
// 低权限视图不返回任意消息、源码路径、请求标识或异常原文。
// 公共事件仅开放固定生命周期文案,无法确认归属的历史日志默认隐藏。
func presentScopedLine(line string, actors map[string]bool) (string, bool) {
if actors == nil {
return presentLine(line)
}
header := scopedHeader.FindStringSubmatch(line)
boundary := strings.LastIndex(line, " @event ")
if header == nil || boundary < len(header[0]) {
return "", false
}
var event struct {
Schema int `json:"logSchema"`
ActorID string `json:"actorId"`
ActorRole string `json:"actorRole"`
Action string `json:"action"`
Result string `json:"result"`
Object string `json:"object"`
}
if json.Unmarshal([]byte(line[boundary+8:]), &event) != nil || event.Schema != 1 {
return "", false
}
action := "账号相关运行事件"
if own, allowed := actors[event.ActorID]; allowed {
if !own && event.ActorRole != "user" {
return "", false
}
// 已知动作保留业务含义,未知动作不能携带任意错误原文或账号信息。
switch event.Action {
case "执行收信规则", "读取收信规则", "通知 IMAP 客户端新邮件", "接收邮件", "投递邮件", "客户端提交邮件", "更新个人资料", "登录验证", "退出登录", "保存配置", "回滚配置", "迁移配置":
action = event.Action
}
} else {
if event.ActorID != "" || event.Object != "Smail" {
return "", false
}
switch event.Action {
case "启动主服务", "停止主服务", "运行主服务":
action = event.Action
default:
return "", false
}
}
outcome := map[string]string{"success": "处理已完成", "failure": "处理失败", "started": "已开始处理", "recorded": "已记录运行状态", "accepted": "已接收", "partial": "部分完成", "unknown": "结果待确认"}[event.Result]
if outcome == "" {
event.Result, outcome = "recorded", "已记录运行状态"
}
payload, _ := json.Marshal(map[string]any{"logSchema": 1, "action": action, "result": event.Result, "outcome": outcome})
return header[1] + action + " @event " + string(payload), true
}