补齐证书任务创建人归属
传递已认证操作者上下文,关联证书任务审计,并同步四份整改清单进度。
This commit is contained in:
parent
4cf9fb6076
commit
5fecd05d46
@ -65,7 +65,8 @@ func (w *certificateTaskWorkflow) run(ctx context.Context, id, taskType, stage s
|
||||
task := repository.Task{
|
||||
ID: domain.NewID(), DomainID: id, TaskType: taskType,
|
||||
Status: "running", Stage: stage, Message: "正在执行证书工作流",
|
||||
StartedAt: &started, CreatedAt: started,
|
||||
OperatorID: repository.TaskOperatorFromContext(ctx),
|
||||
StartedAt: &started, CreatedAt: started,
|
||||
}
|
||||
if err := w.tasks.CreateTask(ctx, task); err != nil {
|
||||
return result, err
|
||||
@ -84,7 +85,8 @@ func (w *certificateTaskWorkflow) run(ctx context.Context, id, taskType, stage s
|
||||
auditErr := w.audit.CreateAuditLog(finishCtx, repository.AuditLog{
|
||||
TaskID: task.ID,
|
||||
Action: taskType, ResourceType: "domain", ResourceID: id,
|
||||
Status: status, Message: message,
|
||||
OperatorID: task.OperatorID,
|
||||
Status: status, Message: message,
|
||||
})
|
||||
if auditErr != nil {
|
||||
status, message = certificateTaskOutcome(result, auditErr)
|
||||
@ -99,7 +101,8 @@ func (w *certificateTaskWorkflow) run(ctx context.Context, id, taskType, stage s
|
||||
if err := w.audit.CreateAuditLog(taskCtx, repository.AuditLog{
|
||||
TaskID: task.ID,
|
||||
Action: taskType, ResourceType: "domain", ResourceID: id,
|
||||
Status: "running", Message: "开始执行证书工作流",
|
||||
OperatorID: task.OperatorID,
|
||||
Status: "running", Message: "开始执行证书工作流",
|
||||
}); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
@ -92,6 +92,40 @@ func TestCertificateTasksRecordSuccessFailureAndCancellation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCertificateTasksRecordOperatorFromWorkflowContext(t *testing.T) {
|
||||
w, a := newCertificateTaskFixture(t)
|
||||
ctx := repository.WithTaskOperator(t.Context(), "operator-1")
|
||||
_, err := w.run(ctx, "task-domain", "certificate_validate", "certificate_validate", 1, 0, func(context.Context, string) (CertificateWorkflowResult, error) {
|
||||
return CertificateWorkflowResult{}, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("带操作者的证书任务执行失败:%v", err)
|
||||
}
|
||||
items, err := a.Tasks.ListTasks(t.Context(), "task-domain", 10)
|
||||
if err != nil || len(items) != 1 || items[0].OperatorID != "operator-1" {
|
||||
t.Fatalf("任务创建人记录错误:%+v %v", items, err)
|
||||
}
|
||||
var operators []string
|
||||
rows, err := a.Database.DB.QueryContext(t.Context(), "SELECT operator_id FROM audit_logs WHERE task_id = ? ORDER BY created_at, id", items[0].ID)
|
||||
if err != nil {
|
||||
t.Fatalf("读取任务审计失败:%v", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var operator string
|
||||
if err := rows.Scan(&operator); err != nil {
|
||||
t.Fatalf("读取任务审计操作者失败:%v", err)
|
||||
}
|
||||
operators = append(operators, operator)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
t.Fatalf("遍历任务审计失败:%v", err)
|
||||
}
|
||||
if len(operators) != 2 || operators[0] != "operator-1" || operators[1] != "operator-1" {
|
||||
t.Fatalf("任务审计创建人记录错误:%v", operators)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCertificateTasksKeepRetriesInOneTask(t *testing.T) {
|
||||
w, a := newCertificateTaskFixture(t)
|
||||
calls := 0
|
||||
|
||||
@ -242,10 +242,11 @@ func (s *Server) unregisterTaskCancel(taskID string) {
|
||||
}
|
||||
|
||||
func (s *Server) taskWorkflowContext(c *gin.Context) context.Context {
|
||||
return repository.WithTaskCancellationHooks(c.Request.Context(), repository.TaskCancellationHooks{
|
||||
ctx := repository.WithTaskCancellationHooks(c.Request.Context(), repository.TaskCancellationHooks{
|
||||
Register: s.registerTaskCancel,
|
||||
Unregister: s.unregisterTaskCancel,
|
||||
})
|
||||
return repository.WithTaskOperator(ctx, s.currentOperatorID(c))
|
||||
}
|
||||
|
||||
func taskRepositoryUnavailable(tasks repository.TaskRepository) bool {
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package repository
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type TaskCancellationHooks struct {
|
||||
Register func(string, context.CancelFunc)
|
||||
@ -8,6 +11,7 @@ type TaskCancellationHooks struct {
|
||||
}
|
||||
|
||||
type taskCancellationHooksContextKey struct{}
|
||||
type taskOperatorContextKey struct{}
|
||||
|
||||
func WithTaskCancellationHooks(ctx context.Context, hooks TaskCancellationHooks) context.Context {
|
||||
return context.WithValue(ctx, taskCancellationHooksContextKey{}, hooks)
|
||||
@ -20,3 +24,14 @@ func TaskCancellationHooksFromContext(ctx context.Context) (TaskCancellationHook
|
||||
}
|
||||
return hooks, true
|
||||
}
|
||||
|
||||
// WithTaskOperator 将当前已认证操作者绑定到任务工作流上下文。
|
||||
func WithTaskOperator(ctx context.Context, operatorID string) context.Context {
|
||||
return context.WithValue(ctx, taskOperatorContextKey{}, strings.TrimSpace(operatorID))
|
||||
}
|
||||
|
||||
// TaskOperatorFromContext 读取任务工作流的创建人;后台调度任务没有操作者时返回空字符串。
|
||||
func TaskOperatorFromContext(ctx context.Context) string {
|
||||
operatorID, _ := ctx.Value(taskOperatorContextKey{}).(string)
|
||||
return strings.TrimSpace(operatorID)
|
||||
}
|
||||
|
||||
@ -2,6 +2,17 @@
|
||||
|
||||
## 最新执行摘要(2026-09-29 继续开发)
|
||||
|
||||
总体验收位置继续保持 **P0-03 完成,待复审**;本轮继续先开发、后统一测试,不进入远端生产验收。
|
||||
|
||||
- [x] 已为证书任务工作流增加操作者上下文;HTTP 发起的证书部署、导入、恢复、校验任务会记录当前创建人。
|
||||
- [x] 已将证书任务开始与完成审计关联到同一创建人;后台续期调度没有登录操作者时保持为空,避免伪造身份。
|
||||
- [x] 已新增创建人及审计归属回归测试;`go test ./internal/app ./internal/httpapi ./internal/repository` 和 `git diff --check` 已通过。
|
||||
- [~] P0-10 其余任务的崩溃恢复、DNS 验证任务、批量部署结果及跨入口归属仍需继续审查。
|
||||
- [ ] 三数据库矩阵、浏览器清缓存、密码 SSH、远端部署和生产验收仍未执行。
|
||||
- [!] 不升级总体验收位置;当前仍为 **P0-03 完成,待复审**,本轮没有新增 `[✓]` 复审通过项。
|
||||
|
||||
## 最新执行摘要(2026-09-29 继续开发)
|
||||
|
||||
本轮继续保持总体验收位置为 **P0-03 完成,待复审**,没有新增复审通过项;当前仍按“先开发、后统一测试”执行。
|
||||
|
||||
- [x] 已提交证书导入、恢复、校验任务入口接入代码:`b899751`;远程推送因仓库认证失败未成功,未阻塞本地继续开发。
|
||||
|
||||
@ -2,6 +2,17 @@
|
||||
|
||||
## 最新任务批次(2026-09-29 继续开发)
|
||||
|
||||
总体验收仍保持 **P0-03 完成,待复审**;本批只补齐 P0-10 任务创建人和审计归属,不代表生产部署验收通过。
|
||||
|
||||
- [x] HTTP 证书工作流上下文已传递当前已认证操作者;证书部署、导入、恢复、校验任务不再默认丢失创建人。
|
||||
- [x] 任务开始、完成审计已写入任务创建人;后台续期无认证操作者时保持空值,不使用请求身份以外的信息填充。
|
||||
- [x] 创建人归属回归测试已通过;专项测试为 `go test ./internal/app ./internal/httpapi ./internal/repository`,并通过 `git diff --check`。
|
||||
- [~] P0-10 仍需继续审查 DNS 验证任务、批量部署 `partial_success`、崩溃恢复、重试和其他同步长耗时入口。
|
||||
- [ ] P0-12、三数据库实库矩阵、浏览器、密码 SSH、远端部署和生产验收尚未执行。
|
||||
- [!] 总体验收位置不变:**P0-03 完成,待复审**。
|
||||
|
||||
## 最新任务批次(2026-09-29 继续开发)
|
||||
|
||||
总体验收仍保持 **P0-03 完成,待复审**;本批代码已完成,统一测试已完成本地自动化部分。
|
||||
|
||||
- [x] 证书导入、恢复、校验入口已接入应用任务工作流,提交 `b899751`。
|
||||
|
||||
@ -2,6 +2,16 @@
|
||||
|
||||
## 最新进度摘要(2026-09-29 继续开发)
|
||||
|
||||
**总体验收位置仍为 P0-03 完成,待复审。** 本轮只推进 P0-10 任务归属链,不把局部代码或专项测试结果视为整项复审通过。
|
||||
|
||||
- [x] 任务工作流从认证请求上下文读取创建人,并写入证书任务的 `operator_id`。
|
||||
- [x] 任务开始和完成审计使用任务自身的创建人;后台调度任务继续保留空操作者边界。
|
||||
- [x] 创建人和审计归属专项测试通过;尚未执行三数据库、浏览器、密码 SSH、远端部署和生产门禁。
|
||||
- [~] P0-10 其余任务链、DNS 验证、批量部署、崩溃恢复、重试幂等和 P0-12 仍未完成。
|
||||
- [!] 不新增 `[✓]` 复审通过项,总体验收继续停在 **P0-03 完成,待复审**。
|
||||
|
||||
## 最新进度摘要(2026-09-29 继续开发)
|
||||
|
||||
**总体验收位置仍为 P0-03 完成,待复审。** 本轮只推进 P0-10 任务工作流,不把局部代码完成或专项测试通过视为生产验收通过。
|
||||
|
||||
- [x] 证书导入、恢复、校验任务入口接入应用层,提交 `b899751`。
|
||||
|
||||
@ -2,6 +2,16 @@
|
||||
|
||||
## 最新执行与补充约束(2026-09-29 继续开发)
|
||||
|
||||
总体验收位置继续保持 **P0-03 完成,待复审**。本轮补充 P0-10 任务归属不变量,不改变原始 44 项范围,也不提前进入生产验收。
|
||||
|
||||
- [x] 证书工作流通过上下文记录已认证请求的任务创建人,后台调度任务不得伪造登录操作者。
|
||||
- [x] 证书任务开始、完成审计必须与任务的 `operator_id` 一致;任务资源范围仍由域名项目归属服务端确定。
|
||||
- [x] 创建人归属专项测试通过;完整后端、三数据库实库、浏览器、密码 SSH、远端部署和生产门禁仍未完成。
|
||||
- [~] DNS 验证任务、批量部署结果、崩溃恢复、重试和其他长耗时入口仍需继续补齐。
|
||||
- [!] 本轮不得将总体验收升级为复审通过,当前仍为 **P0-03 完成,待复审**。
|
||||
|
||||
## 最新执行与补充约束(2026-09-29 继续开发)
|
||||
|
||||
总体验收位置继续保持 **P0-03 完成,待复审**。本轮开发不改变原始 44 项范围,也不提前进入生产验收。
|
||||
|
||||
- [x] 证书导入、恢复、校验已接入统一任务工作流,提交 `b899751`。
|
||||
|
||||
Loading…
Reference in New Issue
Block a user