diff --git a/pkg/ape/router/single_pass.go b/pkg/ape/router/single_pass.go new file mode 100644 index 000000000..c0c78db76 --- /dev/null +++ b/pkg/ape/router/single_pass.go @@ -0,0 +1,55 @@ +package router + +import ( + "fmt" + + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape" + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" + cidSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" + apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" + "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine" + "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine/inmemory" +) + +func newTarget(ct ape.ChainTarget) (engine.Target, error) { + var target engine.Target + switch ct.TargetType { + case ape.TargetTypeContainer: + var cid cidSDK.ID + err := cid.DecodeString(ct.Name) + if err != nil { + return target, fmt.Errorf("invalid cid format: %s", target.Name) + } + target.Type = engine.Container + case ape.TargetTypeGroup: + target.Type = engine.Group + case ape.TargetTypeNamespace: + target.Type = engine.Namespace + case ape.TargetTypeUser: + target.Type = engine.User + default: + return target, fmt.Errorf("unsupported target type: %v", ct.TargetType) + } + target.Name = ct.Name + return target, nil +} + +// SingleUseRouterWithBearerTokenChains creates chain router with inmemory storage implementation and +// fed with APE chains defined in Bearer token. +func SingleUseRouterWithBearerTokenChains(overrides []bearer.APEOverride) (engine.ChainRouter, error) { + storage := inmemory.NewInmemoryMorphRuleChainStorage() + for _, override := range overrides { + target, err := newTarget(override.Target) + if err != nil { + return nil, err + } + for i := range override.Chains { + chain := new(apechain.Chain) + if err := chain.DecodeBytes(override.Chains[i].Raw); err != nil { + return nil, fmt.Errorf("invalid ape chain: %w", err) + } + _, _, _ = storage.AddMorphRuleChain(apechain.Ingress, target, chain) + } + } + return engine.NewDefaultChainRouter(storage), nil +}