generated from TrueCloudLab/basic
[#76] chain: Increase unit-test coverage for chain related types
All checks were successful
DCO action / DCO (pull_request) Successful in 1m8s
Tests and linters / Tests (1.20) (pull_request) Successful in 1m22s
Tests and linters / Tests (1.21) (pull_request) Successful in 1m17s
Tests and linters / Staticcheck (pull_request) Successful in 1m31s
Tests and linters / Tests with -race (pull_request) Successful in 1m43s
Tests and linters / Lint (pull_request) Successful in 2m17s
All checks were successful
DCO action / DCO (pull_request) Successful in 1m8s
Tests and linters / Tests (1.20) (pull_request) Successful in 1m22s
Tests and linters / Tests (1.21) (pull_request) Successful in 1m17s
Tests and linters / Staticcheck (pull_request) Successful in 1m31s
Tests and linters / Tests with -race (pull_request) Successful in 1m43s
Tests and linters / Lint (pull_request) Successful in 2m17s
* Add more unit-test cases. Signed-off-by: Airat Arifullin <aarifullin@yadro.com>
This commit is contained in:
parent
1f6f4163d4
commit
d7ed188f68
1 changed files with 795 additions and 54 deletions
|
@ -1,6 +1,8 @@
|
|||
package chain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource/testutil"
|
||||
|
@ -50,7 +52,7 @@ func TestEncodeDecode(t *testing.T) {
|
|||
require.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestReturnFirstMatch(t *testing.T) {
|
||||
func TestChainMatch(t *testing.T) {
|
||||
ch := Chain{
|
||||
Rules: []Rule{
|
||||
{
|
||||
|
@ -87,9 +89,195 @@ func TestReturnFirstMatch(t *testing.T) {
|
|||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run("unknown match", func(t *testing.T) {
|
||||
ch.MatchType = MatchType(255)
|
||||
request := testutil.NewRequest(native.MethodGetObject, resource, nil)
|
||||
require.PanicsWithValue(t, "unknown MatchType 255", func() {
|
||||
ch.Match(request)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("no rule found", func(t *testing.T) {
|
||||
ch.MatchType = MatchTypeFirstMatch
|
||||
request := testutil.NewRequest(native.MethodGetObject, resource, nil)
|
||||
st, found := ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
}
|
||||
|
||||
func TestCondSliceContainsMatch(t *testing.T) {
|
||||
func TestAnyAllConditionMatch(t *testing.T) {
|
||||
ch := Chain{
|
||||
Rules: []Rule{
|
||||
{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{
|
||||
{
|
||||
Op: CondIPAddress,
|
||||
Kind: KindRequest,
|
||||
Key: common.PropertyKeyFrostFSSourceIP,
|
||||
Value: "192.92.1.1/20",
|
||||
},
|
||||
{
|
||||
Op: CondStringEquals,
|
||||
Kind: KindRequest,
|
||||
Key: native.PropertyKeyActorRole,
|
||||
Value: "owner",
|
||||
},
|
||||
{
|
||||
Op: CondStringEquals,
|
||||
Kind: KindResource,
|
||||
Key: native.PropertyKeyObjectID,
|
||||
Value: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
t.Run("match by all conditions", func(t *testing.T) {
|
||||
ch.Rules[0].Any = false
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{
|
||||
native.PropertyKeyObjectID: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
|
||||
})
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
native.PropertyKeyActorRole: "owner",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run("match by any condition", func(t *testing.T) {
|
||||
ch.Rules[0].Any = true
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{
|
||||
native.PropertyKeyObjectID: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
|
||||
})
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, nil)
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
native.PropertyKeyActorRole: "owner",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
resource = testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{})
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
}
|
||||
|
||||
func TestConditionMatch(t *testing.T) {
|
||||
t.Run("condition types", func(t *testing.T) {
|
||||
t.Run("slice condition type", testCondSliceContainsMatch)
|
||||
t.Run("numeric condition types", testNumericConditionsMatch)
|
||||
t.Run("string condition types", testStringConiditionsMatch)
|
||||
t.Run("ip conidition types", testIPConditionMatch)
|
||||
t.Run("unknown condition type", func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: ConditionType(255),
|
||||
Kind: KindRequest,
|
||||
Key: common.PropertyKeyFrostFSSourceIP,
|
||||
Value: "192.92.1.1/20",
|
||||
}},
|
||||
}}}
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{
|
||||
native.PropertyKeyObjectID: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
|
||||
})
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
native.PropertyKeyActorRole: "owner",
|
||||
})
|
||||
require.PanicsWithValue(t, "unimplemented: 255", func() {
|
||||
ch.Match(request)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("kind", func(t *testing.T) {
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{
|
||||
native.PropertyKeyObjectID: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
|
||||
})
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
native.PropertyKeyActorRole: "owner",
|
||||
})
|
||||
|
||||
t.Run("resource", func(t *testing.T) {
|
||||
cond := Condition{
|
||||
Op: CondStringEquals,
|
||||
Kind: KindResource,
|
||||
Key: native.PropertyKeyObjectID,
|
||||
Value: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
|
||||
}
|
||||
|
||||
found := cond.Match(request)
|
||||
require.True(t, found)
|
||||
})
|
||||
t.Run("request", func(t *testing.T) {
|
||||
cond := Condition{
|
||||
Op: CondStringEquals,
|
||||
Kind: KindRequest,
|
||||
Key: native.PropertyKeyActorRole,
|
||||
Value: "owner",
|
||||
}
|
||||
|
||||
found := cond.Match(request)
|
||||
require.True(t, found)
|
||||
})
|
||||
t.Run("unknown", func(t *testing.T) {
|
||||
cond := Condition{
|
||||
Op: CondStringEquals,
|
||||
Kind: ConditionKindType(255),
|
||||
Key: native.PropertyKeyActorRole,
|
||||
Value: "owner",
|
||||
}
|
||||
|
||||
require.PanicsWithValue(t, "unknown condition type: 255", func() {
|
||||
cond.Match(request)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func testCondSliceContainsMatch(t *testing.T) {
|
||||
propKey := common.PropertyKeyFrostFSIDGroupID
|
||||
groupID := "1"
|
||||
|
||||
|
@ -151,7 +339,7 @@ func TestCondSliceContainsMatch(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNumericConditionsMatch(t *testing.T) {
|
||||
func testNumericConditionsMatch(t *testing.T) {
|
||||
propKey := s3.PropertyKeyMaxKeys
|
||||
|
||||
for _, tc := range []struct {
|
||||
|
@ -227,61 +415,614 @@ func TestNumericConditionsMatch(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestInvalidNumericValues(t *testing.T) {
|
||||
propKey := s3.PropertyKeyMaxKeys
|
||||
propValues := []string{"", "invalid"}
|
||||
func testStringConiditionsMatch(t *testing.T) {
|
||||
propKey := fmt.Sprintf(common.PropertyKeyFormatFrostFSIDUserClaim, "some-tag")
|
||||
val := "tag-value"
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
conditionType ConditionType
|
||||
match bool
|
||||
}{
|
||||
{
|
||||
name: "NumericEquals condition",
|
||||
conditionType: CondNumericEquals,
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "NumericNotEquals condition",
|
||||
conditionType: CondNumericNotEquals,
|
||||
match: true,
|
||||
},
|
||||
{
|
||||
name: "NumericLessThan condition",
|
||||
conditionType: CondNumericLessThan,
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "NumericLessThanEquals condition",
|
||||
conditionType: CondNumericLessThanEquals,
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "NumericGreaterThan condition",
|
||||
conditionType: CondNumericGreaterThan,
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "NumericGreaterThanEquals condition",
|
||||
conditionType: CondNumericGreaterThanEquals,
|
||||
match: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
condition := Condition{
|
||||
Op: tc.conditionType,
|
||||
t.Run(CondStringEquals.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringEquals,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: "50",
|
||||
}
|
||||
Value: val,
|
||||
}},
|
||||
}}}
|
||||
|
||||
for _, propValue := range propValues {
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{propKey: propValue})
|
||||
|
||||
match := condition.Match(request)
|
||||
require.Equal(t, tc.match, match)
|
||||
}
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val,
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: "distort_tag_value" + val,
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringNotEquals.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringNotEquals,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val,
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: "distort_tag_value" + val,
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val,
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringEqualsIgnoreCase.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringEqualsIgnoreCase,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val,
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: strings.ToUpper(val),
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: strings.ToUpper("distort_tag_value" + val),
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringNotEqualsIgnoreCase.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringNotEqualsIgnoreCase,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val,
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: strings.ToUpper("distort_tag_value" + val),
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: strings.ToUpper(val),
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLike.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringLike,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val + "*",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "suffix",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: string([]byte(val)[:len(val)-1]), //cut last letter
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringNotLike.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringNotLike,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: "prefix" + val + "*",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "suffix",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: "prefix" + val,
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLessThan.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringLessThan,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val + "b",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "a",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "c",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLessThanEquals.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringLessThanEquals,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val + "b",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "a",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "b",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringGreaterThan.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringGreaterThan,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val + "b",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "c",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "b",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringGreaterThanEquals.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondStringGreaterThanEquals,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val + "b",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "c",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
propKey: val + "b",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
}
|
||||
|
||||
func testIPConditionMatch(t *testing.T) {
|
||||
t.Run(CondIPAddress.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondIPAddress,
|
||||
Kind: KindRequest,
|
||||
Key: common.PropertyKeyFrostFSSourceIP,
|
||||
Value: "192.92.1.1/20",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondNotIPAddress.String(), func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondNotIPAddress,
|
||||
Kind: KindRequest,
|
||||
Key: common.PropertyKeyFrostFSSourceIP,
|
||||
Value: "192.92.1.1/20",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
})
|
||||
|
||||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run("invalid ip address condition value", func(t *testing.T) {
|
||||
ch := Chain{Rules: []Rule{{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondIPAddress,
|
||||
Kind: KindRequest,
|
||||
Key: common.PropertyKeyFrostFSSourceIP,
|
||||
Value: "192.92.1.1:33333",
|
||||
}},
|
||||
}}}
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
})
|
||||
|
||||
st, found := ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run("match ip", func(t *testing.T) {
|
||||
cond := Condition{
|
||||
Op: CondIPAddress,
|
||||
Kind: KindRequest,
|
||||
Key: common.PropertyKeyFrostFSSourceIP,
|
||||
Value: "192.92.1.1/10",
|
||||
}
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
cond.matchIP("192.92.1.91")
|
||||
})
|
||||
|
||||
require.PanicsWithValue(t, "unimplemented: 10", func() {
|
||||
cond.Op = CondNumericEquals
|
||||
cond.matchIP("192.92.1.91")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestInvalidNumericValues(t *testing.T) {
|
||||
t.Run("invalid request property", func(t *testing.T) {
|
||||
propKey := s3.PropertyKeyMaxKeys
|
||||
propValues := []string{"", "invalid"}
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
conditionType ConditionType
|
||||
match bool
|
||||
}{
|
||||
{
|
||||
name: "NumericEquals condition",
|
||||
conditionType: CondNumericEquals,
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "NumericNotEquals condition",
|
||||
conditionType: CondNumericNotEquals,
|
||||
match: true,
|
||||
},
|
||||
{
|
||||
name: "NumericLessThan condition",
|
||||
conditionType: CondNumericLessThan,
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "NumericLessThanEquals condition",
|
||||
conditionType: CondNumericLessThanEquals,
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "NumericGreaterThan condition",
|
||||
conditionType: CondNumericGreaterThan,
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "NumericGreaterThanEquals condition",
|
||||
conditionType: CondNumericGreaterThanEquals,
|
||||
match: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
condition := Condition{
|
||||
Op: tc.conditionType,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: "50",
|
||||
}
|
||||
|
||||
for _, propValue := range propValues {
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{propKey: propValue})
|
||||
|
||||
match := condition.Match(request)
|
||||
require.Equal(t, tc.match, match)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
t.Run("invalid condition numeric value", func(t *testing.T) {
|
||||
propKey := s3.PropertyKeyMaxKeys
|
||||
|
||||
condition := Condition{
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: "invalid",
|
||||
}
|
||||
|
||||
t.Run("match on CondNumericNotEquals", func(t *testing.T) {
|
||||
condition.Op = CondNumericNotEquals
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{propKey: "50"})
|
||||
|
||||
match := condition.Match(request)
|
||||
require.Equal(t, true, match)
|
||||
})
|
||||
|
||||
t.Run("non-match on non-CondNumericNotEquals", func(t *testing.T) {
|
||||
condition.Op = CondNumericEquals
|
||||
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{propKey: "50"})
|
||||
|
||||
match := condition.Match(request)
|
||||
require.Equal(t, false, match)
|
||||
})
|
||||
|
||||
t.Run("match numeric", func(t *testing.T) {
|
||||
cond := Condition{
|
||||
Op: CondNumericLessThan,
|
||||
Kind: KindRequest,
|
||||
Key: s3.PropertyKeyMaxKeys,
|
||||
Value: "5",
|
||||
}
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
cond.matchNumeric("6")
|
||||
})
|
||||
|
||||
require.PanicsWithValue(t, "unimplemented: 0", func() {
|
||||
cond.Op = CondStringEquals
|
||||
cond.matchNumeric("10")
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestCondTypeStringification(t *testing.T) {
|
||||
for _, pair := range []struct {
|
||||
cond ConditionType
|
||||
expectedString string
|
||||
}{
|
||||
{CondStringEquals, "StringEquals"},
|
||||
{CondStringNotEquals, "StringNotEquals"},
|
||||
{CondStringEqualsIgnoreCase, "StringEqualsIgnoreCase"},
|
||||
{CondStringNotEqualsIgnoreCase, "StringNotEqualsIgnoreCase"},
|
||||
{CondStringLike, "StringLike"},
|
||||
{CondStringNotLike, "StringNotLike"},
|
||||
{CondStringLessThan, "StringLessThan"},
|
||||
{CondStringLessThanEquals, "StringLessThanEquals"},
|
||||
{CondStringGreaterThan, "StringGreaterThan"},
|
||||
{CondStringGreaterThanEquals, "StringGreaterThanEquals"},
|
||||
{CondNumericEquals, "NumericEquals"},
|
||||
{CondNumericNotEquals, "NumericNotEquals"},
|
||||
{CondNumericLessThan, "NumericLessThan"},
|
||||
{CondNumericLessThanEquals, "NumericLessThanEquals"},
|
||||
{CondNumericGreaterThan, "NumericGreaterThan"},
|
||||
{CondNumericGreaterThanEquals, "NumericGreaterThanEquals"},
|
||||
{CondSliceContains, "SliceContains"},
|
||||
{CondIPAddress, "IPAddress"},
|
||||
{CondNotIPAddress, "NotIPAddress"},
|
||||
{ConditionType(255), "unknown condition type"},
|
||||
} {
|
||||
require.Equal(t, pair.expectedString, pair.cond.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRuleMatch(t *testing.T) {
|
||||
rule := Rule{
|
||||
Status: Allow,
|
||||
Actions: Actions{Names: []string{native.MethodPutObject}},
|
||||
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
|
||||
Condition: []Condition{{
|
||||
Op: CondIPAddress,
|
||||
Kind: KindRequest,
|
||||
Key: common.PropertyKeyFrostFSSourceIP,
|
||||
Value: "192.92.1.1/20",
|
||||
}},
|
||||
}
|
||||
|
||||
t.Run("match", func(t *testing.T) {
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
})
|
||||
st, found := rule.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run("not matching resource name", func(t *testing.T) {
|
||||
resource := testutil.NewResource(fmt.Sprintf(native.ResourceFormatNamespaceContainers, "namespicy"), nil)
|
||||
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
})
|
||||
st, found := rule.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run("not matching action", func(t *testing.T) {
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodGetObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
|
||||
})
|
||||
st, found := rule.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run("not matching condition", func(t *testing.T) {
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
request := testutil.NewRequest(native.MethodGetObject, resource, map[string]string{
|
||||
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
|
||||
})
|
||||
st, found := rule.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue