[#182] sdk/eacl: Implement convenient methods for adding object filters
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
309c39481e
commit
6f45f713c1
4 changed files with 116 additions and 31 deletions
|
@ -1,6 +1,8 @@
|
||||||
package eacl
|
package eacl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -8,13 +10,40 @@ import (
|
||||||
// header means that request should be processed according to EACL action.
|
// header means that request should be processed according to EACL action.
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
from FilterHeaderType
|
from FilterHeaderType
|
||||||
key string
|
key filterKey
|
||||||
matcher Match
|
matcher Match
|
||||||
value string
|
value fmt.Stringer
|
||||||
|
}
|
||||||
|
|
||||||
|
type staticStringer string
|
||||||
|
|
||||||
|
type filterKey struct {
|
||||||
|
typ filterKeyType
|
||||||
|
|
||||||
|
str string
|
||||||
|
}
|
||||||
|
|
||||||
|
// enumeration of reserved filter keys.
|
||||||
|
type filterKeyType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ filterKeyType = iota
|
||||||
|
fKeyObjVersion
|
||||||
|
fKeyObjContainerID
|
||||||
|
fKeyObjOwnerID
|
||||||
|
fKeyObjCreationEpoch
|
||||||
|
fKeyObjPayloadLength
|
||||||
|
fKeyObjPayloadHash
|
||||||
|
fKeyObjType
|
||||||
|
fKeyObjHomomorphicHash
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s staticStringer) String() string {
|
||||||
|
return string(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Filter) Value() string {
|
func (a Filter) Value() string {
|
||||||
return a.value
|
return a.value.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Filter) Matcher() Match {
|
func (a Filter) Matcher() Match {
|
||||||
|
@ -22,7 +51,7 @@ func (a Filter) Matcher() Match {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Filter) Key() string {
|
func (a Filter) Key() string {
|
||||||
return a.key
|
return a.key.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Filter) From() FilterHeaderType {
|
func (a Filter) From() FilterHeaderType {
|
||||||
|
@ -31,14 +60,37 @@ func (a Filter) From() FilterHeaderType {
|
||||||
|
|
||||||
func (a *Filter) ToV2() *v2acl.HeaderFilter {
|
func (a *Filter) ToV2() *v2acl.HeaderFilter {
|
||||||
filter := new(v2acl.HeaderFilter)
|
filter := new(v2acl.HeaderFilter)
|
||||||
filter.SetValue(a.value)
|
filter.SetValue(a.value.String())
|
||||||
filter.SetKey(a.key)
|
filter.SetKey(a.key.String())
|
||||||
filter.SetMatchType(a.matcher.ToV2())
|
filter.SetMatchType(a.matcher.ToV2())
|
||||||
filter.SetHeaderType(a.from.ToV2())
|
filter.SetHeaderType(a.from.ToV2())
|
||||||
|
|
||||||
return filter
|
return filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k filterKey) String() string {
|
||||||
|
switch k.typ {
|
||||||
|
default:
|
||||||
|
return k.str
|
||||||
|
case fKeyObjVersion:
|
||||||
|
return v2acl.FilterObjectVersion
|
||||||
|
case fKeyObjContainerID:
|
||||||
|
return v2acl.FilterObjectContainerID
|
||||||
|
case fKeyObjOwnerID:
|
||||||
|
return v2acl.FilterObjectOwnerID
|
||||||
|
case fKeyObjCreationEpoch:
|
||||||
|
return v2acl.FilterObjectCreationEpoch
|
||||||
|
case fKeyObjPayloadLength:
|
||||||
|
return v2acl.FilterObjectPayloadLength
|
||||||
|
case fKeyObjPayloadHash:
|
||||||
|
return v2acl.FilterObjectPayloadHash
|
||||||
|
case fKeyObjType:
|
||||||
|
return v2acl.FilterObjectType
|
||||||
|
case fKeyObjHomomorphicHash:
|
||||||
|
return v2acl.FilterObjectHomomorphicHash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func NewFilterFromV2(filter *v2acl.HeaderFilter) *Filter {
|
func NewFilterFromV2(filter *v2acl.HeaderFilter) *Filter {
|
||||||
f := new(Filter)
|
f := new(Filter)
|
||||||
|
|
||||||
|
@ -48,8 +100,8 @@ func NewFilterFromV2(filter *v2acl.HeaderFilter) *Filter {
|
||||||
|
|
||||||
f.from = FilterHeaderTypeFromV2(filter.GetHeaderType())
|
f.from = FilterHeaderTypeFromV2(filter.GetHeaderType())
|
||||||
f.matcher = MatchFromV2(filter.GetMatchType())
|
f.matcher = MatchFromV2(filter.GetMatchType())
|
||||||
f.key = filter.GetKey()
|
f.key.str = filter.GetKey()
|
||||||
f.value = filter.GetValue()
|
f.value = staticStringer(filter.GetValue())
|
||||||
|
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,19 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFilter(t *testing.T) {
|
func newObjectFilter(match Match, key, val string) *Filter {
|
||||||
filter := &Filter{
|
return &Filter{
|
||||||
from: HeaderFromObject,
|
from: HeaderFromObject,
|
||||||
key: "some name",
|
key: filterKey{
|
||||||
matcher: MatchStringEqual,
|
str: key,
|
||||||
value: "200",
|
},
|
||||||
|
matcher: match,
|
||||||
|
value: staticStringer(val),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilter(t *testing.T) {
|
||||||
|
filter := newObjectFilter(MatchStringEqual, "some name", "200")
|
||||||
|
|
||||||
v2 := filter.ToV2()
|
v2 := filter.ToV2()
|
||||||
require.NotNil(t, v2)
|
require.NotNil(t, v2)
|
||||||
|
|
|
@ -2,7 +2,11 @@ package eacl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||||
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,17 +58,50 @@ func (r *Record) AddTarget(role Role, keys ...ecdsa.PublicKey) {
|
||||||
r.targets = append(r.targets, t)
|
r.targets = append(r.targets, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Record) AddFilter(from FilterHeaderType, matcher Match, name, value string) {
|
func (r *Record) addFilter(from FilterHeaderType, m Match, keyTyp filterKeyType, key string, val fmt.Stringer) {
|
||||||
filter := Filter{
|
filter := Filter{
|
||||||
from: from,
|
from: from,
|
||||||
key: name,
|
key: filterKey{
|
||||||
matcher: matcher,
|
typ: keyTyp,
|
||||||
value: value,
|
str: key,
|
||||||
|
},
|
||||||
|
matcher: m,
|
||||||
|
value: val,
|
||||||
}
|
}
|
||||||
|
|
||||||
r.filters = append(r.filters, filter)
|
r.filters = append(r.filters, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Record) addObjectFilter(m Match, keyTyp filterKeyType, key string, val fmt.Stringer) {
|
||||||
|
r.addFilter(HeaderFromObject, m, keyTyp, key, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Record) addObjectReservedFilter(m Match, typ filterKeyType, val fmt.Stringer) {
|
||||||
|
r.addObjectFilter(m, typ, "", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Record) AddFilter(from FilterHeaderType, matcher Match, name, value string) {
|
||||||
|
r.addFilter(from, matcher, 0, name, staticStringer(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Record) AddObjectAttributeFilter(m Match, key, value string) {
|
||||||
|
r.addObjectFilter(m, 0, key, staticStringer(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Record) AddObjectVersionFilter(m Match, v *pkg.Version) {
|
||||||
|
r.addObjectReservedFilter(m, fKeyObjVersion, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Record) AddObjectContainerIDFilter(m Match, id *container.ID) {
|
||||||
|
r.addObjectReservedFilter(m, fKeyObjContainerID, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Record) AddObjectOwnerIDFilter(m Match, id *owner.ID) {
|
||||||
|
r.addObjectReservedFilter(m, fKeyObjOwnerID, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add remaining filters after neofs-api#72
|
||||||
|
|
||||||
func (r *Record) ToV2() *v2acl.Record {
|
func (r *Record) ToV2() *v2acl.Record {
|
||||||
targets := make([]*v2acl.Target, 0, len(r.targets))
|
targets := make([]*v2acl.Target, 0, len(r.targets))
|
||||||
for _, target := range r.targets {
|
for _, target := range r.targets {
|
||||||
|
|
|
@ -60,18 +60,8 @@ func TestRecord_AddTarget(t *testing.T) {
|
||||||
|
|
||||||
func TestRecord_AddFilter(t *testing.T) {
|
func TestRecord_AddFilter(t *testing.T) {
|
||||||
filters := []Filter{
|
filters := []Filter{
|
||||||
{
|
*newObjectFilter(MatchStringEqual, "some name", "ContainerID"),
|
||||||
from: HeaderFromObject,
|
*newObjectFilter(MatchStringNotEqual, "X-Header-Name", "X-Header-Value"),
|
||||||
key: "some name",
|
|
||||||
matcher: MatchStringEqual,
|
|
||||||
value: "ContainerID",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: HeaderFromRequest,
|
|
||||||
key: "X-Header-Name",
|
|
||||||
matcher: MatchStringNotEqual,
|
|
||||||
value: "X-Header-Value",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r := NewRecord()
|
r := NewRecord()
|
||||||
|
|
Loading…
Reference in a new issue