[#243] eacl: Return success flag in CalculateAction

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-05-18 14:46:28 +03:00 committed by fyrchik
parent 031eac2f48
commit 5518b63432
2 changed files with 37 additions and 22 deletions

View file

@ -21,8 +21,11 @@ func NewValidator() *Validator {
// The action is calculated according to the application of // The action is calculated according to the application of
// eACL table of rules to the request. // eACL table of rules to the request.
// //
// If no matching table entry is found, ActionAllow is returned. // Second return value is true iff the action was produced by a matching entry.
func (v *Validator) CalculateAction(unit *ValidationUnit) Action { //
// If no matching table entry is found or some filters are missing,
// ActionAllow is returned and the second return value is false.
func (v *Validator) CalculateAction(unit *ValidationUnit) (Action, bool) {
for _, record := range unit.table.Records() { for _, record := range unit.table.Records() {
// check type of operation // check type of operation
if record.Operation() != unit.op { if record.Operation() != unit.op {
@ -38,13 +41,13 @@ func (v *Validator) CalculateAction(unit *ValidationUnit) Action {
switch val := matchFilters(unit.hdrSrc, record.Filters()); { switch val := matchFilters(unit.hdrSrc, record.Filters()); {
case val < 0: case val < 0:
// headers of some type could not be composed => allow // headers of some type could not be composed => allow
return ActionAllow return ActionAllow, false
case val == 0: case val == 0:
return record.Action() return record.Action(), true
} }
} }
return ActionAllow return ActionAllow, false
} }
// returns: // returns:

View file

@ -7,6 +7,18 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func checkAction(t *testing.T, expected Action, v *Validator, vu *ValidationUnit) {
action, ok := v.CalculateAction(vu)
require.True(t, ok)
require.Equal(t, expected, action)
}
func checkDefaultAction(t *testing.T, v *Validator, vu *ValidationUnit) {
action, ok := v.CalculateAction(vu)
require.False(t, ok)
require.Equal(t, ActionAllow, action)
}
func TestFilterMatch(t *testing.T) { func TestFilterMatch(t *testing.T) {
tgt := *NewTarget() tgt := *NewTarget()
tgt.SetRole(RoleOthers) tgt.SetRole(RoleOthers)
@ -29,20 +41,20 @@ func TestFilterMatch(t *testing.T) {
hs := headers{} hs := headers{}
vu.hdrSrc = &hs vu.hdrSrc = &hs
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkAction(t, ActionAllow, v, vu)
hs.obj = makeHeaders("b", "yyy") hs.obj = makeHeaders("b", "yyy")
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkAction(t, ActionAllow, v, vu)
hs.obj = makeHeaders("a", "xxx") hs.obj = makeHeaders("a", "xxx")
require.Equal(t, ActionDeny, v.CalculateAction(vu)) checkAction(t, ActionDeny, v, vu)
hs.obj = nil hs.obj = nil
hs.req = makeHeaders("b", "yyy") hs.req = makeHeaders("b", "yyy")
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkAction(t, ActionAllow, v, vu)
hs.req = makeHeaders("b", "abc") hs.req = makeHeaders("b", "abc")
require.Equal(t, ActionDeny, v.CalculateAction(vu)) checkAction(t, ActionDeny, v, vu)
}) })
t.Run("all filters must match", func(t *testing.T) { t.Run("all filters must match", func(t *testing.T) {
@ -59,13 +71,13 @@ func TestFilterMatch(t *testing.T) {
vu.hdrSrc = &hs vu.hdrSrc = &hs
hs.obj = makeHeaders("a", "xxx") hs.obj = makeHeaders("a", "xxx")
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkAction(t, ActionAllow, v, vu)
hs.req = makeHeaders("b", "yyy") hs.req = makeHeaders("b", "yyy")
require.Equal(t, ActionDeny, v.CalculateAction(vu)) checkAction(t, ActionDeny, v, vu)
hs.obj = nil hs.obj = nil
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkAction(t, ActionAllow, v, vu)
}) })
t.Run("filters with unknown type are skipped", func(t *testing.T) { t.Run("filters with unknown type are skipped", func(t *testing.T) {
@ -85,14 +97,14 @@ func TestFilterMatch(t *testing.T) {
hs := headers{} hs := headers{}
vu.hdrSrc = &hs vu.hdrSrc = &hs
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkDefaultAction(t, v, vu)
hs.obj = makeHeaders("a", "xxx") hs.obj = makeHeaders("a", "xxx")
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkDefaultAction(t, v, vu)
hs.obj = nil hs.obj = nil
hs.req = makeHeaders("b", "yyy") hs.req = makeHeaders("b", "yyy")
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkDefaultAction(t, v, vu)
}) })
t.Run("filters with match function are skipped", func(t *testing.T) { t.Run("filters with match function are skipped", func(t *testing.T) {
@ -107,10 +119,10 @@ func TestFilterMatch(t *testing.T) {
hs := headers{} hs := headers{}
vu.hdrSrc = &hs vu.hdrSrc = &hs
require.Equal(t, ActionDeny, v.CalculateAction(vu)) checkAction(t, ActionDeny, v, vu)
hs.obj = makeHeaders("a", "xxx") hs.obj = makeHeaders("a", "xxx")
require.Equal(t, ActionDeny, v.CalculateAction(vu)) checkAction(t, ActionDeny, v, vu)
}) })
} }
@ -127,10 +139,10 @@ func TestOperationMatch(t *testing.T) {
vu := newValidationUnit(RoleOthers, nil, tb) vu := newValidationUnit(RoleOthers, nil, tb)
vu.op = OperationPut vu.op = OperationPut
require.Equal(t, ActionDeny, v.CalculateAction(vu)) checkAction(t, ActionDeny, v, vu)
vu.op = OperationGet vu.op = OperationGet
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkAction(t, ActionAllow, v, vu)
}) })
t.Run("unknown operation", func(t *testing.T) { t.Run("unknown operation", func(t *testing.T) {
@ -143,10 +155,10 @@ func TestOperationMatch(t *testing.T) {
// TODO discuss if both next tests should result in DENY // TODO discuss if both next tests should result in DENY
vu.op = OperationPut vu.op = OperationPut
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkDefaultAction(t, v, vu)
vu.op = OperationGet vu.op = OperationGet
require.Equal(t, ActionAllow, v.CalculateAction(vu)) checkAction(t, ActionAllow, v, vu)
}) })
} }