generated from TrueCloudLab/basic
167 lines
4.7 KiB
Go
167 lines
4.7 KiB
Go
|
package policyengine
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func TestInmemory(t *testing.T) {
|
||
|
const (
|
||
|
object = "native::object::abc/xyz"
|
||
|
container = "native::object::abc/*"
|
||
|
namespace = "Tenant1"
|
||
|
actor1 = "owner1"
|
||
|
actor2 = "owner2"
|
||
|
)
|
||
|
|
||
|
s := NewInMemory()
|
||
|
|
||
|
// Object which was put via S3.
|
||
|
res := newResource(object, map[string]string{"FromS3": "true"})
|
||
|
// Request initiating from the trusted subnet and actor.
|
||
|
reqGood := newRequest("native::object::put", res, map[string]string{
|
||
|
"SourceIP": "10.1.1.12",
|
||
|
"Actor": actor1,
|
||
|
})
|
||
|
|
||
|
status, ok := s.IsAllowed(Ingress, namespace, reqGood)
|
||
|
require.Equal(t, NoRuleFound, status)
|
||
|
require.False(t, ok)
|
||
|
|
||
|
s.AddNameSpaceChain(Ingress, namespace, &Chain{
|
||
|
Rules: []Rule{
|
||
|
{ // Restrict to remove ANY object from the namespace.
|
||
|
Status: AccessDenied,
|
||
|
Action: []string{"native::object::delete"},
|
||
|
Resource: []string{"native::object::*"},
|
||
|
},
|
||
|
{ // Allow to put object only from the trusted subnet AND trusted actor, deny otherwise.
|
||
|
Status: AccessDenied,
|
||
|
Action: []string{"native::object::put"},
|
||
|
Resource: []string{"native::object::*"},
|
||
|
Any: true,
|
||
|
Condition: []Condition{
|
||
|
{
|
||
|
Op: CondStringNotLike,
|
||
|
Object: ObjectRequest,
|
||
|
Key: "SourceIP",
|
||
|
Value: "10.1.1.*",
|
||
|
},
|
||
|
{
|
||
|
Op: CondStringNotEquals,
|
||
|
Object: ObjectRequest,
|
||
|
Key: "Actor",
|
||
|
Value: actor1,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
})
|
||
|
|
||
|
s.AddResourceChain(Ingress, container, &Chain{
|
||
|
Rules: []Rule{
|
||
|
{ // Allow to actor2 to get objects from the specific container only if they have `Department=HR` attribute.
|
||
|
Status: Allow,
|
||
|
Action: []string{"native::object::get"},
|
||
|
Resource: []string{"native::object::abc/*"},
|
||
|
Condition: []Condition{
|
||
|
{
|
||
|
Op: CondStringEquals,
|
||
|
Object: ObjectResource,
|
||
|
Key: "Department",
|
||
|
Value: "HR",
|
||
|
},
|
||
|
{
|
||
|
Op: CondStringEquals,
|
||
|
Object: ObjectRequest,
|
||
|
Key: "Actor",
|
||
|
Value: actor2,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
})
|
||
|
|
||
|
t.Run("bad subnet, namespace deny", func(t *testing.T) {
|
||
|
// Request initiating from the untrusted subnet.
|
||
|
reqBadIP := newRequest("native::object::put", res, map[string]string{
|
||
|
"SourceIP": "10.122.1.20",
|
||
|
"Actor": actor1,
|
||
|
})
|
||
|
status, ok := s.IsAllowed(Ingress, namespace, reqBadIP)
|
||
|
require.Equal(t, AccessDenied, status)
|
||
|
require.True(t, ok)
|
||
|
})
|
||
|
t.Run("bad actor, namespace deny", func(t *testing.T) {
|
||
|
// Request initiating from the untrusted actor.
|
||
|
reqBadActor := newRequest("native::object::put", res, map[string]string{
|
||
|
"SourceIP": "10.1.1.13",
|
||
|
"Actor": actor2,
|
||
|
})
|
||
|
status, ok := s.IsAllowed(Ingress, namespace, reqBadActor)
|
||
|
require.Equal(t, AccessDenied, status)
|
||
|
require.True(t, ok)
|
||
|
})
|
||
|
t.Run("bad object, container deny", func(t *testing.T) {
|
||
|
objGood := newResource("native::object::abc/id1", map[string]string{"Department": "HR"})
|
||
|
objBadAttr := newResource("native::object::abc/id2", map[string]string{"Department": "Support"})
|
||
|
|
||
|
status, ok := s.IsAllowed(Ingress, namespace, newRequest("native::object::get", objGood, map[string]string{
|
||
|
"SourceIP": "10.1.1.14",
|
||
|
"Actor": actor2,
|
||
|
}))
|
||
|
require.Equal(t, Allow, status)
|
||
|
require.True(t, ok)
|
||
|
|
||
|
status, ok = s.IsAllowed(Ingress, namespace, newRequest("native::object::get", objBadAttr, map[string]string{
|
||
|
"SourceIP": "10.1.1.14",
|
||
|
"Actor": actor2,
|
||
|
}))
|
||
|
require.Equal(t, NoRuleFound, status)
|
||
|
require.False(t, ok)
|
||
|
})
|
||
|
t.Run("bad operation, namespace deny", func(t *testing.T) {
|
||
|
// Request with the forbidden operation.
|
||
|
reqBadOperation := newRequest("native::object::delete", res, map[string]string{
|
||
|
"SourceIP": "10.1.1.12",
|
||
|
"Actor": actor1,
|
||
|
})
|
||
|
status, ok := s.IsAllowed(Ingress, namespace, reqBadOperation)
|
||
|
require.Equal(t, AccessDenied, status)
|
||
|
require.True(t, ok)
|
||
|
})
|
||
|
t.Run("good", func(t *testing.T) {
|
||
|
status, ok = s.IsAllowed(Ingress, namespace, reqGood)
|
||
|
require.Equal(t, NoRuleFound, status)
|
||
|
require.False(t, ok)
|
||
|
|
||
|
t.Run("quota on a different container", func(t *testing.T) {
|
||
|
s.AddOverride(Ingress, &Chain{
|
||
|
Rules: []Rule{{
|
||
|
Status: QuotaLimitReached,
|
||
|
Action: []string{"native::object::put"},
|
||
|
Resource: []string{"native::object::cba/*"},
|
||
|
}},
|
||
|
})
|
||
|
|
||
|
status, ok = s.IsAllowed(Ingress, namespace, reqGood)
|
||
|
require.Equal(t, NoRuleFound, status)
|
||
|
require.False(t, ok)
|
||
|
})
|
||
|
t.Run("quota on the request container", func(t *testing.T) {
|
||
|
s.AddOverride(Ingress, &Chain{
|
||
|
Rules: []Rule{{
|
||
|
Status: QuotaLimitReached,
|
||
|
Action: []string{"native::object::put"},
|
||
|
Resource: []string{"native::object::abc/*"},
|
||
|
}},
|
||
|
})
|
||
|
|
||
|
status, ok = s.IsAllowed(Ingress, namespace, reqGood)
|
||
|
require.Equal(t, QuotaLimitReached, status)
|
||
|
require.True(t, ok)
|
||
|
})
|
||
|
})
|
||
|
}
|