This commit is contained in:
@@ -2,10 +2,12 @@ package domain
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"git.cin.su/m/Assistant/contracts/authority"
|
||||
"git.cin.su/m/Assistant/contracts/capability"
|
||||
commitcontract "git.cin.su/m/Assistant/contracts/commit"
|
||||
"git.cin.su/m/Assistant/contracts/continuity"
|
||||
"git.cin.su/m/Assistant/modules/commit/ports"
|
||||
)
|
||||
|
||||
@@ -39,14 +41,17 @@ func Reconcile(action commitcontract.AuthorizedAction, previous commitcontract.A
|
||||
}
|
||||
|
||||
// Authorize is the Commit boundary. A proposal alone never reaches Executor.
|
||||
func Authorize(proposal commitcontract.ActionProposal, context AuthorizationContext, validator ports.AuthorityValidator, authorizedID commitcontract.AuthorizedActionID) (commitcontract.AuthorizedAction, error) {
|
||||
func Authorize(proposal commitcontract.ActionProposal, context AuthorizationContext, validator ports.AuthorityValidator, authorizedID commitcontract.AuthorizedActionID, authorizedAtUnixMillis int64) (commitcontract.AuthorizedAction, error) {
|
||||
if proposal.IntentID == "" || proposal.ActorID == "" || proposal.CapabilityID == capability.CapabilityID("") ||
|
||||
proposal.Target.TaskID == "" || proposal.Target.GoalID == "" || proposal.Target.ScopeID == "" || proposal.Target.Revision == 0 || proposal.Operation == "" {
|
||||
proposal.Target.TaskID == "" || proposal.Target.GoalID == "" || proposal.Target.ScopeID == "" || proposal.Target.Revision == 0 || proposal.Operation == "" || authorizedAtUnixMillis <= 0 {
|
||||
return commitcontract.AuthorizedAction{}, ErrInvalidProposal
|
||||
}
|
||||
if proposal.ActorID != context.Binding.ActorID || proposal.Target.ScopeID != context.Scope.ID {
|
||||
return commitcontract.AuthorizedAction{}, ErrInvalidProposal
|
||||
}
|
||||
if !allowedOperation(proposal, context) {
|
||||
return commitcontract.AuthorizedAction{}, ErrInvalidProposal
|
||||
}
|
||||
if err := validator.Validate(context); err != nil {
|
||||
return commitcontract.AuthorizedAction{}, err
|
||||
}
|
||||
@@ -54,7 +59,21 @@ func Authorize(proposal commitcontract.ActionProposal, context AuthorizationCont
|
||||
return commitcontract.AuthorizedAction{}, ErrInvalidProposal
|
||||
}
|
||||
proposal.State = commitcontract.ActionProposed
|
||||
return commitcontract.AuthorizedAction{ID: authorizedID, Proposal: proposal, GrantID: context.Grant.ID, ScopeID: context.Scope.ID, State: commitcontract.ActionAuthorized}, nil
|
||||
return commitcontract.AuthorizedAction{ID: authorizedID, Proposal: proposal, PrincipalID: context.Binding.PrincipalID, GrantID: context.Grant.ID, GrantRevision: context.Grant.Revision, ScopeID: context.Scope.ID, AuthorizedAtUnixMillis: authorizedAtUnixMillis, State: commitcontract.ActionAuthorized}, nil
|
||||
}
|
||||
|
||||
func allowedOperation(proposal commitcontract.ActionProposal, context AuthorizationContext) bool {
|
||||
switch {
|
||||
case proposal.CapabilityID == commitcontract.CapabilityTestExecutor && proposal.Operation == commitcontract.OperationTestIdempotentEffect:
|
||||
return true
|
||||
case context.Grant.Class == authority.GrantClassCreator && proposal.CapabilityID == commitcontract.CapabilityContinuityTransition && proposal.Operation == commitcontract.OperationSatisfyDelivered:
|
||||
subject := proposal.ContinuitySubject
|
||||
return subject.ProspectiveItemID != "" && subject.ExpectedRevision > 0 &&
|
||||
subject.FromState == continuity.ProspectiveDelivered && subject.ToState == continuity.ProspectiveSatisfied &&
|
||||
strings.TrimSpace(subject.EvidenceRef) != ""
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Execute records UNKNOWN_OUTCOME rather than silently retrying an ambiguous
|
||||
|
||||
Reference in New Issue
Block a user