frostfs-node/cmd/frostfs-node/policy_engine.go

102 lines
2.6 KiB
Go

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
}