policy-engine/pkg/engine/inmemory.go
aarifullin a08f600d97 [#7] engine: Set project structure pattern for files
* Create pkg package
* Move chain-relates structures to pkg/chain package
* Move inmemory and interface files to pkg/engine package
* Move resource structures to pkg/resource package
* Move GlobMatch to util package

Signed-off-by: Airat Arifullin <aarifullin@yadro.com>
2023-11-15 09:22:42 +00:00

113 lines
2.7 KiB
Go

package engine
import (
"git.frostfs.info/TrueCloudLab/policy-engine/util"
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource"
)
type inmemory struct {
namespace map[chain.Name][]chainWrapper
resource map[chain.Name][]chainWrapper
local map[chain.Name][]*chain.Chain
}
type chainWrapper struct {
object string
chain *chain.Chain
}
// NewInMemory returns new inmemory instance of chain storage.
func NewInMemory() CachedChainStorage {
return &inmemory{
namespace: make(map[chain.Name][]chainWrapper),
resource: make(map[chain.Name][]chainWrapper),
local: make(map[chain.Name][]*chain.Chain),
}
}
// IsAllowed implements the Engine interface.
func (s *inmemory) IsAllowed(name chain.Name, namespace string, r resource.Request) (chain.Status, bool) {
var ruleFound bool
if local, ok := s.local[name]; ok {
for _, c := range local {
if status, matched := c.Match(r); matched && status != chain.Allow {
return status, true
}
}
}
if cs, ok := s.namespace[name]; ok {
status, ok := matchArray(cs, namespace, r)
if ok && status != chain.Allow {
return status, true
}
ruleFound = ruleFound || ok
}
if cs, ok := s.resource[name]; ok {
status, ok := matchArray(cs, r.Resource().Name(), r)
if ok {
return status, true
}
ruleFound = ruleFound || ok
}
if ruleFound {
return chain.Allow, true
}
return chain.NoRuleFound, false
}
func matchArray(cs []chainWrapper, object string, r resource.Request) (chain.Status, bool) {
for _, c := range cs {
if !util.GlobMatch(object, c.object) {
continue
}
if status, matched := c.chain.Match(r); matched {
return status, true
}
}
return chain.NoRuleFound, false
}
func (s *inmemory) AddResourceChain(name chain.Name, resource string, c *chain.Chain) {
s.resource[name] = append(s.resource[name], chainWrapper{resource, c})
}
func (s *inmemory) AddNameSpaceChain(name chain.Name, namespace string, c *chain.Chain) {
s.namespace[name] = append(s.namespace[name], chainWrapper{namespace, c})
}
func (s *inmemory) AddOverride(name chain.Name, c *chain.Chain) {
s.local[name] = append(s.local[name], c)
}
func (s *inmemory) GetOverride(name chain.Name, chainID chain.ID) (chain *chain.Chain, found bool) {
chains := s.local[name]
for _, chain = range chains {
if chain.ID == chainID {
found = true
return
}
}
return
}
func (s *inmemory) RemoveOverride(name chain.Name, chainID chain.ID) (found bool) {
chains := s.local[name]
for i, chain := range chains {
if chain.ID == chainID {
s.local[name] = append(chains[:i], chains[i+1:]...)
found = true
return
}
}
return
}
func (s *inmemory) ListOverrides(name chain.Name) []*chain.Chain {
return s.local[name]
}