2023-12-08 07:44:13 +00:00
|
|
|
package policy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
policycontract "git.frostfs.info/TrueCloudLab/frostfs-contract/policy"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
2024-02-13 08:50:11 +00:00
|
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
2023-12-08 07:44:13 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
|
|
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
2024-04-01 09:51:05 +00:00
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
2023-12-08 07:44:13 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
type MorphRuleChainStorage struct {
|
|
|
|
contract Contract
|
|
|
|
cache *cache.MorphPolicyCache
|
|
|
|
log *zap.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
type MorphRuleChainStorageConfig struct {
|
|
|
|
Contract Contract
|
|
|
|
Cache *cache.MorphPolicyCache
|
|
|
|
Log *zap.Logger
|
|
|
|
}
|
|
|
|
|
2024-04-01 09:51:05 +00:00
|
|
|
var _ engine.MorphRuleChainStorageReader = (*MorphRuleChainStorage)(nil)
|
2024-02-13 08:50:11 +00:00
|
|
|
|
|
|
|
const bucketPolicyPrefix = 'b'
|
2023-12-08 07:44:13 +00:00
|
|
|
|
|
|
|
func NewMorphRuleChainStorage(config *MorphRuleChainStorageConfig) *MorphRuleChainStorage {
|
|
|
|
return &MorphRuleChainStorage{
|
|
|
|
contract: config.Contract,
|
|
|
|
cache: config.Cache,
|
|
|
|
log: config.Log,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-01 09:51:05 +00:00
|
|
|
func (c *MorphRuleChainStorage) GetAdmin() (util.Uint160, error) {
|
2024-02-13 08:50:11 +00:00
|
|
|
panic("should never be called")
|
2023-12-08 07:44:13 +00:00
|
|
|
}
|
|
|
|
|
2024-04-01 09:51:05 +00:00
|
|
|
func (c *MorphRuleChainStorage) ListTargetsIterator(engine.TargetType) (uuid.UUID, result.Iterator, error) {
|
2024-02-13 08:50:11 +00:00
|
|
|
panic("should never be called")
|
2023-12-08 07:44:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *MorphRuleChainStorage) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) {
|
|
|
|
key := cache.MorphPolicyCacheKey{Target: target, Name: name}
|
|
|
|
list := c.cache.Get(key)
|
|
|
|
if list != nil {
|
|
|
|
return list, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
listChains, err := c.contract.ListChains(getKind(target), target.Name, []byte(name))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
list = make([]*chain.Chain, len(listChains))
|
|
|
|
for i, listChain := range listChains {
|
|
|
|
var item chain.Chain
|
2024-02-07 09:23:15 +00:00
|
|
|
if err = item.DecodeBytes(listChain); err != nil {
|
2023-12-08 07:44:13 +00:00
|
|
|
return nil, fmt.Errorf("unmarshal chain: %w", err)
|
|
|
|
}
|
|
|
|
list[i] = &item
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = c.cache.Put(key, list); err != nil {
|
|
|
|
c.log.Warn(logs.CouldntCacheListPolicyChains)
|
|
|
|
}
|
|
|
|
|
|
|
|
return list, nil
|
|
|
|
}
|
|
|
|
|
2024-02-19 07:51:41 +00:00
|
|
|
func (c *MorphRuleChainStorage) PutBucketPolicy(ns string, cnrID cid.ID, policy []byte, chains []*chain.Chain) error {
|
2024-04-10 12:53:36 +00:00
|
|
|
c.cache.Delete(cache.MorphPolicyCacheKey{Target: engine.ContainerTarget(cnrID.EncodeToString()), Name: chain.S3})
|
2024-02-13 08:50:11 +00:00
|
|
|
|
|
|
|
tx := c.contract.StartTx()
|
|
|
|
tx.AddChain(policycontract.IAM, ns, getBucketPolicyName(cnrID), policy)
|
|
|
|
|
2024-02-19 07:51:41 +00:00
|
|
|
for i := range chains {
|
2024-04-10 12:53:36 +00:00
|
|
|
tx.AddChain(policycontract.Container, cnrID.EncodeToString(), chains[i].ID, chains[i].Bytes())
|
2024-02-19 07:51:41 +00:00
|
|
|
}
|
|
|
|
|
2024-02-13 08:50:11 +00:00
|
|
|
return c.contract.SendTx(tx)
|
|
|
|
}
|
|
|
|
|
2024-04-01 09:51:05 +00:00
|
|
|
func (c *MorphRuleChainStorage) DeleteBucketPolicy(ns string, cnrID cid.ID, chainIDs []chain.ID) error {
|
2024-04-10 12:53:36 +00:00
|
|
|
c.cache.Delete(cache.MorphPolicyCacheKey{Target: engine.ContainerTarget(cnrID.EncodeToString()), Name: chain.S3})
|
2024-02-13 08:50:11 +00:00
|
|
|
|
|
|
|
tx := c.contract.StartTx()
|
2024-04-01 09:51:05 +00:00
|
|
|
for _, chainID := range chainIDs {
|
2024-04-10 12:53:36 +00:00
|
|
|
tx.RemoveChain(policycontract.Container, cnrID.EncodeToString(), chainID)
|
2024-04-01 09:51:05 +00:00
|
|
|
}
|
2024-02-13 08:50:11 +00:00
|
|
|
tx.RemoveChain(policycontract.IAM, ns, getBucketPolicyName(cnrID))
|
|
|
|
|
|
|
|
return c.contract.SendTx(tx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *MorphRuleChainStorage) GetBucketPolicy(ns string, cnrID cid.ID) ([]byte, error) {
|
|
|
|
return c.contract.GetChain(policycontract.IAM, ns, getBucketPolicyName(cnrID))
|
|
|
|
}
|
|
|
|
|
2024-04-10 12:53:36 +00:00
|
|
|
func (c *MorphRuleChainStorage) SaveACLChains(cid string, chains []*chain.Chain) error {
|
|
|
|
c.cache.Delete(cache.MorphPolicyCacheKey{Target: engine.ContainerTarget(cid), Name: chain.S3})
|
|
|
|
c.cache.Delete(cache.MorphPolicyCacheKey{Target: engine.ContainerTarget(cid), Name: chain.Ingress})
|
2024-02-13 08:50:11 +00:00
|
|
|
|
|
|
|
tx := c.contract.StartTx()
|
|
|
|
for i := range chains {
|
2024-04-10 12:53:36 +00:00
|
|
|
tx.AddChain(policycontract.Container, cid, chains[i].ID, chains[i].Bytes())
|
2024-02-13 08:50:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return c.contract.SendTx(tx)
|
|
|
|
}
|
|
|
|
|
2023-12-08 07:44:13 +00:00
|
|
|
func getKind(target engine.Target) policycontract.Kind {
|
2024-04-11 11:31:53 +00:00
|
|
|
switch target.Type {
|
|
|
|
case engine.Container:
|
|
|
|
return policycontract.Container
|
|
|
|
case engine.User:
|
|
|
|
return 'u'
|
|
|
|
case engine.Group:
|
|
|
|
return 'g'
|
|
|
|
default:
|
|
|
|
return policycontract.Namespace
|
2023-12-08 07:44:13 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-13 08:50:11 +00:00
|
|
|
|
|
|
|
func getBucketPolicyName(cnrID cid.ID) []byte {
|
|
|
|
return append([]byte{bucketPolicyPrefix}, cnrID[:]...)
|
2023-12-08 07:44:13 +00:00
|
|
|
}
|