package router_test import ( "fmt" "testing" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/router" apeSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape" bearerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" "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" resourcetest "git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource/testutil" nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native" "github.com/stretchr/testify/require" ) const ( container = "67ETTZzbzJC6WxdQhHHHsJNCttVMBqYrSoFaUFVDNfiX" rootNs = "" ) var ( allowBySourceIP = &chain.Chain{ Rules: []chain.Rule{ { Status: chain.Allow, Actions: chain.Actions{Names: []string{nativeschema.MethodPutObject}}, Resources: chain.Resources{Names: []string{fmt.Sprintf(nativeschema.ResourceFormatRootContainer, container)}}, Condition: []chain.Condition{ { Op: chain.CondStringEquals, Kind: chain.KindRequest, Key: "SourceIP", Value: "10.122.1.20", }, }, }, }, } denyBySourceIP = &chain.Chain{ Rules: []chain.Rule{ { Status: chain.AccessDenied, Actions: chain.Actions{Names: []string{nativeschema.MethodPutObject}}, Resources: chain.Resources{Names: []string{fmt.Sprintf(nativeschema.ResourceFormatRootContainer, container)}}, Condition: []chain.Condition{ { Op: chain.CondStringEquals, Kind: chain.KindRequest, Key: "SourceIP", Value: "10.122.1.20", }, }, }, }, } ) func TestBearerChainFedRouter(t *testing.T) { t.Run("no bearer token overrides", func(t *testing.T) { inmem := inmemory.NewInMemoryLocalOverrides() inmem.LocalStorage().AddOverride(chain.Ingress, engine.ContainerTarget(container), denyBySourceIP) inmem.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.ContainerTarget(container), allowBySourceIP) _, err := router.BearerChainFeedRouter(inmem.LocalStorage(), inmem.MorphRuleChainStorage(), bearerSDK.APEOverride{}) require.Error(t, err) }) t.Run("allow by container with deny by bearer overrides", func(t *testing.T) { inmem := inmemory.NewInMemoryLocalOverrides() inmem.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.ContainerTarget(container), allowBySourceIP) bt := bearerSDK.APEOverride{ Target: apeSDK.ChainTarget{ TargetType: apeSDK.TargetTypeContainer, Name: container, }, Chains: []apeSDK.Chain{{ Raw: denyBySourceIP.Bytes(), }}, } r, err := router.BearerChainFeedRouter(inmem.LocalStorage(), inmem.MorphRuleChainStorage(), bt) require.NoError(t, err) req := resourcetest.NewRequest(nativeschema.MethodPutObject, resourcetest.NewResource(fmt.Sprintf(nativeschema.ResourceFormatRootContainer, container), map[string]string{}), map[string]string{ "SourceIP": "10.122.1.20", "Actor": "someOwner", }, ) st, found, err := r.IsAllowed(chain.Ingress, engine.NewRequestTarget(rootNs, container), req) require.NoError(t, err) require.True(t, found) require.Equal(t, st, chain.AccessDenied) }) t.Run("allow by namespace with deny by bearer overrides", func(t *testing.T) { inmem := inmemory.NewInMemoryLocalOverrides() inmem.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.ContainerTarget(container), allowBySourceIP) inmem.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.NamespaceTarget(rootNs), allowBySourceIP) bt := bearerSDK.APEOverride{ Target: apeSDK.ChainTarget{ TargetType: apeSDK.TargetTypeContainer, Name: container, }, Chains: []apeSDK.Chain{{ Raw: denyBySourceIP.Bytes(), }}, } r, err := router.BearerChainFeedRouter(inmem.LocalStorage(), inmem.MorphRuleChainStorage(), bt) require.NoError(t, err) req := resourcetest.NewRequest(nativeschema.MethodPutObject, resourcetest.NewResource(fmt.Sprintf(nativeschema.ResourceFormatRootContainer, container), map[string]string{}), map[string]string{ "SourceIP": "10.122.1.20", "Actor": "someOwner", }, ) st, found, err := r.IsAllowed(chain.Ingress, engine.NewRequestTarget(rootNs, container), req) require.NoError(t, err) require.True(t, found) require.Equal(t, st, chain.AccessDenied) }) t.Run("deny by namespace with allow by bearer overrides", func(t *testing.T) { inmem := inmemory.NewInMemoryLocalOverrides() inmem.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.NamespaceTarget(rootNs), denyBySourceIP) bt := bearerSDK.APEOverride{ Target: apeSDK.ChainTarget{ TargetType: apeSDK.TargetTypeContainer, Name: container, }, Chains: []apeSDK.Chain{{ Raw: allowBySourceIP.Bytes(), }}, } r, err := router.BearerChainFeedRouter(inmem.LocalStorage(), inmem.MorphRuleChainStorage(), bt) require.NoError(t, err) req := resourcetest.NewRequest(nativeschema.MethodPutObject, resourcetest.NewResource(fmt.Sprintf(nativeschema.ResourceFormatRootContainer, container), map[string]string{}), map[string]string{ "SourceIP": "10.122.1.20", "Actor": "someOwner", }, ) st, found, err := r.IsAllowed(chain.Ingress, engine.NewRequestTarget(rootNs, container), req) require.NoError(t, err) require.True(t, found) require.Equal(t, st, chain.AccessDenied) }) }