2023-10-30 16:48:02 +03:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2023-10-30 18:30:23 +03:00
|
|
|
"sync"
|
2024-03-15 10:10:03 +03:00
|
|
|
"time"
|
2023-10-30 18:30:23 +03:00
|
|
|
|
2023-11-20 19:35:16 +03:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/chainbase"
|
|
|
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
2023-11-16 10:58:55 +03:00
|
|
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
2023-11-20 19:35:16 +03:00
|
|
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource"
|
2024-03-15 10:10:03 +03:00
|
|
|
"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"
|
2023-10-30 16:48:02 +03:00
|
|
|
)
|
|
|
|
|
2023-11-20 19:35:16 +03:00
|
|
|
type accessPolicyEngine struct {
|
|
|
|
mtx sync.RWMutex
|
|
|
|
|
|
|
|
chainRouter engine.ChainRouter
|
|
|
|
|
|
|
|
morphChainStorage engine.MorphRuleChainStorage
|
|
|
|
|
|
|
|
localOverrideDatabase chainbase.LocalOverrideDatabase
|
2023-10-30 16:48:02 +03:00
|
|
|
}
|
|
|
|
|
2023-11-20 19:35:16 +03:00
|
|
|
var _ engine.LocalOverrideEngine = (*accessPolicyEngine)(nil)
|
|
|
|
|
2024-03-15 10:10:03 +03:00
|
|
|
var _ engine.MorphRuleChainStorage = (*morphAPEChainCache)(nil)
|
|
|
|
|
|
|
|
type morphAPEChainCacheKey struct {
|
|
|
|
name chain.Name
|
|
|
|
target engine.Target
|
|
|
|
}
|
|
|
|
|
|
|
|
type morphAPEChainCache struct {
|
|
|
|
source engine.MorphRuleChainStorage
|
|
|
|
cache *expirable.LRU[morphAPEChainCacheKey, []*chain.Chain]
|
|
|
|
}
|
|
|
|
|
|
|
|
func newMorphCache(source engine.MorphRuleChainStorage, size int, ttl time.Duration) engine.MorphRuleChainStorage {
|
|
|
|
return &morphAPEChainCache{
|
|
|
|
source: source,
|
|
|
|
cache: expirable.NewLRU(size, func(morphAPEChainCacheKey, []*chain.Chain) {}, ttl),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *morphAPEChainCache) AddMorphRuleChain(name chain.Name, target engine.Target, c *chain.Chain) (util.Uint256, uint32, error) {
|
|
|
|
m.cache.Remove(morphAPEChainCacheKey{name: name, target: target})
|
|
|
|
return m.source.AddMorphRuleChain(name, target, c)
|
|
|
|
}
|
|
|
|
|
|
|
|
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) RemoveMorphRuleChain(name chain.Name, target engine.Target, chainID chain.ID) (util.Uint256, uint32, error) {
|
|
|
|
m.cache.Remove(morphAPEChainCacheKey{name: name, target: target})
|
|
|
|
return m.source.RemoveMorphRuleChain(name, target, chainID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *morphAPEChainCache) SetAdmin(addr util.Uint160) (util.Uint256, uint32, error) {
|
|
|
|
return m.source.SetAdmin(addr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *morphAPEChainCache) ListTargetsIterator(targetType engine.TargetType) (uuid.UUID, result.Iterator, error) {
|
|
|
|
return m.source.ListTargetsIterator(targetType)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *morphAPEChainCache) RemoveMorphRuleChainsByTarget(name chain.Name, target engine.Target) (util.Uint256, uint32, error) {
|
|
|
|
m.cache.Remove(morphAPEChainCacheKey{name: name, target: target})
|
|
|
|
return m.source.RemoveMorphRuleChainsByTarget(name, target)
|
|
|
|
}
|
|
|
|
|
2023-11-20 19:35:16 +03:00
|
|
|
func newAccessPolicyEngine(
|
|
|
|
morphChainStorage engine.MorphRuleChainStorage,
|
2023-12-12 15:36:27 +03:00
|
|
|
localOverrideDatabase chainbase.LocalOverrideDatabase,
|
|
|
|
) *accessPolicyEngine {
|
2023-11-20 19:35:16 +03:00
|
|
|
return &accessPolicyEngine{
|
|
|
|
chainRouter: engine.NewDefaultChainRouterWithLocalOverrides(
|
|
|
|
morphChainStorage,
|
|
|
|
localOverrideDatabase,
|
|
|
|
),
|
|
|
|
|
|
|
|
morphChainStorage: morphChainStorage,
|
|
|
|
|
|
|
|
localOverrideDatabase: localOverrideDatabase,
|
2023-10-30 16:48:02 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-20 19:35:16 +03:00
|
|
|
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()
|
2023-10-30 16:48:02 +03:00
|
|
|
|
2023-11-20 19:35:16 +03:00
|
|
|
return a.chainRouter.IsAllowed(name, target, r)
|
|
|
|
}
|
2023-10-30 18:30:23 +03:00
|
|
|
|
2023-11-20 19:35:16 +03:00
|
|
|
func (a *accessPolicyEngine) MorphRuleChainStorage() engine.MorphRuleChainStorage {
|
|
|
|
a.mtx.Lock()
|
|
|
|
defer a.mtx.Unlock()
|
|
|
|
|
|
|
|
return a.morphChainStorage
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2023-10-30 16:48:02 +03:00
|
|
|
}
|