Scert/backend/internal/httpapi/task_execution_authorization.go

43 lines
1.7 KiB
Go

package httpapi
import (
"context"
"git.pcux.cn/xuans/Scert/backend/internal/domain"
"git.pcux.cn/xuans/Scert/backend/internal/repository"
)
// 排队期间权限和资源归属可能变化;历史快照只用于审计,不作为授权凭证。
// 只检查本次即将执行的操作,后台自动续期不从此 HTTP 任务入口执行。
func (s *Server) authorizeCertificateTaskExecution(ctx context.Context, task repository.Task, attempt repository.TaskAttempt) error {
authorizer, ok := s.projectMembers.(repository.ProjectAuthorizer)
if !ok || s.projectResources == nil || task.OperatorID == "" || task.ScopeType != repository.ScopeProject || task.ProjectID == "" {
return repository.ErrProjectAccessDenied
}
resource, err := s.projectResources.GetVisibleDomain(ctx, task.OperatorID, task.DomainID)
if err != nil {
return err
}
if resource.ID != task.DomainID || resource.ResourceScope.Normalize().ProjectID != task.ProjectID {
return repository.ErrProjectAccessDenied
}
permissions := []domain.ProjectPermission{domain.PermissionDeploymentExecute}
switch task.TaskType {
case "certificate_issue":
permissions = append(permissions, domain.PermissionCertificateManage, domain.PermissionDNSCredentialUse)
case "certificate_deploy":
default:
return repository.ErrProjectAccessDenied
}
if attempt.AttemptNumber > 1 {
// 重试仓储已将操作者更新为本次重试者,不能沿用首次提交者权限。
permissions = append(permissions, domain.PermissionTaskRetry, domain.PermissionCertificateManage)
}
for _, permission := range permissions {
if err := authorizer.AuthorizeProject(ctx, task.OperatorID, task.ProjectID, permission); err != nil {
return err
}
}
return nil
}