forked from TrueCloudLab/frostfs-api-go
[#139] sdk/acl: Add test coverage for EACL structures
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
790add6538
commit
d1499e65b9
5 changed files with 334 additions and 2 deletions
117
pkg/acl/eacl/enums_test.go
Normal file
117
pkg/acl/eacl/enums_test.go
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
package eacl_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
||||||
|
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
eqV2Actions = map[eacl.Action]v2acl.Action{
|
||||||
|
eacl.ActionUnknown: v2acl.ActionUnknown,
|
||||||
|
eacl.ActionAllow: v2acl.ActionAllow,
|
||||||
|
eacl.ActionDeny: v2acl.ActionDeny,
|
||||||
|
}
|
||||||
|
|
||||||
|
eqV2Operations = map[eacl.Operation]v2acl.Operation{
|
||||||
|
eacl.OperationUnknown: v2acl.OperationUnknown,
|
||||||
|
eacl.OperationGet: v2acl.OperationGet,
|
||||||
|
eacl.OperationHead: v2acl.OperationHead,
|
||||||
|
eacl.OperationPut: v2acl.OperationPut,
|
||||||
|
eacl.OperationDelete: v2acl.OperationDelete,
|
||||||
|
eacl.OperationSearch: v2acl.OperationSearch,
|
||||||
|
eacl.OperationRange: v2acl.OperationRange,
|
||||||
|
eacl.OperationRangeHash: v2acl.OperationRangeHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
eqV2Roles = map[eacl.Role]v2acl.Role{
|
||||||
|
eacl.RoleUnknown: v2acl.RoleUnknown,
|
||||||
|
eacl.RoleUser: v2acl.RoleUser,
|
||||||
|
eacl.RoleSystem: v2acl.RoleSystem,
|
||||||
|
eacl.RoleOthers: v2acl.RoleOthers,
|
||||||
|
}
|
||||||
|
|
||||||
|
eqV2Matches = map[eacl.Match]v2acl.MatchType{
|
||||||
|
eacl.MatchUnknown: v2acl.MatchTypeUnknown,
|
||||||
|
eacl.MatchStringEqual: v2acl.MatchTypeStringEqual,
|
||||||
|
eacl.MatchStringNotEqual: v2acl.MatchTypeStringNotEqual,
|
||||||
|
}
|
||||||
|
|
||||||
|
eqV2HeaderTypes = map[eacl.FilterHeaderType]v2acl.HeaderType{
|
||||||
|
eacl.HeaderTypeUnknown: v2acl.HeaderTypeUnknown,
|
||||||
|
eacl.HeaderFromRequest: v2acl.HeaderTypeRequest,
|
||||||
|
eacl.HeaderFromObject: v2acl.HeaderTypeObject,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAction(t *testing.T) {
|
||||||
|
t.Run("known actions", func(t *testing.T) {
|
||||||
|
for i := eacl.ActionUnknown; i <= eacl.ActionDeny; i++ {
|
||||||
|
require.Equal(t, eqV2Actions[i], i.ToV2())
|
||||||
|
require.Equal(t, eacl.ActionFromV2(i.ToV2()), i)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("unknown actions", func(t *testing.T) {
|
||||||
|
require.Equal(t, (eacl.ActionDeny + 1).ToV2(), v2acl.ActionUnknown)
|
||||||
|
require.Equal(t, eacl.ActionFromV2(v2acl.ActionDeny+1), eacl.ActionUnknown)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOperation(t *testing.T) {
|
||||||
|
t.Run("known operations", func(t *testing.T) {
|
||||||
|
for i := eacl.OperationUnknown; i <= eacl.OperationRangeHash; i++ {
|
||||||
|
require.Equal(t, eqV2Operations[i], i.ToV2())
|
||||||
|
require.Equal(t, eacl.OperationFromV2(i.ToV2()), i)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("unknown operations", func(t *testing.T) {
|
||||||
|
require.Equal(t, (eacl.OperationRangeHash + 1).ToV2(), v2acl.OperationUnknown)
|
||||||
|
require.Equal(t, eacl.OperationFromV2(v2acl.OperationRangeHash+1), eacl.OperationUnknown)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRole(t *testing.T) {
|
||||||
|
t.Run("known roles", func(t *testing.T) {
|
||||||
|
for i := eacl.RoleUnknown; i <= eacl.RoleOthers; i++ {
|
||||||
|
require.Equal(t, eqV2Roles[i], i.ToV2())
|
||||||
|
require.Equal(t, eacl.RoleFromV2(i.ToV2()), i)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("unknown roles", func(t *testing.T) {
|
||||||
|
require.Equal(t, (eacl.RoleOthers + 1).ToV2(), v2acl.RoleUnknown)
|
||||||
|
require.Equal(t, eacl.RoleFromV2(v2acl.RoleOthers+1), eacl.RoleUnknown)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatch(t *testing.T) {
|
||||||
|
t.Run("known matches", func(t *testing.T) {
|
||||||
|
for i := eacl.MatchUnknown; i <= eacl.MatchStringNotEqual; i++ {
|
||||||
|
require.Equal(t, eqV2Matches[i], i.ToV2())
|
||||||
|
require.Equal(t, eacl.MatchFromV2(i.ToV2()), i)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("unknown matches", func(t *testing.T) {
|
||||||
|
require.Equal(t, (eacl.MatchStringNotEqual + 1).ToV2(), v2acl.MatchTypeUnknown)
|
||||||
|
require.Equal(t, eacl.MatchFromV2(v2acl.MatchTypeStringNotEqual+1), eacl.MatchUnknown)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterHeaderType(t *testing.T) {
|
||||||
|
t.Run("known header types", func(t *testing.T) {
|
||||||
|
for i := eacl.HeaderTypeUnknown; i <= eacl.HeaderFromObject; i++ {
|
||||||
|
require.Equal(t, eqV2HeaderTypes[i], i.ToV2())
|
||||||
|
require.Equal(t, eacl.FilterHeaderTypeFromV2(i.ToV2()), i)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("unknown header types", func(t *testing.T) {
|
||||||
|
require.Equal(t, (eacl.HeaderFromObject + 1).ToV2(), v2acl.HeaderTypeUnknown)
|
||||||
|
require.Equal(t, eacl.FilterHeaderTypeFromV2(v2acl.HeaderTypeObject+1), eacl.HeaderTypeUnknown)
|
||||||
|
})
|
||||||
|
}
|
31
pkg/acl/eacl/filter_test.go
Normal file
31
pkg/acl/eacl/filter_test.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package eacl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilter(t *testing.T) {
|
||||||
|
filter := &Filter{
|
||||||
|
from: HeaderFromObject,
|
||||||
|
name: HdrObjSysNamePayloadLength,
|
||||||
|
matcher: MatchStringEqual,
|
||||||
|
value: "200",
|
||||||
|
}
|
||||||
|
|
||||||
|
v2 := filter.ToV2()
|
||||||
|
require.NotNil(t, v2)
|
||||||
|
require.Equal(t, v2acl.HeaderTypeObject, v2.GetHeaderType())
|
||||||
|
require.EqualValues(t, v2acl.MatchTypeStringEqual, v2.GetMatchType())
|
||||||
|
require.Equal(t, filter.Name(), v2.GetName())
|
||||||
|
require.Equal(t, filter.Value(), v2.GetValue())
|
||||||
|
|
||||||
|
newFilter := NewFilterFromV2(v2)
|
||||||
|
require.Equal(t, filter, newFilter)
|
||||||
|
|
||||||
|
t.Run("from nil v2 filter", func(t *testing.T) {
|
||||||
|
require.Equal(t, new(Filter), NewFilterFromV2(nil))
|
||||||
|
})
|
||||||
|
}
|
83
pkg/acl/eacl/record_test.go
Normal file
83
pkg/acl/eacl/record_test.go
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
package eacl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
|
"github.com/nspcc-dev/neofs-crypto/test"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRecord(t *testing.T) {
|
||||||
|
record := NewRecord()
|
||||||
|
record.SetOperation(OperationRange)
|
||||||
|
record.SetAction(ActionAllow)
|
||||||
|
record.AddFilter(HeaderFromRequest, MatchStringEqual, "A", "B")
|
||||||
|
record.AddFilter(HeaderFromRequest, MatchStringNotEqual, "C", "D")
|
||||||
|
record.AddTarget(RoleSystem)
|
||||||
|
|
||||||
|
v2 := record.ToV2()
|
||||||
|
require.NotNil(t, v2)
|
||||||
|
require.Equal(t, v2acl.OperationRange, v2.GetOperation())
|
||||||
|
require.Equal(t, v2acl.ActionAllow, v2.GetAction())
|
||||||
|
require.Len(t, v2.GetFilters(), len(record.Filters()))
|
||||||
|
require.Len(t, v2.GetTargets(), len(record.Targets()))
|
||||||
|
|
||||||
|
newRecord := NewRecordFromV2(v2)
|
||||||
|
require.Equal(t, record, newRecord)
|
||||||
|
|
||||||
|
t.Run("create record", func(t *testing.T) {
|
||||||
|
record := CreateRecord(ActionAllow, OperationGet)
|
||||||
|
require.Equal(t, ActionAllow, record.Action())
|
||||||
|
require.Equal(t, OperationGet, record.Operation())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("new from nil v2 record", func(t *testing.T) {
|
||||||
|
require.Equal(t, new(Record), NewRecordFromV2(nil))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRecord_AddTarget(t *testing.T) {
|
||||||
|
targets := []Target{
|
||||||
|
{
|
||||||
|
role: RoleUnknown,
|
||||||
|
keys: []ecdsa.PublicKey{test.DecodeKey(1).PublicKey},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: RoleSystem,
|
||||||
|
keys: []ecdsa.PublicKey{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
r := NewRecord()
|
||||||
|
for _, target := range targets {
|
||||||
|
r.AddTarget(target.Role(), target.Keys()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, targets, r.Targets())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRecord_AddFilter(t *testing.T) {
|
||||||
|
filters := []Filter{
|
||||||
|
{
|
||||||
|
from: HeaderFromObject,
|
||||||
|
name: HdrObjSysNameCID,
|
||||||
|
matcher: MatchStringEqual,
|
||||||
|
value: "ContainerID",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: HeaderFromRequest,
|
||||||
|
name: "X-Header-Name",
|
||||||
|
matcher: MatchStringNotEqual,
|
||||||
|
value: "X-Header-Value",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
r := NewRecord()
|
||||||
|
for _, filter := range filters {
|
||||||
|
r.AddFilter(filter.From(), filter.Matcher(), filter.Name(), filter.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, filters, r.Filters())
|
||||||
|
}
|
|
@ -1,17 +1,80 @@
|
||||||
package eacl_test
|
package eacl_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||||
"github.com/nspcc-dev/neofs-crypto/test"
|
"github.com/nspcc-dev/neofs-crypto/test"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TextExample(t *testing.T) {
|
// example how to create eACL tables in applications
|
||||||
|
func example() {
|
||||||
record := eacl.CreateRecord(eacl.ActionDeny, eacl.OperationPut)
|
record := eacl.CreateRecord(eacl.ActionDeny, eacl.OperationPut)
|
||||||
record.AddFilter(eacl.HeaderFromObject, eacl.MatchStringEqual, "filename", "cat.jpg")
|
record.AddFilter(eacl.HeaderFromObject, eacl.MatchStringEqual, "filename", "cat.jpg")
|
||||||
record.AddTarget(eacl.RoleOthers, test.DecodeKey(1).PublicKey, test.DecodeKey(2).PublicKey)
|
record.AddTarget(eacl.RoleOthers, test.DecodeKey(1).PublicKey, test.DecodeKey(2).PublicKey)
|
||||||
|
|
||||||
table := eacl.NewTable()
|
var cid container.ID
|
||||||
|
cid.SetSHA256(sha256.Sum256([]byte("container id")))
|
||||||
|
|
||||||
|
table := eacl.CreateTable(cid)
|
||||||
table.AddRecord(record)
|
table.AddRecord(record)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTable(t *testing.T) {
|
||||||
|
var (
|
||||||
|
v pkg.Version
|
||||||
|
cid container.ID
|
||||||
|
)
|
||||||
|
|
||||||
|
sha := sha256.Sum256([]byte("container id"))
|
||||||
|
cid.SetSHA256(sha)
|
||||||
|
|
||||||
|
v.SetMajor(3)
|
||||||
|
v.SetMinor(2)
|
||||||
|
|
||||||
|
table := eacl.NewTable()
|
||||||
|
table.SetVersion(v)
|
||||||
|
table.SetCID(&cid)
|
||||||
|
table.AddRecord(eacl.CreateRecord(eacl.ActionAllow, eacl.OperationPut))
|
||||||
|
|
||||||
|
v2 := table.ToV2()
|
||||||
|
require.NotNil(t, v2)
|
||||||
|
require.Equal(t, uint32(3), v2.GetVersion().GetMajor())
|
||||||
|
require.Equal(t, uint32(2), v2.GetVersion().GetMinor())
|
||||||
|
require.Equal(t, sha[:], v2.GetContainerID().GetValue())
|
||||||
|
require.Len(t, v2.GetRecords(), 1)
|
||||||
|
|
||||||
|
newTable := eacl.NewTableFromV2(v2)
|
||||||
|
require.Equal(t, table, newTable)
|
||||||
|
|
||||||
|
t.Run("new from nil v2 table", func(t *testing.T) {
|
||||||
|
require.Equal(t, new(eacl.Table), eacl.NewTableFromV2(nil))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("create table", func(t *testing.T) {
|
||||||
|
var cid = new(container.ID)
|
||||||
|
cid.SetSHA256(sha256.Sum256([]byte("container id")))
|
||||||
|
|
||||||
|
table := eacl.CreateTable(*cid)
|
||||||
|
require.Equal(t, cid, table.CID())
|
||||||
|
require.Equal(t, *pkg.SDKVersion(), table.Version())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTable_AddRecord(t *testing.T) {
|
||||||
|
records := []eacl.Record{
|
||||||
|
*eacl.CreateRecord(eacl.ActionDeny, eacl.OperationDelete),
|
||||||
|
*eacl.CreateRecord(eacl.ActionAllow, eacl.OperationPut),
|
||||||
|
}
|
||||||
|
|
||||||
|
table := eacl.NewTable()
|
||||||
|
for _, record := range records {
|
||||||
|
table.AddRecord(&record)
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, records, table.Records())
|
||||||
|
}
|
||||||
|
|
38
pkg/acl/eacl/target_test.go
Normal file
38
pkg/acl/eacl/target_test.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package eacl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||||
|
"github.com/nspcc-dev/neofs-crypto/test"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTarget(t *testing.T) {
|
||||||
|
keys := []ecdsa.PublicKey{
|
||||||
|
test.DecodeKey(1).PublicKey,
|
||||||
|
test.DecodeKey(2).PublicKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
target := &Target{
|
||||||
|
role: RoleSystem,
|
||||||
|
keys: keys,
|
||||||
|
}
|
||||||
|
|
||||||
|
v2 := target.ToV2()
|
||||||
|
require.NotNil(t, v2)
|
||||||
|
require.Equal(t, v2acl.RoleSystem, v2.GetRole())
|
||||||
|
require.Len(t, v2.GetKeyList(), len(keys))
|
||||||
|
for i, key := range v2.GetKeyList() {
|
||||||
|
require.Equal(t, key, crypto.MarshalPublicKey(&keys[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
newTarget := NewTargetFromV2(v2)
|
||||||
|
require.Equal(t, target, newTarget)
|
||||||
|
|
||||||
|
t.Run("from nil v2 target", func(t *testing.T) {
|
||||||
|
require.Equal(t, new(Target), NewTargetFromV2(nil))
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue