forked from TrueCloudLab/frostfs-api-go
alc: add a rich functionality to manage Extended ACL
This commit is contained in:
parent
2456521240
commit
1dd4d48b5f
12 changed files with 1428 additions and 0 deletions
38
acl/action.go
Normal file
38
acl/action.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package acl
|
||||
|
||||
// RequestInfo is an interface of request information needed for extended ACL check.
|
||||
type RequestInfo interface {
|
||||
TypedHeaderSource
|
||||
|
||||
// Must return the binary representation of request initiator's key.
|
||||
Key() []byte
|
||||
|
||||
// Must return true if request corresponds to operation type.
|
||||
TypeOf(OperationType) bool
|
||||
|
||||
// Must return true if request has passed target.
|
||||
TargetOf(Target) bool
|
||||
}
|
||||
|
||||
// ExtendedACLChecker is an interface of extended ACL checking tool.
|
||||
type ExtendedACLChecker interface {
|
||||
// Must return an action according to the results of applying the ACL table rules to request.
|
||||
//
|
||||
// Must return ActionUndefined if it is unable to explicitly calculate the action.
|
||||
Action(ExtendedACLTable, RequestInfo) ExtendedACLAction
|
||||
}
|
||||
|
||||
type extendedACLChecker struct{}
|
||||
|
||||
const (
|
||||
// ActionUndefined is ExtendedACLAction used to mark value as undefined.
|
||||
// Most of the tools consider ActionUndefined as incalculable.
|
||||
// Using ActionUndefined in ExtendedACLRecord is unsafe.
|
||||
ActionUndefined ExtendedACLAction = iota
|
||||
|
||||
// ActionAllow is ExtendedACLAction used to mark an applicability of ACL rule.
|
||||
ActionAllow
|
||||
|
||||
// ActionDeny is ExtendedACLAction used to mark an inapplicability of ACL rule.
|
||||
ActionDeny
|
||||
)
|
76
acl/action_test.go
Normal file
76
acl/action_test.go
Normal file
|
@ -0,0 +1,76 @@
|
|||
package acl
|
||||
|
||||
type testExtendedACLTable struct {
|
||||
records []ExtendedACLRecord
|
||||
}
|
||||
|
||||
type testRequestInfo struct {
|
||||
headers []TypedHeader
|
||||
key []byte
|
||||
opType OperationType
|
||||
target Target
|
||||
}
|
||||
|
||||
type testEACLRecord struct {
|
||||
opType OperationType
|
||||
filters []HeaderFilter
|
||||
targets []ExtendedACLTarget
|
||||
action ExtendedACLAction
|
||||
}
|
||||
|
||||
type testEACLTarget struct {
|
||||
target Target
|
||||
keys [][]byte
|
||||
}
|
||||
|
||||
func (s testEACLTarget) Target() Target {
|
||||
return s.target
|
||||
}
|
||||
|
||||
func (s testEACLTarget) KeyList() [][]byte {
|
||||
return s.keys
|
||||
}
|
||||
|
||||
func (s testEACLRecord) OperationType() OperationType {
|
||||
return s.opType
|
||||
}
|
||||
|
||||
func (s testEACLRecord) HeaderFilters() []HeaderFilter {
|
||||
return s.filters
|
||||
}
|
||||
|
||||
func (s testEACLRecord) TargetList() []ExtendedACLTarget {
|
||||
return s.targets
|
||||
}
|
||||
|
||||
func (s testEACLRecord) Action() ExtendedACLAction {
|
||||
return s.action
|
||||
}
|
||||
|
||||
func (s testRequestInfo) HeadersOfType(typ HeaderType) ([]Header, bool) {
|
||||
res := make([]Header, 0, len(s.headers))
|
||||
|
||||
for i := range s.headers {
|
||||
if s.headers[i].HeaderType() == typ {
|
||||
res = append(res, s.headers[i])
|
||||
}
|
||||
}
|
||||
|
||||
return res, true
|
||||
}
|
||||
|
||||
func (s testRequestInfo) Key() []byte {
|
||||
return s.key
|
||||
}
|
||||
|
||||
func (s testRequestInfo) TypeOf(t OperationType) bool {
|
||||
return s.opType == t
|
||||
}
|
||||
|
||||
func (s testRequestInfo) TargetOf(t Target) bool {
|
||||
return s.target == t
|
||||
}
|
||||
|
||||
func (s testExtendedACLTable) Records() []ExtendedACLRecord {
|
||||
return s.records
|
||||
}
|
120
acl/extended.go
Normal file
120
acl/extended.go
Normal file
|
@ -0,0 +1,120 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/refs"
|
||||
)
|
||||
|
||||
// OperationType is an enumeration of operation types for extended ACL.
|
||||
type OperationType uint32
|
||||
|
||||
// HeaderType is an enumeration of header types for extended ACL.
|
||||
type HeaderType uint32
|
||||
|
||||
// MatchType is an enumeration of match types for extended ACL.
|
||||
type MatchType uint32
|
||||
|
||||
// ExtendedACLAction is an enumeration of extended ACL actions.
|
||||
type ExtendedACLAction uint32
|
||||
|
||||
// Header is an interface of string key-value pair,
|
||||
type Header interface {
|
||||
// Must return string identifier of header.
|
||||
Name() string
|
||||
|
||||
// Must return string value of header.
|
||||
Value() string
|
||||
}
|
||||
|
||||
// TypedHeader is an interface of Header and HeaderType pair.
|
||||
type TypedHeader interface {
|
||||
Header
|
||||
|
||||
// Must return type of filtered header.
|
||||
HeaderType() HeaderType
|
||||
}
|
||||
|
||||
// TypedHeaderSource is a various types of header set interface.
|
||||
type TypedHeaderSource interface {
|
||||
// Must return list of Header of particular type.
|
||||
// Must return false if there is no ability to compose header list.
|
||||
HeadersOfType(HeaderType) ([]Header, bool)
|
||||
}
|
||||
|
||||
// HeaderFilter is an interface of grouped information about filtered header.
|
||||
type HeaderFilter interface {
|
||||
// Must return match type of filter.
|
||||
MatchType() MatchType
|
||||
|
||||
TypedHeader
|
||||
}
|
||||
|
||||
// ExtendedACLTarget is an interface of grouped information about extended ACL rule target.
|
||||
type ExtendedACLTarget interface {
|
||||
// Must return ACL target type.
|
||||
Target() Target
|
||||
|
||||
// Must return public key list of ACL targets.
|
||||
KeyList() [][]byte
|
||||
}
|
||||
|
||||
// ExtendedACLRecord is an interface of record of extended ACL rule table.
|
||||
type ExtendedACLRecord interface {
|
||||
// Must return operation type of extended ACL rule.
|
||||
OperationType() OperationType
|
||||
|
||||
// Must return list of header filters of extended ACL rule.
|
||||
HeaderFilters() []HeaderFilter
|
||||
|
||||
// Must return target list of extended ACL rule.
|
||||
TargetList() []ExtendedACLTarget
|
||||
|
||||
// Must return action of extended ACL rule.
|
||||
Action() ExtendedACLAction
|
||||
}
|
||||
|
||||
// ExtendedACLTable is an interface of extended ACL table.
|
||||
type ExtendedACLTable interface {
|
||||
// Must return list of extended ACL rules.
|
||||
Records() []ExtendedACLRecord
|
||||
}
|
||||
|
||||
// ExtendedACLSource is an interface of storage of extended ACL tables with read access.
|
||||
type ExtendedACLSource interface {
|
||||
// Must return extended ACL table by container ID key.
|
||||
GetExtendedACLTable(context.Context, refs.CID) (ExtendedACLTable, error)
|
||||
}
|
||||
|
||||
// ExtendedACLStore is an interface of storage of extended ACL tables.
|
||||
type ExtendedACLStore interface {
|
||||
ExtendedACLSource
|
||||
|
||||
// Must store extended ACL table for container ID key.
|
||||
PutExtendedACLTable(context.Context, refs.CID, ExtendedACLTable) error
|
||||
}
|
||||
|
||||
const (
|
||||
_ OperationType = iota
|
||||
|
||||
// OpTypeGet is an OperationType for object.Get RPC
|
||||
OpTypeGet
|
||||
|
||||
// OpTypePut is an OperationType for object.Put RPC
|
||||
OpTypePut
|
||||
|
||||
// OpTypeHead is an OperationType for object.Head RPC
|
||||
OpTypeHead
|
||||
|
||||
// OpTypeSearch is an OperationType for object.Search RPC
|
||||
OpTypeSearch
|
||||
|
||||
// OpTypeDelete is an OperationType for object.Delete RPC
|
||||
OpTypeDelete
|
||||
|
||||
// OpTypeRange is an OperationType for object.GetRange RPC
|
||||
OpTypeRange
|
||||
|
||||
// OpTypeRangeHash is an OperationType for object.GetRangeHash RPC
|
||||
OpTypeRangeHash
|
||||
)
|
290
acl/header.go
Normal file
290
acl/header.go
Normal file
|
@ -0,0 +1,290 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/service"
|
||||
)
|
||||
|
||||
type objectHeaderSource struct {
|
||||
obj *object.Object
|
||||
}
|
||||
|
||||
type typedHeader struct {
|
||||
n string
|
||||
v string
|
||||
t HeaderType
|
||||
}
|
||||
|
||||
type extendedHeadersWrapper struct {
|
||||
hdrSrc service.ExtendedHeadersSource
|
||||
}
|
||||
|
||||
type typedExtendedHeader struct {
|
||||
hdr service.ExtendedHeader
|
||||
}
|
||||
|
||||
const (
|
||||
_ HeaderType = iota
|
||||
|
||||
// HdrTypeRequest is a HeaderType for request header.
|
||||
HdrTypeRequest
|
||||
|
||||
// HdrTypeObjSys is a HeaderType for system headers of object.
|
||||
HdrTypeObjSys
|
||||
|
||||
// HdrTypeObjUsr is a HeaderType for user headers of object.
|
||||
HdrTypeObjUsr
|
||||
)
|
||||
|
||||
const (
|
||||
// HdrObjSysNameID is a name of ID field in system header of object.
|
||||
HdrObjSysNameID = "ID"
|
||||
|
||||
// HdrObjSysNameCID is a name of CID field in system header of object.
|
||||
HdrObjSysNameCID = "CID"
|
||||
|
||||
// HdrObjSysNameOwnerID is a name of OwnerID field in system header of object.
|
||||
HdrObjSysNameOwnerID = "OWNER_ID"
|
||||
|
||||
// HdrObjSysNameVersion is a name of Version field in system header of object.
|
||||
HdrObjSysNameVersion = "VERSION"
|
||||
|
||||
// HdrObjSysNamePayloadLength is a name of PayloadLength field in system header of object.
|
||||
HdrObjSysNamePayloadLength = "PAYLOAD_LENGTH"
|
||||
|
||||
// HdrObjSysNameCreatedUnix is a name of CreatedAt.UnitTime field in system header of object.
|
||||
HdrObjSysNameCreatedUnix = "CREATED_UNIX"
|
||||
|
||||
// HdrObjSysNameCreatedEpoch is a name of CreatedAt.Epoch field in system header of object.
|
||||
HdrObjSysNameCreatedEpoch = "CREATED_EPOCH"
|
||||
|
||||
// HdrObjSysLinkPrev is a name of previous link header in extended headers of object.
|
||||
HdrObjSysLinkPrev = "LINK_PREV"
|
||||
|
||||
// HdrObjSysLinkNext is a name of next link header in extended headers of object.
|
||||
HdrObjSysLinkNext = "LINK_NEXT"
|
||||
|
||||
// HdrObjSysLinkChild is a name of child link header in extended headers of object.
|
||||
HdrObjSysLinkChild = "LINK_CHILD"
|
||||
|
||||
// HdrObjSysLinkPar is a name of parent link header in extended headers of object.
|
||||
HdrObjSysLinkPar = "LINK_PAR"
|
||||
|
||||
// HdrObjSysLinkSG is a name of storage group link header in extended headers of object.
|
||||
HdrObjSysLinkSG = "LINK_SG"
|
||||
)
|
||||
|
||||
func newTypedHeader(name, value string, typ HeaderType) TypedHeader {
|
||||
return &typedHeader{
|
||||
n: name,
|
||||
v: value,
|
||||
t: typ,
|
||||
}
|
||||
}
|
||||
|
||||
// Name is a name field getter.
|
||||
func (s typedHeader) Name() string {
|
||||
return s.n
|
||||
}
|
||||
|
||||
// Value is a value field getter.
|
||||
func (s typedHeader) Value() string {
|
||||
return s.v
|
||||
}
|
||||
|
||||
// HeaderType is a type field getter.
|
||||
func (s typedHeader) HeaderType() HeaderType {
|
||||
return s.t
|
||||
}
|
||||
|
||||
// TypedHeaderSourceFromObject wraps passed object and returns TypedHeaderSource interface.
|
||||
func TypedHeaderSourceFromObject(obj *object.Object) TypedHeaderSource {
|
||||
return &objectHeaderSource{
|
||||
obj: obj,
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderOfType gathers object headers of passed type and returns Header list.
|
||||
//
|
||||
// If value of some header can not be calculated (e.g. nil extended header), it does not appear in list.
|
||||
//
|
||||
// Always returns true.
|
||||
func (s objectHeaderSource) HeadersOfType(typ HeaderType) ([]Header, bool) {
|
||||
if s.obj == nil {
|
||||
return nil, true
|
||||
}
|
||||
|
||||
var res []Header
|
||||
|
||||
switch typ {
|
||||
case HdrTypeObjUsr:
|
||||
objHeaders := s.obj.GetHeaders()
|
||||
|
||||
res = make([]Header, 0, len(objHeaders)) // 7 system header fields
|
||||
|
||||
for _, extHdr := range objHeaders {
|
||||
if h := newTypedObjectExtendedHeader(extHdr); h != nil {
|
||||
res = append(res, h)
|
||||
}
|
||||
}
|
||||
case HdrTypeObjSys:
|
||||
res = make([]Header, 0, 7)
|
||||
|
||||
sysHdr := s.obj.GetSystemHeader()
|
||||
|
||||
// ID
|
||||
res = append(res, newTypedHeader(
|
||||
HdrObjSysNameID,
|
||||
sysHdr.ID.String(),
|
||||
HdrTypeObjSys),
|
||||
)
|
||||
|
||||
// CID
|
||||
res = append(res, newTypedHeader(
|
||||
HdrObjSysNameCID,
|
||||
sysHdr.CID.String(),
|
||||
HdrTypeObjSys),
|
||||
)
|
||||
|
||||
// OwnerID
|
||||
res = append(res, newTypedHeader(
|
||||
HdrObjSysNameOwnerID,
|
||||
sysHdr.OwnerID.String(),
|
||||
HdrTypeObjSys),
|
||||
)
|
||||
|
||||
// Version
|
||||
res = append(res, newTypedHeader(
|
||||
HdrObjSysNameVersion,
|
||||
strconv.FormatUint(sysHdr.GetVersion(), 10),
|
||||
HdrTypeObjSys),
|
||||
)
|
||||
|
||||
// PayloadLength
|
||||
res = append(res, newTypedHeader(
|
||||
HdrObjSysNamePayloadLength,
|
||||
strconv.FormatUint(sysHdr.GetPayloadLength(), 10),
|
||||
HdrTypeObjSys),
|
||||
)
|
||||
|
||||
created := sysHdr.GetCreatedAt()
|
||||
|
||||
// CreatedAt.UnitTime
|
||||
res = append(res, newTypedHeader(
|
||||
HdrObjSysNameCreatedUnix,
|
||||
strconv.FormatUint(uint64(created.GetUnixTime()), 10),
|
||||
HdrTypeObjSys),
|
||||
)
|
||||
|
||||
// CreatedAt.Epoch
|
||||
res = append(res, newTypedHeader(
|
||||
HdrObjSysNameCreatedEpoch,
|
||||
strconv.FormatUint(created.GetEpoch(), 10),
|
||||
HdrTypeObjSys),
|
||||
)
|
||||
}
|
||||
|
||||
return res, true
|
||||
}
|
||||
|
||||
func newTypedObjectExtendedHeader(h object.Header) TypedHeader {
|
||||
val := h.GetValue()
|
||||
if val == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
res := new(typedHeader)
|
||||
res.t = HdrTypeObjSys
|
||||
|
||||
switch hdr := val.(type) {
|
||||
case *object.Header_UserHeader:
|
||||
if hdr.UserHeader == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
res.t = HdrTypeObjUsr
|
||||
res.n = hdr.UserHeader.GetKey()
|
||||
res.v = hdr.UserHeader.GetValue()
|
||||
case *object.Header_Link:
|
||||
if hdr.Link == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch hdr.Link.GetType() {
|
||||
case object.Link_Previous:
|
||||
res.n = HdrObjSysLinkPrev
|
||||
case object.Link_Next:
|
||||
res.n = HdrObjSysLinkNext
|
||||
case object.Link_Child:
|
||||
res.n = HdrObjSysLinkChild
|
||||
case object.Link_Parent:
|
||||
res.n = HdrObjSysLinkPar
|
||||
case object.Link_StorageGroup:
|
||||
res.n = HdrObjSysLinkSG
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
res.v = hdr.Link.ID.String()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// TypedHeaderSourceFromExtendedHeaders wraps passed ExtendedHeadersSource and returns TypedHeaderSource interface.
|
||||
func TypedHeaderSourceFromExtendedHeaders(hdrSrc service.ExtendedHeadersSource) TypedHeaderSource {
|
||||
return &extendedHeadersWrapper{
|
||||
hdrSrc: hdrSrc,
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the result of Key method.
|
||||
func (s typedExtendedHeader) Name() string {
|
||||
return s.hdr.Key()
|
||||
}
|
||||
|
||||
// Value returns the result of Value method.
|
||||
func (s typedExtendedHeader) Value() string {
|
||||
return s.hdr.Value()
|
||||
}
|
||||
|
||||
// HeaderType always returns HdrTypeRequest.
|
||||
func (s typedExtendedHeader) HeaderType() HeaderType {
|
||||
return HdrTypeRequest
|
||||
}
|
||||
|
||||
// TypedHeaders gathers extended request headers and returns TypedHeader list.
|
||||
//
|
||||
// Nil headers are ignored.
|
||||
//
|
||||
// Always returns true.
|
||||
func (s extendedHeadersWrapper) HeadersOfType(typ HeaderType) ([]Header, bool) {
|
||||
if s.hdrSrc == nil {
|
||||
return nil, true
|
||||
}
|
||||
|
||||
var res []Header
|
||||
|
||||
switch typ {
|
||||
case HdrTypeRequest:
|
||||
hs := s.hdrSrc.ExtendedHeaders()
|
||||
|
||||
res = make([]Header, 0, len(hs))
|
||||
|
||||
for i := range hs {
|
||||
if hs[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
res = append(res, &typedExtendedHeader{
|
||||
hdr: hs[i],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return res, true
|
||||
}
|
59
acl/headers_test.go
Normal file
59
acl/headers_test.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/object"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewTypedObjectExtendedHeader(t *testing.T) {
|
||||
var res TypedHeader
|
||||
|
||||
hdr := object.Header{}
|
||||
|
||||
// nil value
|
||||
require.Nil(t, newTypedObjectExtendedHeader(hdr))
|
||||
|
||||
// UserHeader
|
||||
{
|
||||
key := "key"
|
||||
val := "val"
|
||||
hdr.Value = &object.Header_UserHeader{
|
||||
UserHeader: &object.UserHeader{
|
||||
Key: key,
|
||||
Value: val,
|
||||
},
|
||||
}
|
||||
|
||||
res = newTypedObjectExtendedHeader(hdr)
|
||||
require.Equal(t, HdrTypeObjUsr, res.HeaderType())
|
||||
require.Equal(t, key, res.Name())
|
||||
require.Equal(t, val, res.Value())
|
||||
}
|
||||
|
||||
{ // Link
|
||||
link := new(object.Link)
|
||||
link.ID = object.ID{1, 2, 3}
|
||||
|
||||
hdr.Value = &object.Header_Link{
|
||||
Link: link,
|
||||
}
|
||||
|
||||
check := func(lt object.Link_Type, name string) {
|
||||
link.Type = lt
|
||||
|
||||
res = newTypedObjectExtendedHeader(hdr)
|
||||
|
||||
require.Equal(t, HdrTypeObjSys, res.HeaderType())
|
||||
require.Equal(t, name, res.Name())
|
||||
require.Equal(t, link.ID.String(), res.Value())
|
||||
}
|
||||
|
||||
check(object.Link_Previous, HdrObjSysLinkPrev)
|
||||
check(object.Link_Next, HdrObjSysLinkNext)
|
||||
check(object.Link_Parent, HdrObjSysLinkPar)
|
||||
check(object.Link_Child, HdrObjSysLinkChild)
|
||||
check(object.Link_StorageGroup, HdrObjSysLinkSG)
|
||||
}
|
||||
}
|
29
acl/match.go
Normal file
29
acl/match.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package acl
|
||||
|
||||
const (
|
||||
_ MatchType = iota
|
||||
StringEqual
|
||||
StringNotEqual
|
||||
)
|
||||
|
||||
// Maps MatchType to corresponding function.
|
||||
// 1st argument of function - header value, 2nd - header filter.
|
||||
var mMatchFns = map[MatchType]func(Header, Header) bool{
|
||||
StringEqual: stringEqual,
|
||||
|
||||
StringNotEqual: stringNotEqual,
|
||||
}
|
||||
|
||||
const (
|
||||
mResUndefined = iota
|
||||
mResMatch
|
||||
mResMismatch
|
||||
)
|
||||
|
||||
func stringEqual(header, filter Header) bool {
|
||||
return header.Value() == filter.Value()
|
||||
}
|
||||
|
||||
func stringNotEqual(header, filter Header) bool {
|
||||
return header.Value() != filter.Value()
|
||||
}
|
44
acl/match_test.go
Normal file
44
acl/match_test.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package acl
|
||||
|
||||
type testTypedHeader struct {
|
||||
t HeaderType
|
||||
k string
|
||||
v string
|
||||
}
|
||||
|
||||
type testHeaderSrc struct {
|
||||
hs []TypedHeader
|
||||
}
|
||||
|
||||
type testHeaderFilter struct {
|
||||
TypedHeader
|
||||
t MatchType
|
||||
}
|
||||
|
||||
func (s testHeaderFilter) MatchType() MatchType {
|
||||
return s.t
|
||||
}
|
||||
|
||||
func (s testHeaderSrc) HeadersOfType(typ HeaderType) ([]Header, bool) {
|
||||
res := make([]Header, 0, len(s.hs))
|
||||
|
||||
for i := range s.hs {
|
||||
if s.hs[i].HeaderType() == typ {
|
||||
res = append(res, s.hs[i])
|
||||
}
|
||||
}
|
||||
|
||||
return res, true
|
||||
}
|
||||
|
||||
func (s testTypedHeader) Name() string {
|
||||
return s.k
|
||||
}
|
||||
|
||||
func (s testTypedHeader) Value() string {
|
||||
return s.v
|
||||
}
|
||||
|
||||
func (s testTypedHeader) HeaderType() HeaderType {
|
||||
return s.t
|
||||
}
|
56
acl/types.go
Normal file
56
acl/types.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package acl
|
||||
|
||||
// SetMatchType is MatchType field setter.
|
||||
func (m *EACLRecord_FilterInfo) SetMatchType(v EACLRecord_FilterInfo_MatchType) {
|
||||
m.MatchType = v
|
||||
}
|
||||
|
||||
// SetHeader is a Header field setter.
|
||||
func (m *EACLRecord_FilterInfo) SetHeader(v EACLRecord_FilterInfo_Header) {
|
||||
m.Header = v
|
||||
}
|
||||
|
||||
// SetHeaderName is a HeaderName field setter.
|
||||
func (m *EACLRecord_FilterInfo) SetHeaderName(v string) {
|
||||
m.HeaderName = v
|
||||
}
|
||||
|
||||
// SetHeaderVal is a HeaderVal field setter.
|
||||
func (m *EACLRecord_FilterInfo) SetHeaderVal(v string) {
|
||||
m.HeaderVal = v
|
||||
}
|
||||
|
||||
// SetTarget is a Target field setter.
|
||||
func (m *EACLRecord_TargetInfo) SetTarget(v Target) {
|
||||
m.Target = v
|
||||
}
|
||||
|
||||
// SetKeyList is a KeyList field setter.
|
||||
func (m *EACLRecord_TargetInfo) SetKeyList(v [][]byte) {
|
||||
m.KeyList = v
|
||||
}
|
||||
|
||||
// SetOperation is an Operation field setter.
|
||||
func (m *EACLRecord) SetOperation(v EACLRecord_Operation) {
|
||||
m.Operation = v
|
||||
}
|
||||
|
||||
// SetAction is an Action field setter.
|
||||
func (m *EACLRecord) SetAction(v EACLRecord_Action) {
|
||||
m.Action = v
|
||||
}
|
||||
|
||||
// SetFilters is a Filters field setter.
|
||||
func (m *EACLRecord) SetFilters(v []*EACLRecord_FilterInfo) {
|
||||
m.Filters = v
|
||||
}
|
||||
|
||||
// SetTargets is a Targets field setter.
|
||||
func (m *EACLRecord) SetTargets(v []*EACLRecord_TargetInfo) {
|
||||
m.Targets = v
|
||||
}
|
||||
|
||||
// SetRecords is a Records field setter.
|
||||
func (m *EACLTable) SetRecords(v []*EACLRecord) {
|
||||
m.Records = v
|
||||
}
|
BIN
acl/types.pb.go
BIN
acl/types.pb.go
Binary file not shown.
|
@ -25,3 +25,82 @@ enum Target {
|
|||
// extended ACL.
|
||||
PubKey = 4;
|
||||
}
|
||||
|
||||
// EACLRecord groups information about extended ACL rule.
|
||||
message EACLRecord {
|
||||
// Operation is an enumeration of operation types.
|
||||
enum Operation {
|
||||
OPERATION_UNKNOWN = 0;
|
||||
GET = 1;
|
||||
HEAD = 2;
|
||||
PUT = 3;
|
||||
DELETE = 4;
|
||||
SEARCH = 5;
|
||||
GETRANGE = 6;
|
||||
GETRANGEHASH = 7;
|
||||
}
|
||||
|
||||
// Operation carries type of operation.
|
||||
Operation operation = 1 [(gogoproto.customname) = "Operation", json_name="Operation"];
|
||||
|
||||
// Action is an enumeration of EACL actions.
|
||||
enum Action {
|
||||
ActionUnknown = 0;
|
||||
Allow = 1;
|
||||
Deny = 2;
|
||||
}
|
||||
|
||||
// Action carries ACL target action.
|
||||
Action action = 2 [(gogoproto.customname) = "Action", json_name="Action"];
|
||||
|
||||
// FilterInfo groups information about filter.
|
||||
message FilterInfo {
|
||||
// Header is an enumeration of filtering header types.
|
||||
enum Header {
|
||||
HeaderUnknown = 0;
|
||||
Request = 1;
|
||||
ObjectSystem = 2;
|
||||
ObjectUser = 3;
|
||||
}
|
||||
|
||||
// Header carries type of header.
|
||||
Header header = 1 [(gogoproto.customname) = "Header", json_name="HeaderType"];
|
||||
|
||||
// MatchType is an enumeration of match types.
|
||||
enum MatchType {
|
||||
MatchUnknown = 0;
|
||||
StringEqual = 1;
|
||||
StringNotEqual = 2;
|
||||
}
|
||||
|
||||
// MatchType carries type of match.
|
||||
MatchType matchType = 2 [(gogoproto.customname) = "MatchType", json_name="MatchType"];
|
||||
|
||||
// HeaderName carries name of filtering header.
|
||||
string HeaderName = 3 [json_name="Name"];
|
||||
|
||||
// HeaderVal carries value of filtering header.
|
||||
string HeaderVal = 4 [json_name="Value"];
|
||||
}
|
||||
|
||||
// Filters carries set of filters.
|
||||
repeated FilterInfo Filters = 3 [json_name="Filters"];
|
||||
|
||||
// TargetInfo groups information about extended ACL target.
|
||||
message TargetInfo {
|
||||
// Target carries target of ACL rule.
|
||||
acl.Target Target = 1 [json_name="Role"];
|
||||
|
||||
// KeyList carries public keys of ACL target.
|
||||
repeated bytes KeyList = 2 [json_name="Keys"];
|
||||
}
|
||||
|
||||
// Targets carries information about extended ACL target list.
|
||||
repeated TargetInfo Targets = 4 [json_name="Targets"];
|
||||
}
|
||||
|
||||
// EACLRecord carries the information about extended ACL rules.
|
||||
message EACLTable {
|
||||
// Records carries list of extended ACL rule records.
|
||||
repeated EACLRecord Records = 1 [json_name="Records"];
|
||||
}
|
498
acl/wrappers.go
Normal file
498
acl/wrappers.go
Normal file
|
@ -0,0 +1,498 @@
|
|||
package acl
|
||||
|
||||
// EACLFilterWrapper is a wrapper over EACLRecord_FilterInfo pointer.
|
||||
type EACLFilterWrapper struct {
|
||||
filter *EACLRecord_FilterInfo
|
||||
}
|
||||
|
||||
// EACLTargetWrapper is a wrapper over EACLRecord_TargetInfo pointer.
|
||||
type EACLTargetWrapper struct {
|
||||
target *EACLRecord_TargetInfo
|
||||
}
|
||||
|
||||
// EACLRecordWrapper is a wrapper over EACLRecord pointer.
|
||||
type EACLRecordWrapper struct {
|
||||
record *EACLRecord
|
||||
}
|
||||
|
||||
// EACLTableWrapper is a wrapper over EACLTable pointer.
|
||||
type EACLTableWrapper struct {
|
||||
table *EACLTable
|
||||
}
|
||||
|
||||
// WrapFilterInfo wraps EACLRecord_FilterInfo pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord_FilterInfo is initialized.
|
||||
func WrapFilterInfo(v *EACLRecord_FilterInfo) EACLFilterWrapper {
|
||||
if v == nil {
|
||||
v = new(EACLRecord_FilterInfo)
|
||||
}
|
||||
|
||||
return EACLFilterWrapper{
|
||||
filter: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapEACLTarget wraps EACLRecord_TargetInfo pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord_TargetInfo is initialized.
|
||||
func WrapEACLTarget(v *EACLRecord_TargetInfo) EACLTargetWrapper {
|
||||
if v == nil {
|
||||
v = new(EACLRecord_TargetInfo)
|
||||
}
|
||||
|
||||
return EACLTargetWrapper{
|
||||
target: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapEACLRecord wraps EACLRecord pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord is initialized.
|
||||
func WrapEACLRecord(v *EACLRecord) EACLRecordWrapper {
|
||||
if v == nil {
|
||||
v = new(EACLRecord)
|
||||
}
|
||||
|
||||
return EACLRecordWrapper{
|
||||
record: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapEACLTable wraps EACLTable pointer.
|
||||
//
|
||||
// If argument is nil, new EACLTable is initialized.
|
||||
func WrapEACLTable(v *EACLTable) EACLTableWrapper {
|
||||
if v == nil {
|
||||
v = new(EACLTable)
|
||||
}
|
||||
|
||||
return EACLTableWrapper{
|
||||
table: v,
|
||||
}
|
||||
}
|
||||
|
||||
// MatchType returns casted result of MatchType field getter.
|
||||
//
|
||||
// If filter is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if MatchType is not one of:
|
||||
// - EACLRecord_FilterInfo_StringEqual;
|
||||
// - EACLRecord_FilterInfo_StringNotEqual.
|
||||
func (s EACLFilterWrapper) MatchType() (res MatchType) {
|
||||
if s.filter != nil {
|
||||
switch s.filter.GetMatchType() {
|
||||
case EACLRecord_FilterInfo_StringEqual:
|
||||
res = StringEqual
|
||||
case EACLRecord_FilterInfo_StringNotEqual:
|
||||
res = StringNotEqual
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetMatchType passes casted argument to MatchType field setter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
//
|
||||
// MatchType is set to EACLRecord_FilterInfo_MatchUnknown if argument is not one of:
|
||||
// - StringEqual;
|
||||
// - StringNotEqual.
|
||||
func (s EACLFilterWrapper) SetMatchType(v MatchType) {
|
||||
if s.filter != nil {
|
||||
switch v {
|
||||
case StringEqual:
|
||||
s.filter.SetMatchType(EACLRecord_FilterInfo_StringEqual)
|
||||
case StringNotEqual:
|
||||
s.filter.SetMatchType(EACLRecord_FilterInfo_StringNotEqual)
|
||||
default:
|
||||
s.filter.SetMatchType(EACLRecord_FilterInfo_MatchUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the result of HeaderName field getter.
|
||||
//
|
||||
// If filter is not initialized, empty string returns.
|
||||
func (s EACLFilterWrapper) Name() string {
|
||||
if s.filter == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s.filter.GetHeaderName()
|
||||
}
|
||||
|
||||
// SetName passes argument to HeaderName field setter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
func (s EACLFilterWrapper) SetName(v string) {
|
||||
if s.filter != nil {
|
||||
s.filter.SetHeaderName(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Value returns the result of HeaderVal field getter.
|
||||
//
|
||||
// If filter is not initialized, empty string returns.
|
||||
func (s EACLFilterWrapper) Value() string {
|
||||
if s.filter == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s.filter.GetHeaderVal()
|
||||
}
|
||||
|
||||
// SetValue passes argument to HeaderVal field setter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
func (s EACLFilterWrapper) SetValue(v string) {
|
||||
if s.filter != nil {
|
||||
s.filter.SetHeaderVal(v)
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderType returns the result of Header field getter.
|
||||
//
|
||||
// If filter is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if Header is not one of:
|
||||
// - EACLRecord_FilterInfo_Request;
|
||||
// - EACLRecord_FilterInfo_ObjectSystem;
|
||||
// - EACLRecord_FilterInfo_ObjectUser.
|
||||
func (s EACLFilterWrapper) HeaderType() (res HeaderType) {
|
||||
if s.filter != nil {
|
||||
switch s.filter.GetHeader() {
|
||||
case EACLRecord_FilterInfo_Request:
|
||||
res = HdrTypeRequest
|
||||
case EACLRecord_FilterInfo_ObjectSystem:
|
||||
res = HdrTypeObjSys
|
||||
case EACLRecord_FilterInfo_ObjectUser:
|
||||
res = HdrTypeObjUsr
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetHeaderType passes casted argument to Header field setter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
//
|
||||
// Header is set to EACLRecord_FilterInfo_HeaderUnknown if argument is not one of:
|
||||
// - HdrTypeRequest;
|
||||
// - HdrTypeObjSys;
|
||||
// - HdrTypeObjUsr.
|
||||
func (s EACLFilterWrapper) SetHeaderType(t HeaderType) {
|
||||
if s.filter != nil {
|
||||
switch t {
|
||||
case HdrTypeRequest:
|
||||
s.filter.SetHeader(EACLRecord_FilterInfo_Request)
|
||||
case HdrTypeObjSys:
|
||||
s.filter.SetHeader(EACLRecord_FilterInfo_ObjectSystem)
|
||||
case HdrTypeObjUsr:
|
||||
s.filter.SetHeader(EACLRecord_FilterInfo_ObjectUser)
|
||||
default:
|
||||
s.filter.SetHeader(EACLRecord_FilterInfo_HeaderUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Target returns the result of Target field getter.
|
||||
//
|
||||
// If target is not initialized, Target_Unknown returns.
|
||||
func (s EACLTargetWrapper) Target() Target {
|
||||
if s.target == nil {
|
||||
return Target_Unknown
|
||||
}
|
||||
|
||||
return s.target.GetTarget()
|
||||
}
|
||||
|
||||
// SetTarget passes argument to Target field setter.
|
||||
//
|
||||
// If target is not initialized, nothing changes.
|
||||
func (s EACLTargetWrapper) SetTarget(v Target) {
|
||||
if s.target != nil {
|
||||
s.target.SetTarget(v)
|
||||
}
|
||||
}
|
||||
|
||||
// KeyList returns the result of KeyList field getter.
|
||||
//
|
||||
// If target is not initialized, nil returns.
|
||||
func (s EACLTargetWrapper) KeyList() [][]byte {
|
||||
if s.target == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.target.GetKeyList()
|
||||
}
|
||||
|
||||
// SetKeyList passes argument to KeyList field setter.
|
||||
//
|
||||
// If target is not initialized, nothing changes.
|
||||
func (s EACLTargetWrapper) SetKeyList(v [][]byte) {
|
||||
if s.target != nil {
|
||||
s.target.SetKeyList(v)
|
||||
}
|
||||
}
|
||||
|
||||
// KeyList returns casted result of Operation field getter.
|
||||
//
|
||||
// If record is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if Operation is not one of:
|
||||
// - EACLRecord_HEAD;
|
||||
// - EACLRecord_PUT;
|
||||
// - EACLRecord_SEARCH;
|
||||
// - EACLRecord_GET;
|
||||
// - EACLRecord_GETRANGE;
|
||||
// - EACLRecord_GETRANGEHASH;
|
||||
// - EACLRecord_DELETE.
|
||||
func (s EACLRecordWrapper) OperationType() (res OperationType) {
|
||||
if s.record != nil {
|
||||
switch s.record.GetOperation() {
|
||||
case EACLRecord_HEAD:
|
||||
res = OpTypeHead
|
||||
case EACLRecord_PUT:
|
||||
res = OpTypePut
|
||||
case EACLRecord_SEARCH:
|
||||
res = OpTypeSearch
|
||||
case EACLRecord_GET:
|
||||
res = OpTypeGet
|
||||
case EACLRecord_GETRANGE:
|
||||
res = OpTypeRange
|
||||
case EACLRecord_GETRANGEHASH:
|
||||
res = OpTypeRangeHash
|
||||
case EACLRecord_DELETE:
|
||||
res = OpTypeDelete
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetOperationType passes casted argument to Operation field setter.
|
||||
//
|
||||
// If record is not initialized, nothing changes.
|
||||
//
|
||||
// Operation is set to EACLRecord_OPERATION_UNKNOWN if argument is not one of:
|
||||
// - OpTypeHead;
|
||||
// - OpTypePut;
|
||||
// - OpTypeSearch;
|
||||
// - OpTypeGet;
|
||||
// - OpTypeRange;
|
||||
// - OpTypeRangeHash;
|
||||
// - OpTypeDelete.
|
||||
func (s EACLRecordWrapper) SetOperationType(v OperationType) {
|
||||
if s.record != nil {
|
||||
switch v {
|
||||
case OpTypeHead:
|
||||
s.record.SetOperation(EACLRecord_HEAD)
|
||||
case OpTypePut:
|
||||
s.record.SetOperation(EACLRecord_PUT)
|
||||
case OpTypeSearch:
|
||||
s.record.SetOperation(EACLRecord_SEARCH)
|
||||
case OpTypeGet:
|
||||
s.record.SetOperation(EACLRecord_GET)
|
||||
case OpTypeRange:
|
||||
s.record.SetOperation(EACLRecord_GETRANGE)
|
||||
case OpTypeRangeHash:
|
||||
s.record.SetOperation(EACLRecord_GETRANGEHASH)
|
||||
case OpTypeDelete:
|
||||
s.record.SetOperation(EACLRecord_DELETE)
|
||||
default:
|
||||
s.record.SetOperation(EACLRecord_OPERATION_UNKNOWN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Action returns casted result of Action field getter.
|
||||
//
|
||||
// If record is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if Action is not one of:
|
||||
// - EACLRecord_Deny;
|
||||
// - EACLRecord_Allow.
|
||||
func (s EACLRecordWrapper) Action() (res ExtendedACLAction) {
|
||||
if s.record != nil {
|
||||
switch s.record.GetAction() {
|
||||
case EACLRecord_Deny:
|
||||
res = ActionDeny
|
||||
case EACLRecord_Allow:
|
||||
res = ActionAllow
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetAction passes casted argument to Action field setter.
|
||||
//
|
||||
// If record is not initialized, nothing changes.
|
||||
//
|
||||
// Action is set to EACLRecord_ActionUnknown if argument is not one of:
|
||||
// - ActionDeny;
|
||||
// - ActionAllow.
|
||||
func (s EACLRecordWrapper) SetAction(v ExtendedACLAction) {
|
||||
if s.record != nil {
|
||||
switch v {
|
||||
case ActionDeny:
|
||||
s.record.SetAction(EACLRecord_Deny)
|
||||
case ActionAllow:
|
||||
s.record.SetAction(EACLRecord_Allow)
|
||||
default:
|
||||
s.record.SetAction(EACLRecord_ActionUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderFilters wraps all elements from Filters field getter result and returns HeaderFilter list.
|
||||
//
|
||||
// If record is not initialized, nil returns.
|
||||
func (s EACLRecordWrapper) HeaderFilters() []HeaderFilter {
|
||||
if s.record == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
filters := s.record.GetFilters()
|
||||
|
||||
res := make([]HeaderFilter, 0, len(filters))
|
||||
|
||||
for i := range filters {
|
||||
res = append(res, WrapFilterInfo(filters[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetHeaderFilters converts HeaderFilter list to EACLRecord_FilterInfo list and passes it to Filters field setter.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If record is not initialized, nothing changes.
|
||||
func (s EACLRecordWrapper) SetHeaderFilters(v []HeaderFilter) {
|
||||
if s.record == nil {
|
||||
return
|
||||
}
|
||||
|
||||
filters := make([]*EACLRecord_FilterInfo, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapFilterInfo(nil)
|
||||
w.SetMatchType(v[i].MatchType())
|
||||
w.SetHeaderType(v[i].HeaderType())
|
||||
w.SetName(v[i].Name())
|
||||
w.SetValue(v[i].Value())
|
||||
|
||||
filters = append(filters, w.filter)
|
||||
}
|
||||
|
||||
s.record.SetFilters(filters)
|
||||
}
|
||||
|
||||
// TargetList wraps all elements from Targets field getter result and returns ExtendedACLTarget list.
|
||||
//
|
||||
// If record is not initialized, nil returns.
|
||||
func (s EACLRecordWrapper) TargetList() []ExtendedACLTarget {
|
||||
if s.record == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
targets := s.record.GetTargets()
|
||||
|
||||
res := make([]ExtendedACLTarget, 0, len(targets))
|
||||
|
||||
for i := range targets {
|
||||
res = append(res, WrapEACLTarget(targets[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetTargetList converts ExtendedACLTarget list to EACLRecord_TargetInfo list and passes it to Targets field setter.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If record is not initialized, nothing changes.
|
||||
func (s EACLRecordWrapper) SetTargetList(v []ExtendedACLTarget) {
|
||||
if s.record == nil {
|
||||
return
|
||||
}
|
||||
|
||||
targets := make([]*EACLRecord_TargetInfo, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapEACLTarget(nil)
|
||||
w.SetTarget(v[i].Target())
|
||||
w.SetKeyList(v[i].KeyList())
|
||||
|
||||
targets = append(targets, w.target)
|
||||
}
|
||||
|
||||
s.record.SetTargets(targets)
|
||||
}
|
||||
|
||||
// Records wraps all elements from Records field getter result and returns ExtendedACLRecord list.
|
||||
//
|
||||
// If table is not initialized, nil returns.
|
||||
func (s EACLTableWrapper) Records() []ExtendedACLRecord {
|
||||
if s.table == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
records := s.table.GetRecords()
|
||||
|
||||
res := make([]ExtendedACLRecord, 0, len(records))
|
||||
|
||||
for i := range records {
|
||||
res = append(res, WrapEACLRecord(records[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetRecords converts ExtendedACLRecord list to EACLRecord list and passes it to Records field setter.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If table is not initialized, nothing changes.
|
||||
func (s EACLTableWrapper) SetRecords(v []ExtendedACLRecord) {
|
||||
if s.table == nil {
|
||||
return
|
||||
}
|
||||
|
||||
records := make([]*EACLRecord, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapEACLRecord(nil)
|
||||
w.SetOperationType(v[i].OperationType())
|
||||
w.SetAction(v[i].Action())
|
||||
w.SetHeaderFilters(v[i].HeaderFilters())
|
||||
w.SetTargetList(v[i].TargetList())
|
||||
|
||||
records = append(records, w.record)
|
||||
}
|
||||
|
||||
s.table.SetRecords(records)
|
||||
}
|
||||
|
||||
// MarshalBinary returns the result of Marshal method.
|
||||
func (s EACLTableWrapper) MarshalBinary() ([]byte, error) {
|
||||
return s.table.Marshal()
|
||||
}
|
||||
|
||||
// UnmarshalBinary passes argument to Unmarshal method and returns its result.
|
||||
func (s EACLTableWrapper) UnmarshalBinary(data []byte) error {
|
||||
return s.table.Unmarshal(data)
|
||||
}
|
139
acl/wrappers_test.go
Normal file
139
acl/wrappers_test.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEACLFilterWrapper(t *testing.T) {
|
||||
s := WrapFilterInfo(nil)
|
||||
|
||||
mt := StringEqual
|
||||
s.SetMatchType(mt)
|
||||
require.Equal(t, mt, s.MatchType())
|
||||
|
||||
ht := HdrTypeObjUsr
|
||||
s.SetHeaderType(ht)
|
||||
require.Equal(t, ht, s.HeaderType())
|
||||
|
||||
n := "name"
|
||||
s.SetName(n)
|
||||
require.Equal(t, n, s.Name())
|
||||
|
||||
v := "value"
|
||||
s.SetValue(v)
|
||||
require.Equal(t, v, s.Value())
|
||||
}
|
||||
|
||||
func TestEACLTargetWrapper(t *testing.T) {
|
||||
s := WrapEACLTarget(nil)
|
||||
|
||||
target := Target(10)
|
||||
s.SetTarget(target)
|
||||
require.Equal(t, target, s.Target())
|
||||
|
||||
keys := [][]byte{
|
||||
{1, 2, 3},
|
||||
{4, 5, 6},
|
||||
}
|
||||
s.SetKeyList(keys)
|
||||
require.Equal(t, keys, s.KeyList())
|
||||
}
|
||||
|
||||
func TestEACLRecordWrapper(t *testing.T) {
|
||||
s := WrapEACLRecord(nil)
|
||||
|
||||
action := ActionAllow
|
||||
s.SetAction(action)
|
||||
require.Equal(t, action, s.Action())
|
||||
|
||||
opType := OperationType(5)
|
||||
s.SetOperationType(opType)
|
||||
require.Equal(t, opType, s.OperationType())
|
||||
|
||||
f1Name := "name1"
|
||||
f1 := WrapFilterInfo(nil)
|
||||
f1.SetName(f1Name)
|
||||
|
||||
f2Name := "name2"
|
||||
f2 := WrapFilterInfo(nil)
|
||||
f2.SetName(f2Name)
|
||||
|
||||
s.SetHeaderFilters([]HeaderFilter{f1, f2})
|
||||
|
||||
filters := s.HeaderFilters()
|
||||
require.Len(t, filters, 2)
|
||||
require.Equal(t, f1Name, filters[0].Name())
|
||||
require.Equal(t, f2Name, filters[1].Name())
|
||||
|
||||
target1 := Target(1)
|
||||
t1 := WrapEACLTarget(nil)
|
||||
t1.SetTarget(target1)
|
||||
|
||||
target2 := Target(2)
|
||||
t2 := WrapEACLTarget(nil)
|
||||
t2.SetTarget(target2)
|
||||
|
||||
s.SetTargetList([]ExtendedACLTarget{t1, t2})
|
||||
|
||||
targets := s.TargetList()
|
||||
require.Len(t, targets, 2)
|
||||
require.Equal(t, target1, targets[0].Target())
|
||||
require.Equal(t, target2, targets[1].Target())
|
||||
}
|
||||
|
||||
func TestEACLTableWrapper(t *testing.T) {
|
||||
s := WrapEACLTable(nil)
|
||||
|
||||
action1 := ExtendedACLAction(1)
|
||||
r1 := WrapEACLRecord(nil)
|
||||
r1.SetAction(action1)
|
||||
|
||||
action2 := ExtendedACLAction(2)
|
||||
r2 := WrapEACLRecord(nil)
|
||||
r2.SetAction(action2)
|
||||
|
||||
s.SetRecords([]ExtendedACLRecord{r1, r2})
|
||||
|
||||
records := s.Records()
|
||||
require.Len(t, records, 2)
|
||||
require.Equal(t, action1, records[0].Action())
|
||||
require.Equal(t, action2, records[1].Action())
|
||||
|
||||
data, err := s.MarshalBinary()
|
||||
require.NoError(t, err)
|
||||
|
||||
s2 := WrapEACLTable(nil)
|
||||
require.NoError(t, s2.UnmarshalBinary(data))
|
||||
|
||||
records1 := s.Records()
|
||||
records2 := s2.Records()
|
||||
require.Len(t, records1, len(records2))
|
||||
|
||||
for i := range records1 {
|
||||
require.Equal(t, records1[i].Action(), records2[i].Action())
|
||||
require.Equal(t, records1[i].OperationType(), records2[i].OperationType())
|
||||
|
||||
targets1 := records1[i].TargetList()
|
||||
targets2 := records2[i].TargetList()
|
||||
require.Len(t, targets1, len(targets2))
|
||||
|
||||
for j := range targets1 {
|
||||
require.Equal(t, targets1[j].Target(), targets2[j].Target())
|
||||
require.Equal(t, targets1[j].KeyList(), targets2[j].KeyList())
|
||||
}
|
||||
|
||||
filters1 := records1[i].HeaderFilters()
|
||||
filters2 := records2[i].HeaderFilters()
|
||||
require.Len(t, filters1, len(filters2))
|
||||
|
||||
for j := range filters1 {
|
||||
require.Equal(t, filters1[j].MatchType(), filters2[j].MatchType())
|
||||
require.Equal(t, filters1[j].HeaderType(), filters2[j].HeaderType())
|
||||
require.Equal(t, filters1[j].Name(), filters2[j].Name())
|
||||
require.Equal(t, filters1[j].Value(), filters2[j].Value())
|
||||
require.Equal(t, filters1[j].Value(), filters2[j].Value())
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue