This commit is contained in:
@@ -187,6 +187,8 @@ func NewRegistry() *Registry {
|
||||
constants.AuditActionOutboxExpiredLeaseReleased,
|
||||
"人工释放 Outbox 过期租约",
|
||||
)
|
||||
integrationAttemptStarted := integrationAction(constants.AuditActionIntegrationAttemptStarted, "记录外部交互开始")
|
||||
integrationInboundReceived := integrationAction(constants.AuditActionIntegrationInboundReceived, "记录外部入站回调")
|
||||
iotCardImportTaskCreated := taskAction(constants.AuditActionIotCardImportTaskCreated, "创建 IoT 卡导入任务", constants.AuditResourceIotCardImportTask, constants.AuditActorAccount, constants.AuditSourceAdminAPI)
|
||||
iotCardImportTaskCompleted := taskAction(constants.AuditActionIotCardImportTaskCompleted, "完成 IoT 卡导入任务", constants.AuditResourceIotCardImportTask, constants.AuditActorSystemTask, constants.AuditSourceWorker)
|
||||
deviceImportTaskCreated := taskAction(constants.AuditActionDeviceImportTaskCreated, "创建设备导入任务", constants.AuditResourceDeviceImportTask, constants.AuditActorAccount, constants.AuditSourceAdminAPI)
|
||||
@@ -563,6 +565,8 @@ func NewRegistry() *Registry {
|
||||
constants.AuditActionPaymentCreated: paymentCreated,
|
||||
constants.AuditActionPaymentConfirmed: paymentConfirmed,
|
||||
constants.AuditActionPaymentFailed: paymentFailed,
|
||||
constants.AuditActionIntegrationAttemptStarted: integrationAttemptStarted,
|
||||
constants.AuditActionIntegrationInboundReceived: integrationInboundReceived,
|
||||
constants.AuditActionAgentRechargeCreated: agentRechargeCreated,
|
||||
constants.AuditActionAgentRechargeCredited: agentRechargeCredited,
|
||||
constants.AuditActionAgentRechargeClosed: agentRechargeClosed,
|
||||
@@ -1196,6 +1200,23 @@ func outboxRecoveryAction(code, name string) ActionDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
func integrationAction(code, name string) ActionDefinition {
|
||||
return ActionDefinition{
|
||||
Code: code, Name: name, Category: constants.AuditCategoryReliability, Risk: constants.AuditRiskNormal,
|
||||
PrimaryResource: constants.AuditResourceIntegrationLog, AllowedActor: constants.AuditActorSystemTask,
|
||||
Source: constants.AuditSourceWorker, RequireTransaction: false,
|
||||
DefaultVisibility: constants.AuditSubjectInternalOnly,
|
||||
AllowedVisibility: []string{constants.AuditSubjectInternalOnly},
|
||||
AllowedOrigins: []ActionOrigin{
|
||||
{Actor: constants.AuditActorAccount, Source: constants.AuditSourceAdminAPI},
|
||||
{Actor: constants.AuditActorPersonalCustomer, Source: constants.AuditSourcePersonalAPI},
|
||||
{Actor: constants.AuditActorOpenAPI, Source: constants.AuditSourceOpenAPI},
|
||||
{Actor: constants.AuditActorExternalSystem, Source: constants.AuditSourceCallback},
|
||||
{Actor: constants.AuditActorScheduledJob, Source: constants.AuditSourceScheduler},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func connectionConfigAction(code, name, resourceType, risk string) ActionDefinition {
|
||||
return ActionDefinition{
|
||||
Code: code, Name: name, Category: constants.AuditCategoryConfiguration, Risk: risk,
|
||||
|
||||
@@ -872,27 +872,33 @@ func (w *Writer) WriteRecovery(ctx context.Context, tx *gorm.DB, recovery outbox
|
||||
|
||||
// Append 在调用方提供的 GORM 事务中顺序追加事件及资源。
|
||||
func (w *Writer) Append(ctx context.Context, tx *gorm.DB, input AppendInput) error {
|
||||
_, err := w.AppendAndGet(ctx, tx, input)
|
||||
return err
|
||||
}
|
||||
|
||||
// AppendAndGet 追加事件并返回已持久化的审计事件,幂等重放返回已有事件。
|
||||
func (w *Writer) AppendAndGet(ctx context.Context, tx *gorm.DB, input AppendInput) (*model.AuditEvent, error) {
|
||||
if w == nil || w.registry == nil || tx == nil {
|
||||
return pkgerrors.New(pkgerrors.CodeInvalidStatus, "统一审计 Writer 未正确配置")
|
||||
return nil, pkgerrors.New(pkgerrors.CodeInvalidStatus, "统一审计 Writer 未正确配置")
|
||||
}
|
||||
input = fillFromContext(ctx, input)
|
||||
action, ok := w.registry.Action(input.ActionCode)
|
||||
if !ok {
|
||||
return pkgerrors.New(pkgerrors.CodeInvalidParam, "审计动作未注册")
|
||||
return nil, pkgerrors.New(pkgerrors.CodeInvalidParam, "审计动作未注册")
|
||||
}
|
||||
if !actionAllowsOrigin(action, input.Actor.Kind, input.Source) || input.Actor.ID == "" {
|
||||
return pkgerrors.New(pkgerrors.CodeInvalidParam, "审计操作者或入口不符合动作注册规则")
|
||||
return nil, pkgerrors.New(pkgerrors.CodeInvalidParam, "审计操作者或入口不符合动作注册规则")
|
||||
}
|
||||
if !validResult(input.Result) || len(input.Resources) == 0 {
|
||||
return pkgerrors.New(pkgerrors.CodeInvalidParam, "审计结果非法或缺少资源")
|
||||
return nil, pkgerrors.New(pkgerrors.CodeInvalidParam, "审计结果非法或缺少资源")
|
||||
}
|
||||
resources, err := w.buildResources(input.Resources, action)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
metadata, err := safeObject(input.Metadata)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
occurredAt := input.OccurredAt
|
||||
if occurredAt.IsZero() {
|
||||
@@ -913,7 +919,7 @@ func (w *Writer) Append(ctx context.Context, tx *gorm.DB, input AppendInput) err
|
||||
}
|
||||
event.ContentHash, err = contentHash(event, resources)
|
||||
if err != nil {
|
||||
return pkgerrors.Wrap(pkgerrors.CodeInvalidParam, err, "计算审计内容哈希失败")
|
||||
return nil, pkgerrors.Wrap(pkgerrors.CodeInvalidParam, err, "计算审计内容哈希失败")
|
||||
}
|
||||
event.EventID = input.EventID
|
||||
if event.EventID == "" {
|
||||
@@ -923,19 +929,23 @@ func (w *Writer) Append(ctx context.Context, tx *gorm.DB, input AppendInput) err
|
||||
Columns: []clause.Column{{Name: "event_id"}}, DoNothing: true,
|
||||
}).Create(&event)
|
||||
if create.Error != nil {
|
||||
return pkgerrors.Wrap(pkgerrors.CodeDatabaseError, create.Error, "写入审计事件失败")
|
||||
return nil, pkgerrors.Wrap(pkgerrors.CodeDatabaseError, create.Error, "写入审计事件失败")
|
||||
}
|
||||
if create.RowsAffected == 0 {
|
||||
return nil
|
||||
var existing model.AuditEvent
|
||||
if err := tx.WithContext(ctx).Where("event_id = ?", event.EventID).First(&existing).Error; err != nil {
|
||||
return nil, pkgerrors.Wrap(pkgerrors.CodeDatabaseError, err, "读取已存在审计事件失败")
|
||||
}
|
||||
return &existing, nil
|
||||
}
|
||||
for index := range resources {
|
||||
resources[index].AuditEventID = event.ID
|
||||
resources[index].CreatedAt = event.CreatedAt
|
||||
}
|
||||
if err := tx.WithContext(ctx).Create(&resources).Error; err != nil {
|
||||
return pkgerrors.Wrap(pkgerrors.CodeDatabaseError, err, "写入审计事件资源失败")
|
||||
return nil, pkgerrors.Wrap(pkgerrors.CodeDatabaseError, err, "写入审计事件资源失败")
|
||||
}
|
||||
return nil
|
||||
return &event, nil
|
||||
}
|
||||
|
||||
func actionAllowsOrigin(action ActionDefinition, actor, source string) bool {
|
||||
|
||||
Reference in New Issue
Block a user