package engine import ( "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" "git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource" "github.com/google/uuid" "github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/util" ) type ChainRouter interface { // IsAllowed returns status for the operation after all checks. // The second return value signifies whether a matching rule was found. IsAllowed(name chain.Name, reqTarget RequestTarget, r resource.Request) (status chain.Status, found bool, err error) } // LocalOverrideStorage is the interface to manage local overrides defined // for a node. Local overrides have a higher priority than chains got from morph storage. type LocalOverrideStorage interface { AddOverride(name chain.Name, target Target, c *chain.Chain) (chain.ID, error) GetOverride(name chain.Name, target Target, chainID chain.ID) (*chain.Chain, error) RemoveOverride(name chain.Name, target Target, chainID chain.ID) error ListOverrides(name chain.Name, target Target) ([]*chain.Chain, error) DropAllOverrides(name chain.Name) error ListOverrideDefinedTargets(name chain.Name) ([]Target, error) } type TargetType rune const ( Namespace TargetType = 'n' Container TargetType = 'c' ) type Target struct { Type TargetType Name string } // RequestTarget combines several targets on which the request is performed. type RequestTarget struct { Namespace *Target Container *Target } func NewRequestTargetWithNamespace(namespace string) RequestTarget { nt := NamespaceTarget(namespace) return RequestTarget{ Namespace: &nt, } } func NewRequestTargetWithContainer(container string) RequestTarget { ct := ContainerTarget(container) return RequestTarget{ Container: &ct, } } func NewRequestTarget(namespace, container string) RequestTarget { nt := NamespaceTarget(namespace) ct := ContainerTarget(container) return RequestTarget{ Namespace: &nt, Container: &ct, } } func (rt *RequestTarget) Targets() (targets []Target) { if rt.Namespace != nil { targets = append(targets, *rt.Namespace) } if rt.Container != nil { targets = append(targets, *rt.Container) } return } func NamespaceTarget(namespace string) Target { return Target{ Type: Namespace, Name: namespace, } } func ContainerTarget(container string) Target { return Target{ Type: Container, Name: container, } } // MorphRuleChainStorageReader is the interface that provides read-only methods to receive // data like chains, target or admin from a chain storage. type MorphRuleChainStorageReader interface { // ListMorphRuleChains just lists deserialized chains. ListMorphRuleChains(name chain.Name, target Target) ([]*chain.Chain, error) GetAdmin() (util.Uint160, error) // ListTargetsIterator provides an iterator to list targets for which rules are defined. ListTargetsIterator(targetType TargetType) (uuid.UUID, result.Iterator, error) } // MorphRuleChainStorage is the interface to read and manage data within a chain storage. // Basically, this implies that the storage manages rules stored in policy contract. type MorphRuleChainStorage interface { MorphRuleChainStorageReader // AddMorphRuleChain adds a chain rule to the policy contract and returns transaction hash, VUB and error. AddMorphRuleChain(name chain.Name, target Target, c *chain.Chain) (util.Uint256, uint32, error) // RemoveMorphRuleChain removes a chain rule to the policy contract and returns transaction hash, VUB and error. RemoveMorphRuleChain(name chain.Name, target Target, chainID chain.ID) (util.Uint256, uint32, error) SetAdmin(addr util.Uint160) (util.Uint256, uint32, error) } // Engine is the interface that provides methods to check request permissions checking // chain rules from morph client - this implies using the policy contract. type Engine interface { ChainRouter MorphRuleChainStorage() MorphRuleChainStorage } // LocalOverrideEngine is extended Engine that also provides methods to manage a local // chain rule storage. Local overrides must have the highest priority during request checking. type LocalOverrideEngine interface { Engine LocalStorage() LocalOverrideStorage }