补齐任务取消权限闭环

增加项目任务取消权限校验和回归测试,并记录本轮开发进度。
This commit is contained in:
xuans 2026-09-29 21:42:35 +08:00
parent 7718ecf789
commit 3504dcab7a
6 changed files with 90 additions and 4 deletions

View File

@ -273,6 +273,9 @@ func (s *Server) cancelTask(c *gin.Context) {
c.JSON(http.StatusConflict, gin.H{"error": "管理证书任务由续期调度控制,不能单独修改取消状态", "task": item})
return
}
if !s.authorizeProjectPermissions(c, item.ProjectID, domain.PermissionTaskCancel) {
return
}
finished := time.Now().UTC()
if err := reader.CancelVisibleTask(c.Request.Context(), c.GetString(authenticatedActorKey), taskID, "任务已由用户取消", &finished); err != nil {
if errors.Is(err, repository.ErrProjectAccessDenied) || errors.Is(err, sql.ErrNoRows) {

View File

@ -369,6 +369,45 @@ func TestTaskAPIReturnsNotImplementedWhenTaskDependenciesAreMissing(t *testing.T
}
}
type taskPermissionProjectMemberRepository struct {
repository.ProjectMemberRepository
authorize func(context.Context, string, string, domain.ProjectPermission) error
}
func (r taskPermissionProjectMemberRepository) AuthorizeProject(ctx context.Context, actorID, projectID string, permission domain.ProjectPermission) error {
if r.authorize != nil {
return r.authorize(ctx, actorID, projectID, permission)
}
return nil
}
func TestTaskAPIDeniesCancelWithoutProjectPermission(t *testing.T) {
server, tasks, _, closeDB := newTaskAPITestServer(t, nil)
defer closeDB()
server.projectMembers = taskPermissionProjectMemberRepository{
ProjectMemberRepository: server.projectMembers,
authorize: func(_ context.Context, _ string, _ string, permission domain.ProjectPermission) error {
if permission == domain.PermissionTaskCancel {
return repository.ErrProjectAccessDenied
}
return nil
},
}
item := repository.Task{
HistoryScope: repository.HistoryScope{ScopeType: repository.ScopeProject, ProjectID: domain.DefaultProjectID},
ID: "cancel-permission-task", DomainID: "domain-1", TaskType: "certificate_issue", Status: "running", Stage: "certificate_issue",
}
if err := tasks.CreateTask(t.Context(), item); err != nil {
t.Fatal(err)
}
response := httptest.NewRecorder()
serveAdminHTTP(server, response, httptest.NewRequest(http.MethodDelete, "/api/v1/tasks/"+item.ID, nil))
stored, err := tasks.GetTask(t.Context(), item.ID)
if response.Code != http.StatusForbidden || err != nil || stored.Status != "running" {
t.Fatalf("cancel permission denial changed task: %d %+v %v", response.Code, stored, err)
}
}
func TestIssueDomainSanitizesDeploymentReportWithoutTaskRepository(t *testing.T) {
cfg := readyTestConfig(t.TempDir())
server := New(Dependencies{

View File

@ -3462,4 +3462,15 @@ Linux Ubuntu 22.04 上的 `Scert-admin` 手动启停、无开机自启动、无
- `[~]` P0-07 其他资源写入权限、三数据库矩阵、浏览器清缓存验收、密码 SSH、远端部署及 Linux/Windows 生产服务仍需继续开发或复审。
- `[!]` 总体验收不得升级,P0-03 仍为“完成,待复审”。
下一步继续执行前端回归与生产构建,再提交并推送本轮测试代码;完成开发阶段后,统一进行三数据库、浏览器、远端服务器和生产部署测试。
下一步继续执行前端回归与生产构建,再提交并推送本轮测试代码;完成开发阶段后,统一进行三数据库、浏览器、远端服务器和生产部署测试。
## 本轮开发进度(2026-09-29)
总体验收位置继续保持 **P0-03:完成,待复审**;本轮继续推进 P0-07 项目任务权限闭环,不将局部测试结果视为生产部署验收通过。
- [x] 项目任务取消入口新增 ask.cancel 实时项目权限校验,权限拒绝时不会调用取消写入,也不会改变任务状态。
- [x] 已补充缺少任务取消权限的 HTTP 回归测试;任务取消、工作流任务保护及成功证书任务回归测试通过。
- [x] 已确认域名与服务器多对多部署关联仍按既有事务模型工作:一个域名可绑定多个服务器,一个服务器可关联多个域名,解绑单个域名不影响其他关联。
- [~] P0-07 仍需继续补齐续期、证书导入/部署、其他任务写入权限及三数据库矩阵。
- [!] 浏览器清缓存验收、密码 SSH、远端部署、HTTPS/DNS/ACME、Linux/Windows 服务和生产部署验收尚未执行。
下一步继续完成开发阶段剩余权限闭环,再统一执行生产构建、部署和验收;总体验收位置仍以 P0-03 为准。

View File

@ -758,4 +758,15 @@ P0-05 从 `[!]` 调整为 `[~]`,并未标记完成;P0-04 剩余门禁和全
- `[~]` P0-07 其他资源写入权限、三数据库矩阵、浏览器清缓存验收、密码 SSH、远端部署及 Linux/Windows 生产服务仍需继续开发或复审。
- `[!]` 总体验收不得升级,P0-03 仍为“完成,待复审”。
下一步继续执行前端回归与生产构建,再提交并推送本轮测试代码;完成开发阶段后,统一进行三数据库、浏览器、远端服务器和生产部署测试。
下一步继续执行前端回归与生产构建,再提交并推送本轮测试代码;完成开发阶段后,统一进行三数据库、浏览器、远端服务器和生产部署测试。
## 本轮开发进度(2026-09-29)
总体验收位置继续保持 **P0-03:完成,待复审**;本轮继续推进 P0-07 项目任务权限闭环,不将局部测试结果视为生产部署验收通过。
- [x] 项目任务取消入口新增 ask.cancel 实时项目权限校验,权限拒绝时不会调用取消写入,也不会改变任务状态。
- [x] 已补充缺少任务取消权限的 HTTP 回归测试;任务取消、工作流任务保护及成功证书任务回归测试通过。
- [x] 已确认域名与服务器多对多部署关联仍按既有事务模型工作:一个域名可绑定多个服务器,一个服务器可关联多个域名,解绑单个域名不影响其他关联。
- [~] P0-07 仍需继续补齐续期、证书导入/部署、其他任务写入权限及三数据库矩阵。
- [!] 浏览器清缓存验收、密码 SSH、远端部署、HTTPS/DNS/ACME、Linux/Windows 服务和生产部署验收尚未执行。
下一步继续完成开发阶段剩余权限闭环,再统一执行生产构建、部署和验收;总体验收位置仍以 P0-03 为准。

View File

@ -1398,4 +1398,15 @@ P0-11 生产验收门禁
- `[~]` P0-07 其他资源写入权限、三数据库矩阵、浏览器清缓存验收、密码 SSH、远端部署及 Linux/Windows 生产服务仍需继续开发或复审。
- `[!]` 总体验收不得升级,P0-03 仍为“完成,待复审”。
下一步继续执行前端回归与生产构建,再提交并推送本轮测试代码;完成开发阶段后,统一进行三数据库、浏览器、远端服务器和生产部署测试。
下一步继续执行前端回归与生产构建,再提交并推送本轮测试代码;完成开发阶段后,统一进行三数据库、浏览器、远端服务器和生产部署测试。
## 本轮开发进度(2026-09-29)
总体验收位置继续保持 **P0-03:完成,待复审**;本轮继续推进 P0-07 项目任务权限闭环,不将局部测试结果视为生产部署验收通过。
- [x] 项目任务取消入口新增 ask.cancel 实时项目权限校验,权限拒绝时不会调用取消写入,也不会改变任务状态。
- [x] 已补充缺少任务取消权限的 HTTP 回归测试;任务取消、工作流任务保护及成功证书任务回归测试通过。
- [x] 已确认域名与服务器多对多部署关联仍按既有事务模型工作:一个域名可绑定多个服务器,一个服务器可关联多个域名,解绑单个域名不影响其他关联。
- [~] P0-07 仍需继续补齐续期、证书导入/部署、其他任务写入权限及三数据库矩阵。
- [!] 浏览器清缓存验收、密码 SSH、远端部署、HTTPS/DNS/ACME、Linux/Windows 服务和生产部署验收尚未执行。
下一步继续完成开发阶段剩余权限闭环,再统一执行生产构建、部署和验收;总体验收位置仍以 P0-03 为准。

View File

@ -347,4 +347,15 @@ P0-06 与 P0-07 均维持 `[~]`,六阶段中的隔离、生产和最终验收
- `[~]` P0-07 其他资源写入权限、三数据库矩阵、浏览器清缓存验收、密码 SSH、远端部署及 Linux/Windows 生产服务仍需继续开发或复审。
- `[!]` 总体验收不得升级,P0-03 仍为“完成,待复审”。
下一步继续执行前端回归与生产构建,再提交并推送本轮测试代码;完成开发阶段后,统一进行三数据库、浏览器、远端服务器和生产部署测试。
下一步继续执行前端回归与生产构建,再提交并推送本轮测试代码;完成开发阶段后,统一进行三数据库、浏览器、远端服务器和生产部署测试。
## 本轮开发进度(2026-09-29)
总体验收位置继续保持 **P0-03:完成,待复审**;本轮继续推进 P0-07 项目任务权限闭环,不将局部测试结果视为生产部署验收通过。
- [x] 项目任务取消入口新增 ask.cancel 实时项目权限校验,权限拒绝时不会调用取消写入,也不会改变任务状态。
- [x] 已补充缺少任务取消权限的 HTTP 回归测试;任务取消、工作流任务保护及成功证书任务回归测试通过。
- [x] 已确认域名与服务器多对多部署关联仍按既有事务模型工作:一个域名可绑定多个服务器,一个服务器可关联多个域名,解绑单个域名不影响其他关联。
- [~] P0-07 仍需继续补齐续期、证书导入/部署、其他任务写入权限及三数据库矩阵。
- [!] 浏览器清缓存验收、密码 SSH、远端部署、HTTPS/DNS/ACME、Linux/Windows 服务和生产部署验收尚未执行。
下一步继续完成开发阶段剩余权限闭环,再统一执行生产构建、部署和验收;总体验收位置仍以 P0-03 为准。