Airat Arifullin
47bcd346d3
* Unlike default chain router, `BearerChainFedRouter` performs checks for overrides defined in the bearer token; * Add unit-test for the introduced router. Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>
165 lines
5.3 KiB
Go
165 lines
5.3 KiB
Go
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)
|
|
})
|
|
}
|