feat(mcp): TokenService.Revoke + RevokeBySession (with audit)

This commit is contained in:
2026-05-08 08:02:11 +08:00
parent 796e1e0d4c
commit 7d9cd4bf6b
+39 -2
View File
@@ -216,9 +216,46 @@ func (s *tokenService) Authenticate(ctx context.Context, plaintext string) (*MCP
return tok, nil return tok, nil
} }
// Revoke 由 admin 后台或持有者主动调用。
// 写一条 audit `mcp.token.revoke`。
func (s *tokenService) Revoke(ctx context.Context, id, byUserID uuid.UUID) error { func (s *tokenService) Revoke(ctx context.Context, id, byUserID uuid.UUID) error {
panic("not implemented: Revoke") revokedID, err := s.repo.Revoke(ctx, id)
if err != nil {
return err
}
_ = s.audit.Record(ctx, audit.Entry{
UserID: &byUserID,
Action: "mcp.token.revoke",
TargetType: "mcp_token",
TargetID: revokedID.String(),
Metadata: map[string]any{
"token_id": revokedID.String(),
"by_user_id": byUserID.String(),
},
})
return nil
} }
// RevokeBySession 由 ACP SessionService 在 session 终止时调用。
// 撤销该 session 的所有 system token,逐条写 audit `mcp.token.revoke_by_session`。
//
// 错误处理:底层 repo 失败 → 返错,让调用方决定回滚或继续;
// 部分 row audit 失败 → 仅记日志,不影响其他 row(audit 失败不阻塞业务)。
func (s *tokenService) RevokeBySession(ctx context.Context, sessionID uuid.UUID) error { func (s *tokenService) RevokeBySession(ctx context.Context, sessionID uuid.UUID) error {
panic("not implemented: RevokeBySession") revoked, err := s.repo.RevokeBySession(ctx, sessionID)
if err != nil {
return err
}
for _, tokenID := range revoked {
_ = s.audit.Record(ctx, audit.Entry{
Action: "mcp.token.revoke_by_session",
TargetType: "mcp_token",
TargetID: tokenID.String(),
Metadata: map[string]any{
"token_id": tokenID.String(),
"acp_session_id": sessionID.String(),
},
})
}
return nil
} }