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 RemoveOverridesByTarget(name chain.Name, target Target) 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' User TargetType = 'u' Group TargetType = 'g' ) type Target struct { Type TargetType Name string } // RequestTarget combines several targets on which the request is performed. type RequestTarget struct { Namespace *Target Container *Target User *Target Groups []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 NewRequestTargetExtended(namespace, container, user string, groups []string) RequestTarget { nt := NamespaceTarget(namespace) ct := ContainerTarget(container) u := UserTarget(user) rt := RequestTarget{ Namespace: &nt, Container: &ct, User: &u, } if len(groups) != 0 { rt.Groups = make([]Target, len(groups)) for i := range groups { rt.Groups[i] = GroupTarget(groups[i]) } } return rt } func (rt *RequestTarget) Targets() (targets []Target) { if rt.Namespace != nil { targets = append(targets, *rt.Namespace) } if rt.Container != nil { targets = append(targets, *rt.Container) } if rt.User != nil { targets = append(targets, *rt.User) } if len(rt.Groups) != 0 { targets = append(targets, rt.Groups...) } return } func NamespaceTarget(namespace string) Target { return Target{ Type: Namespace, Name: namespace, } } func ContainerTarget(container string) Target { return Target{ Type: Container, Name: container, } } func UserTarget(user string) Target { return Target{ Type: User, Name: user, } } func GroupTarget(group string) Target { return Target{ Type: Group, Name: group, } } // 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) // RemoveMorphRuleChainsByTarget removes all chains by target and returns transaction hash, VUB and error. RemoveMorphRuleChainsByTarget(name chain.Name, target Target) (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 }