// Code scaffolded by goctl. Safe to edit. // goctl 1.10.2 package systemlog import ( "context" "udeServer/internal/apierr" "udeServer/internal/audit" "udeServer/internal/log" "udeServer/internal/svc" "udeServer/internal/types" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stores/sqlx" ) type LogAuditLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } // 日志审计(校验Hmac防篡改) func NewLogAuditLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LogAuditLogic { return &LogAuditLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // LogAudit recomputes the HMAC of the selected entries and marks each one // as audited-passed or audited-anomaly. func (l *LogAuditLogic) LogAudit(req *types.SystemLogAuditReq) (*types.SystemLogAuditResp, error) { if len(req.Idens) == 0 { return nil, apierr.BadRequest("idens 不能为空") } list, err := l.svcCtx.SystemLogModel.FindByIdens(l.ctx, req.Idens) if err != nil { log.RecordError(l.ctx, err) return nil, apierr.New(500, "查询日志失败") } // HMAC 密钥与写入时一致(来自 t_config.log_hmac_secret) _, logConfig := audit.GetGlobalConfig(l.svcCtx.ConfigModel) var invalidCount, validCount int64 auditList := make([]types.AuditResult, 0, len(list)) for i := range list { v := &list[i] auditResult := types.AuditResult{LogIden: v.Iden} macBuffer := make([]byte, 0, 32) mac, hErr := audit.CalculateHMAC(v, logConfig.HmacSecret, macBuffer) switch { case hErr != nil: log.RecordError(l.ctx, hErr) auditResult.Valid = false v.AuditStatus = audit.AuditedAnomaly auditResult.Reason = "HMAC计算失败" case v.HMac == mac: auditResult.Valid = true v.AuditStatus = audit.AuditedPassed validCount++ auditList = append(auditList, auditResult) continue default: auditResult.Valid = false v.AuditStatus = audit.AuditedAnomaly auditResult.Reason = "HMAC不匹配,日志被篡改!" invalidCount++ auditList = append(auditList, auditResult) continue } invalidCount++ auditList = append(auditList, auditResult) } // 事务内逐条更新审计状态 err = l.svcCtx.DB.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error { for i := range list { if _, err := session.ExecCtx(ctx, "update t_system_log set audit_status = ? where id = ?", list[i].AuditStatus, list[i].Id); err != nil { return err } } return nil }) if err != nil { log.RecordError(l.ctx, err) return nil, apierr.New(500, "更新审计状态失败") } resp := &types.SystemLogAuditResp{ AuditResults: auditList, TotalCount: int64(len(auditList)), ValidCount: validCount, InValidCount: invalidCount, } log.RecordDebug(l.ctx, "日志审计完成!") return resp, nil }