package main import ( "sync" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/chainbase" "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine" "git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource" "github.com/google/uuid" "github.com/hashicorp/golang-lru/v2/expirable" "github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/util" ) type accessPolicyEngine struct { mtx sync.RWMutex chainRouter engine.ChainRouter localOverrideDatabase chainbase.LocalOverrideDatabase } var _ engine.MorphRuleChainStorageReader = (*morphAPEChainCache)(nil) type morphAPEChainCacheKey struct { name chain.Name target engine.Target } type morphAPEChainCache struct { source engine.MorphRuleChainStorageReader cache *expirable.LRU[morphAPEChainCacheKey, []*chain.Chain] } func newMorphCache(source engine.MorphRuleChainStorageReader, size int, ttl time.Duration) engine.MorphRuleChainStorageReader { return &morphAPEChainCache{ source: source, cache: expirable.NewLRU(size, func(morphAPEChainCacheKey, []*chain.Chain) {}, ttl), } } func (m *morphAPEChainCache) GetAdmin() (util.Uint160, error) { return m.source.GetAdmin() } func (m *morphAPEChainCache) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) { key := morphAPEChainCacheKey{name: name, target: target} result, found := m.cache.Get(key) if found { return result, nil } result, err := m.source.ListMorphRuleChains(name, target) if err != nil { return nil, err } m.cache.Add(key, result) return result, nil } func (m *morphAPEChainCache) ListTargetsIterator(targetType engine.TargetType) (uuid.UUID, result.Iterator, error) { return m.source.ListTargetsIterator(targetType) } func newAccessPolicyEngine( morphChainStorage engine.MorphRuleChainStorageReader, localOverrideDatabase chainbase.LocalOverrideDatabase, ) *accessPolicyEngine { return &accessPolicyEngine{ chainRouter: engine.NewDefaultChainRouterWithLocalOverrides( morphChainStorage, localOverrideDatabase, ), localOverrideDatabase: localOverrideDatabase, } } func (a *accessPolicyEngine) IsAllowed(name chain.Name, target engine.RequestTarget, r resource.Request) (status chain.Status, found bool, err error) { a.mtx.RLock() defer a.mtx.RUnlock() return a.chainRouter.IsAllowed(name, target, r) } func (a *accessPolicyEngine) LocalStorage() engine.LocalOverrideStorage { a.mtx.Lock() defer a.mtx.Unlock() return a.localOverrideDatabase } func (a *accessPolicyEngine) LocalOverrideDatabaseCore() chainbase.DatabaseCore { a.mtx.Lock() defer a.mtx.Unlock() return a.localOverrideDatabase }