125 lines
3.0 KiB
Go
Raw Normal View History

2025-03-23 16:28:38 +08:00
package aduit
import (
"context"
"github.com/emicklei/go-restful/v3"
"github.com/infraboard/mcube/v2/ioc"
"github.com/infraboard/mcube/v2/ioc/config/application"
"github.com/infraboard/mcube/v2/ioc/config/gorestful"
ioc_kafka "github.com/infraboard/mcube/v2/ioc/config/kafka"
"github.com/infraboard/mcube/v2/ioc/config/log"
"github.com/infraboard/modules/iam/apps/endpoint"
"github.com/infraboard/modules/iam/apps/token"
"github.com/rs/zerolog"
"github.com/segmentio/kafka-go"
"gitlab.com/go-course-project/go17/devcloud-mini/maudit/apps/event"
)
func init() {
ioc.Config().Registry(&auditor{
Topic: "maudit_new",
})
}
func Audit(v bool) (string, bool) {
return event.META_AUDIT_KEY, v
}
type auditor struct {
ioc.ObjectImpl
log *zerolog.Logger
// 当前这个消费者 配置的topic
Topic string `toml:"topic" json:"topic" yaml:"topic" env:"TOPIC"`
//
wirter *kafka.Writer
}
func (a *auditor) Name() string {
return "auditor"
}
func (a *auditor) Init() error {
a.log = log.Sub("mauditor")
a.log.Debug().Msgf("maduit topic name: %s", a.Topic)
a.wirter = ioc_kafka.Producer(a.Topic)
// 添加到中间件, 加到Root Router里面
ws := gorestful.RootRouter()
ws.Filter(a.Audit())
return nil
}
// 补充中间件函数逻辑
func (a *auditor) Audit() restful.FilterFunction {
return func(r1 *restful.Request, r2 *restful.Response, fc *restful.FilterChain) {
sr := r1.SelectedRoute()
md := NewMetaData(sr.Metadata())
// 开关打开,则开启审计
if md.GetBool(event.META_AUDIT_KEY) {
// 获取当前是否需要审计
e := event.NewEvent()
// 用户信息
tk := token.GetTokenFromCtx(r1.Request.Context())
if tk != nil {
e.Who = tk.UserName
e.Extras["namespace"] = tk.NamespaceName
}
// ioc 里面获取当前应用的名称
e.Service = application.Get().AppName
e.ResourceType = md.GetString(endpoint.META_RESOURCE_KEY)
e.Action = md.GetString(endpoint.META_ACTION_KEY)
// {id} /:id
e.ResourceId = r1.PathParameter("id")
e.UserAgent = r1.Request.UserAgent()
e.Extras["method"] = sr.Method()
e.Extras["path"] = sr.Path()
e.Extras["operation"] = sr.Operation()
// 补充处理后的数据
e.StatusCode = r2.StatusCode()
// 发送给topic, 使用这个中间件的使用者需要配置kafka
err := a.wirter.WriteMessages(context.Background(), e.ToKafkaMessage())
if err != nil {
a.log.Error().Msgf("send message error, %s", err)
} else {
a.log.Debug().Msgf("send audit event ok, who: %s, resource: %s, action: %s", e.Who, e.ResourceType, e.Action)
}
}
// 路有给后续逻辑
fc.ProcessFilter(r1, r2)
}
}
func NewMetaData(data map[string]any) *MetaData {
return &MetaData{
data: data,
}
}
type MetaData struct {
data map[string]any
}
func (m *MetaData) GetString(key string) string {
if v, ok := m.data[key]; ok {
return v.(string)
}
return ""
}
func (m *MetaData) GetBool(key string) bool {
if v, ok := m.data[key]; ok {
return v.(bool)
}
return false
}