generated from TrueCloudLab/basic
WIP: chain: Introduce new condition operations #93
4 changed files with 405 additions and 24 deletions
|
@ -111,6 +111,20 @@ const (
|
|||
|
||||
CondIPAddress
|
||||
CondNotIPAddress
|
||||
|
||||
CondStringEqualsIfExists
|
||||
CondStringEqualsIgnoreCaseIfExists
|
||||
CondStringLikeIfExists
|
||||
CondStringLessThanIfExists
|
||||
CondStringLessThanEqualsIfExists
|
||||
CondStringGreaterThanIfExists
|
||||
CondStringGreaterThanEqualsIfExists
|
||||
|
||||
CondNumericEqualsIfExists
|
||||
CondNumericLessThanIfExists
|
||||
CondNumericLessThanEqualsIfExists
|
||||
CondNumericGreaterThanIfExists
|
||||
CondNumericGreaterThanEqualsIfExists
|
||||
)
|
||||
|
||||
var condToStr = []struct {
|
||||
|
@ -127,12 +141,24 @@ var condToStr = []struct {
|
|||
{CondStringLessThanEquals, "StringLessThanEquals"},
|
||||
{CondStringGreaterThan, "StringGreaterThan"},
|
||||
{CondStringGreaterThanEquals, "StringGreaterThanEquals"},
|
||||
{CondStringEqualsIfExists, "StringEqualsIfExists"},
|
||||
{CondStringEqualsIgnoreCaseIfExists, "StringEqualsIgnoreCaseIfExists"},
|
||||
{CondStringLikeIfExists, "StringLikeIfExists"},
|
||||
{CondStringLessThanIfExists, "StringLessThanIfExists"},
|
||||
{CondStringLessThanEqualsIfExists, "StringLessThanEqualsIfExists"},
|
||||
{CondStringGreaterThanIfExists, "StringGreaterThanIfExists"},
|
||||
{CondStringGreaterThanEqualsIfExists, "StringGreaterThanEqualsIfExists"},
|
||||
{CondNumericEquals, "NumericEquals"},
|
||||
{CondNumericNotEquals, "NumericNotEquals"},
|
||||
{CondNumericLessThan, "NumericLessThan"},
|
||||
{CondNumericLessThanEquals, "NumericLessThanEquals"},
|
||||
{CondNumericGreaterThan, "NumericGreaterThan"},
|
||||
{CondNumericGreaterThanEquals, "NumericGreaterThanEquals"},
|
||||
{CondNumericEqualsIfExists, "NumericEqualsIfExists"},
|
||||
{CondNumericLessThanIfExists, "NumericLessThanIfExists"},
|
||||
{CondNumericLessThanEqualsIfExists, "NumericLessThanEqualsIfExists"},
|
||||
{CondNumericGreaterThanIfExists, "NumericGreaterThanIfExists"},
|
||||
{CondNumericGreaterThanEqualsIfExists, "NumericGreaterThanEqualsIfExists"},
|
||||
{CondSliceContains, "SliceContains"},
|
||||
{CondIPAddress, "IPAddress"},
|
||||
{CondNotIPAddress, "NotIPAddress"},
|
||||
|
@ -157,11 +183,12 @@ func FormCondSliceContainsValue(values []string) string {
|
|||
|
||||
func (c *Condition) Match(req resource.Request) bool {
|
||||
var val string
|
||||
var exists bool
|
||||
switch c.Kind {
|
||||
case KindResource:
|
||||
val = req.Resource().Property(c.Key)
|
||||
val, exists = req.Resource().Property(c.Key)
|
||||
case KindRequest:
|
||||
val = req.Property(c.Key)
|
||||
val, exists = req.Property(c.Key)
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown condition type: %d", c.Kind))
|
||||
}
|
||||
|
@ -170,30 +197,47 @@ func (c *Condition) Match(req resource.Request) bool {
|
|||
default:
|
||||
panic(fmt.Sprintf("unimplemented: %d", c.Op))
|
||||
case CondStringEquals:
|
||||
return val == c.Value
|
||||
return exists && val == c.Value
|
||||
|
||||
case CondStringEqualsIfExists:
|
||||
return !exists || val == c.Value
|
||||
case CondStringNotEquals:
|
||||
return val != c.Value
|
||||
return exists && val != c.Value
|
||||
fyrchik
commented
Why have you changed this? Why have you changed this?
aarifullin
commented
The reason why this PR has been created: The [reason](https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/1406#issuecomment-53462) why this PR has been created:
`CondStringNotEquals` works out even key **is not** present (`"" != value -> true) - and we don't want this complicating behavior. If we don't need these changes, then the PR is not needed at all and policy must explicitly specify that a value (got by a key) can't be empty
fyrchik
commented
We need this change for positive conditions, not the negative ones. We need this change for positive conditions, not the negative ones.
As you can see below, negative conditions are handled differently.
aarifullin
commented
Oh, sorry! I misunderstood this - have been keeping the idea about Oh, sorry! I misunderstood this - have been keeping the idea about `...IfExists` operators in my mind
|
||||
case CondStringEqualsIgnoreCase:
|
||||
return strings.EqualFold(val, c.Value)
|
||||
return exists && strings.EqualFold(val, c.Value)
|
||||
case CondStringEqualsIgnoreCaseIfExists:
|
||||
return !exists || strings.EqualFold(val, c.Value)
|
||||
case CondStringNotEqualsIgnoreCase:
|
||||
return !strings.EqualFold(val, c.Value)
|
||||
return exists && !strings.EqualFold(val, c.Value)
|
||||
case CondStringLike:
|
||||
return util.GlobMatch(val, c.Value)
|
||||
return exists && util.GlobMatch(val, c.Value)
|
||||
case CondStringLikeIfExists:
|
||||
return !exists || util.GlobMatch(val, c.Value)
|
||||
case CondStringNotLike:
|
||||
return !util.GlobMatch(val, c.Value)
|
||||
return exists && !util.GlobMatch(val, c.Value)
|
||||
case CondStringLessThan:
|
||||
return val < c.Value
|
||||
return exists && val < c.Value
|
||||
case CondStringLessThanIfExists:
|
||||
return !exists || val < c.Value
|
||||
case CondStringLessThanEquals:
|
||||
return val <= c.Value
|
||||
return exists && val <= c.Value
|
||||
case CondStringLessThanEqualsIfExists:
|
||||
return !exists || val <= c.Value
|
||||
case CondStringGreaterThan:
|
||||
return val > c.Value
|
||||
return exists && val > c.Value
|
||||
case CondStringGreaterThanIfExists:
|
||||
return !exists || val > c.Value
|
||||
case CondStringGreaterThanEquals:
|
||||
return val >= c.Value
|
||||
return exists && val >= c.Value
|
||||
case CondStringGreaterThanEqualsIfExists:
|
||||
return !exists || val >= c.Value
|
||||
case CondSliceContains:
|
||||
return slices.Contains(strings.Split(val, condSliceContainsDelimiter), c.Value)
|
||||
case CondNumericEquals, CondNumericNotEquals, CondNumericLessThan, CondNumericLessThanEquals, CondNumericGreaterThan,
|
||||
CondNumericGreaterThanEquals:
|
||||
return c.matchNumeric(val)
|
||||
return exists && c.matchNumeric(val)
|
||||
case CondNumericEqualsIfExists, CondNumericLessThanIfExists, CondNumericLessThanEqualsIfExists, CondNumericGreaterThanIfExists,
|
||||
CondNumericGreaterThanEqualsIfExists:
|
||||
return !exists || c.matchNumeric(val)
|
||||
case CondIPAddress, CondNotIPAddress:
|
||||
return c.matchIP(val)
|
||||
}
|
||||
|
@ -213,17 +257,17 @@ func (c *Condition) matchNumeric(val string) bool {
|
|||
switch c.Op {
|
||||
default:
|
||||
panic(fmt.Sprintf("unimplemented: %d", c.Op))
|
||||
case CondNumericEquals:
|
||||
case CondNumericEquals, CondNumericEqualsIfExists:
|
||||
return valDecimal.Equal(condVal)
|
||||
case CondNumericNotEquals:
|
||||
return !valDecimal.Equal(condVal)
|
||||
case CondNumericLessThan:
|
||||
case CondNumericLessThan, CondNumericLessThanIfExists:
|
||||
return valDecimal.LessThan(condVal)
|
||||
case CondNumericLessThanEquals:
|
||||
case CondNumericLessThanEquals, CondNumericLessThanEqualsIfExists:
|
||||
return valDecimal.LessThan(condVal) || valDecimal.Equal(condVal)
|
||||
case CondNumericGreaterThan:
|
||||
case CondNumericGreaterThan, CondNumericGreaterThanIfExists:
|
||||
return valDecimal.GreaterThan(condVal)
|
||||
case CondNumericGreaterThanEquals:
|
||||
case CondNumericGreaterThanEquals, CondNumericGreaterThanEqualsIfExists:
|
||||
return valDecimal.GreaterThan(condVal) || valDecimal.Equal(condVal)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -398,6 +398,25 @@ func testNumericConditionsMatch(t *testing.T) {
|
|||
value: "50",
|
||||
status: Allow,
|
||||
},
|
||||
{
|
||||
name: "value if exists from interval",
|
||||
conditions: []Condition{
|
||||
{
|
||||
Op: CondNumericLessThanIfExists,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: "100",
|
||||
},
|
||||
{
|
||||
Op: CondNumericGreaterThanIfExists,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: "80",
|
||||
},
|
||||
},
|
||||
value: "90",
|
||||
status: Allow,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
|
||||
|
@ -411,6 +430,16 @@ func testNumericConditionsMatch(t *testing.T) {
|
|||
}}}
|
||||
st, _ := ch.Match(request)
|
||||
require.Equal(t, tc.status.String(), st.String())
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found := ch.Match(emptyPropsRequest)
|
||||
if strings.HasSuffix(tc.conditions[0].Op.String(), "IfExists") {
|
||||
require.True(t, found)
|
||||
require.Equal(t, tc.status.String(), st.String())
|
||||
} else {
|
||||
require.False(t, found)
|
||||
require.Equal(t, st, NoRuleFound)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -448,6 +477,47 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
_, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringEqualsIfExists.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: CondStringEqualsIfExists,
|
||||
Kind: KindRequest,
|
||||
Key: propKey,
|
||||
Value: val,
|
||||
}},
|
||||
}}}
|
||||
|
||||
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)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringNotEquals.String(), func(t *testing.T) {
|
||||
|
@ -479,6 +549,11 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
_, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringEqualsIgnoreCase.String(), func(t *testing.T) {
|
||||
|
@ -510,6 +585,47 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
_, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringEqualsIgnoreCaseIfExists.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: CondStringEqualsIgnoreCaseIfExists,
|
||||
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)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringNotEqualsIgnoreCase.String(), func(t *testing.T) {
|
||||
|
@ -541,6 +657,11 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLike.String(), func(t *testing.T) {
|
||||
|
@ -572,6 +693,47 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLikeIfExists.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: CondStringLikeIfExists,
|
||||
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)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringNotLike.String(), func(t *testing.T) {
|
||||
|
@ -603,6 +765,11 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLessThan.String(), func(t *testing.T) {
|
||||
|
@ -634,6 +801,47 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLessThanIfExists.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: CondStringLessThanIfExists,
|
||||
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)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLessThanEquals.String(), func(t *testing.T) {
|
||||
|
@ -665,6 +873,47 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringLessThanEqualsIfExists.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: CondStringLessThanEqualsIfExists,
|
||||
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)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringGreaterThan.String(), func(t *testing.T) {
|
||||
|
@ -696,6 +945,47 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringGreaterThanIfExists.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: CondStringGreaterThanIfExists,
|
||||
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)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringGreaterThanEquals.String(), func(t *testing.T) {
|
||||
|
@ -727,6 +1017,47 @@ func testStringConiditionsMatch(t *testing.T) {
|
|||
st, found = ch.Match(request)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.False(t, found)
|
||||
require.Equal(t, NoRuleFound, st)
|
||||
})
|
||||
|
||||
t.Run(CondStringGreaterThanEqualsIfExists.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: CondStringGreaterThanEqualsIfExists,
|
||||
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)
|
||||
|
||||
emptyPropsRequest := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{})
|
||||
st, found = ch.Match(emptyPropsRequest)
|
||||
require.True(t, found)
|
||||
require.Equal(t, Allow, st)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,17 @@ type Request interface {
|
|||
// Name is the operation name, such as Object.Put. Must not include wildcards.
|
||||
Operation() string
|
||||
// Property returns request properties, such as IP address of the origin.
|
||||
Property(string) string
|
||||
// The second return boolean value determines if the specified value exists within the properties.
|
||||
Property(string) (string, bool)
|
||||
// Resource returns resource the operation is applied to.
|
||||
Resource() Resource
|
||||
}
|
||||
|
||||
// Resource represents the resource operation is applied to.
|
||||
type Resource interface {
|
||||
// Name is the resource name.
|
||||
Name() string
|
||||
Property(string) string
|
||||
// Property returns resource properties, such as object type etc.
|
||||
// The second return boolean value determines if the specified value exists within the properties.
|
||||
Property(string) (string, bool)
|
||||
}
|
||||
|
|
|
@ -13,8 +13,9 @@ func (r *Resource) Name() string {
|
|||
return r.name
|
||||
}
|
||||
|
||||
func (r *Resource) Property(name string) string {
|
||||
return r.properties[name]
|
||||
func (r *Resource) Property(name string) (val string, exists bool) {
|
||||
val, exists = r.properties[name]
|
||||
return
|
||||
}
|
||||
|
||||
func NewResource(name string, properties map[string]string) *Resource {
|
||||
|
@ -40,8 +41,9 @@ func (r *Request) Resource() resourcepkg.Resource {
|
|||
return r.resource
|
||||
}
|
||||
|
||||
func (r *Request) Property(name string) string {
|
||||
return r.properties[name]
|
||||
func (r *Request) Property(name string) (val string, exists bool) {
|
||||
val, exists = r.properties[name]
|
||||
return
|
||||
}
|
||||
|
||||
func NewRequest(op string, r *Resource, properties map[string]string) *Request {
|
||||
|
|
Loading…
Reference in a new issue
Why do we change this?
#93 (comment)