Skip to content

Commit

Permalink
cli/util: Refactor eACL parser
Browse files Browse the repository at this point in the history
New ops are coming, with this it'll be easier to change the code. Also
add unit tests.

Refs #2730.

Signed-off-by: Leonard Lyubich <[email protected]>
  • Loading branch information
cthulhu-rider committed Feb 15, 2024
1 parent ef8dbe6 commit 691d385
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 16 deletions.
41 changes: 25 additions & 16 deletions cmd/neofs-cli/modules/util/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,24 +235,11 @@ func parseEACLRecord(args []string) (*eacl.Record, error) {
return nil, fmt.Errorf("invalid filter or target: %s", args[i])
}

i := strings.Index(ss[1], "=")
if i < 0 {
return nil, fmt.Errorf("invalid filter key-value pair: %s", ss[1])
key, value, op, err := parseKVWithOp(ss[1])
if err != nil {
return nil, fmt.Errorf("invalid filter key-value pair %s: %w", ss[1], err)
}

var key, value string
var op eacl.Match

if 0 < i && ss[1][i-1] == '!' {
key = ss[1][:i-1]
op = eacl.MatchStringNotEqual
} else {
key = ss[1][:i]
op = eacl.MatchStringEqual
}

value = ss[1][i+1:]

typ := eacl.HeaderFromRequest
if ss[0] == "obj" {
typ = eacl.HeaderFromObject
Expand Down Expand Up @@ -288,6 +275,28 @@ func parseEACLRecord(args []string) (*eacl.Record, error) {
return r, nil
}

func parseKVWithOp(s string) (string, string, eacl.Match, error) {
i := strings.Index(s, "=")
if i < 0 {
return "", "", 0, errors.New("missing op")
}

var key, value string
var op eacl.Match

if 0 < i && s[i-1] == '!' {
key = s[:i-1]
op = eacl.MatchStringNotEqual
} else {
key = s[:i]
op = eacl.MatchStringEqual
}

value = s[i+1:]

return key, value, op, nil
}

// eaclRoleFromString parses eacl.Role from string.
func eaclRoleFromString(s string) (eacl.Role, error) {
var r eacl.Role
Expand Down
70 changes: 70 additions & 0 deletions cmd/neofs-cli/modules/util/acl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package util

import (
"testing"

"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/stretchr/testify/require"
)

func TestParseKVWithOp(t *testing.T) {
for _, tc := range []struct {
s string
k string
op eacl.Match
v string
}{
{"=", "", eacl.MatchStringEqual, ""},
{"!=", "", eacl.MatchStringNotEqual, ""},
{">=", ">", eacl.MatchStringEqual, ""},
{"=>", "", eacl.MatchStringEqual, ">"},
{"<=", "<", eacl.MatchStringEqual, ""},
{"=<", "", eacl.MatchStringEqual, "<"},
{"key=", "key", eacl.MatchStringEqual, ""},
{"key>=", "key>", eacl.MatchStringEqual, ""},
{"key<=", "key<", eacl.MatchStringEqual, ""},
{"=value", "", eacl.MatchStringEqual, "value"},
{"!=value", "", eacl.MatchStringNotEqual, "value"},
{"key=value", "key", eacl.MatchStringEqual, "value"},
{"key==value", "key", eacl.MatchStringEqual, "=value"},
{"key=>value", "key", eacl.MatchStringEqual, ">value"},
{"key>=value", "key>", eacl.MatchStringEqual, "value"},
{"key<=value", "key<", eacl.MatchStringEqual, "value"},
{"key=<value", "key", eacl.MatchStringEqual, "<value"},
{"key!=value", "key", eacl.MatchStringNotEqual, "value"},
{"key=!value", "key", eacl.MatchStringEqual, "!value"},
{"key!=!value", "key", eacl.MatchStringNotEqual, "!value"},
{"key!!=value", "key!", eacl.MatchStringNotEqual, "value"},
{"key!=!=value", "key", eacl.MatchStringNotEqual, "!=value"},
{"key=value=42", "key", eacl.MatchStringEqual, "value=42"},
{"key!=value!=42", "key", eacl.MatchStringNotEqual, "value!=42"},
{"k e y = v a l u e", "k e y ", eacl.MatchStringEqual, " v a l u e"},
{"k e y != v a l u e", "k e y ", eacl.MatchStringNotEqual, " v a l u e"},
} {
k, v, op, err := parseKVWithOp(tc.s)
require.NoError(t, err, tc)
require.Equal(t, tc.k, k, tc)
require.Equal(t, tc.v, v, tc)
require.Equal(t, tc.op, op, tc)
}

for _, tc := range []struct {
s string
e string
}{
{"", "missing op"},
{"!", "missing op"},
{">", "missing op"},
{"<", "missing op"},
{"k", "missing op"},
{"k!", "missing op"},
{"k>", "missing op"},
{"k<", "missing op"},
{"k!v", "missing op"},
{"k<v", "missing op"},
{"k>v", "missing op"},
} {
_, _, _, err := parseKVWithOp(tc.s)
require.ErrorContains(t, err, tc.e, tc)
}
}

0 comments on commit 691d385

Please sign in to comment.