From 5e1e220988677aa166738ad1f6194e8ea4132744 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 22 Jun 2020 17:26:59 +0300 Subject: [PATCH 1/9] service: sign requests on the principle of Matryoshka This commit changes SignRequestData / VerifyRequestData functions to add the list of previous public keys to a signed message for all requests. --- service/sign.go | 20 +++++++++++++++--- service/sign_test.go | 48 ++++++++++++++++++++++++++++++------------ service/types.go | 1 + service/verify.go | 50 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 16 deletions(-) diff --git a/service/sign.go b/service/sign.go index 50453b9..796a4cd 100644 --- a/service/sign.go +++ b/service/sign.go @@ -137,11 +137,24 @@ func verifySignatures(src SignedDataSource, items ...SignKeyPair) error { } defer bytesPool.Put(data) - for _, signKey := range items { + for i := range items { + if i > 0 { + // add previous key bytes to the signed message + + signKeyDataSrc := SignKeyPairsSignedData(items[i-1]) + + signKeyData, err := signKeyDataSrc.SignedData() + if err != nil { + return errors.Wrapf(err, "could not get signed data of key-signature #%d", i) + } + + data = append(data, signKeyData...) + } + if err := crypto.Verify( - signKey.GetPublicKey(), + items[i].GetPublicKey(), data, - signKey.GetSignature(), + items[i].GetSignature(), ); err != nil { return err } @@ -213,6 +226,7 @@ func SignRequestData(key *ecdsa.PrivateKey, src RequestSignedData) error { src.GetBearerToken(), ), ExtendedHeadersSignedData(src), + SignKeyPairsSignedData(src.GetSignKeyPairs()...), ) if err != nil { return err diff --git a/service/sign_test.go b/service/sign_test.go index 6f1e913..3c54e8c 100644 --- a/service/sign_test.go +++ b/service/sign_test.go @@ -15,13 +15,13 @@ import ( type testSignedDataSrc struct { err error data []byte - sig []byte - key *ecdsa.PublicKey token SessionToken bearer BearerToken extHdrs []ExtendedHeader + + signKeys []SignKeyPair } type testSignedDataReader struct { @@ -29,13 +29,15 @@ type testSignedDataReader struct { } func (s testSignedDataSrc) GetSignature() []byte { - return s.sig + if len(s.signKeys) > 0 { + return s.signKeys[0].GetSignature() + } + + return nil } func (s testSignedDataSrc) GetSignKeyPairs() []SignKeyPair { - return []SignKeyPair{ - newSignatureKeyPair(s.key, s.sig), - } + return s.signKeys } func (s testSignedDataSrc) SignedData() ([]byte, error) { @@ -43,8 +45,9 @@ func (s testSignedDataSrc) SignedData() ([]byte, error) { } func (s *testSignedDataSrc) AddSignKey(sig []byte, key *ecdsa.PublicKey) { - s.key = key - s.sig = sig + s.signKeys = append(s.signKeys, + newSignatureKeyPair(key, sig), + ) } func testData(t *testing.T, sz int) []byte { @@ -209,23 +212,27 @@ func TestVerifyAccumulatedSignatures(t *testing.T) { // create test private key sk := test.DecodeKey(0) + signKey := new(RequestVerificationHeader_Signature) + signKey.Peer = crypto.MarshalPublicKey(&sk.PublicKey) + // create signature source src := &testSignedDataSrc{ data: testData(t, 10), - key: &sk.PublicKey, + + signKeys: []SignKeyPair{signKey}, } var err error // calculate a signature - src.sig, err = crypto.Sign(sk, src.data) + signKey.Sign, err = crypto.Sign(sk, src.data) require.NoError(t, err) // ascertain that verification is passed require.NoError(t, VerifyAccumulatedSignatures(src)) // break the signature - src.sig[0]++ + signKey.Sign[0]++ // ascertain that verification is failed require.Error(t, VerifyAccumulatedSignatures(src)) @@ -238,9 +245,13 @@ func TestVerifySignatureWithKey(t *testing.T) { ErrEmptyDataWithSignature.Error(), ) + signKey := new(RequestVerificationHeader_Signature) + // create test signature source src := &testSignedDataSrc{ data: testData(t, 10), + + signKeys: []SignKeyPair{signKey}, } // nil public key @@ -255,14 +266,14 @@ func TestVerifySignatureWithKey(t *testing.T) { var err error // calculate a signature - src.sig, err = crypto.Sign(sk, src.data) + signKey.Sign, err = crypto.Sign(sk, src.data) require.NoError(t, err) // ascertain that verification is passed require.NoError(t, VerifySignatureWithKey(&sk.PublicKey, src)) // break the signature - src.sig[0]++ + signKey.Sign[0]++ // ascertain that verification is failed require.Error(t, VerifySignatureWithKey(&sk.PublicKey, src)) @@ -375,4 +386,15 @@ func TestSignVerifyRequestData(t *testing.T) { // ascertain that verification is passed require.NoError(t, VerifyRequestData(rdr)) + + if len(rdr.GetSignKeyPairs()) < 2 { + // add one more signature + require.NoError(t, SignRequestData(test.DecodeKey(1), rdr)) + } + + // change key-signature order + rdr.signKeys[0], rdr.signKeys[1] = rdr.signKeys[1], rdr.signKeys[0] + + // ascertain that verification is failed + require.Error(t, VerifyRequestData(src)) } diff --git a/service/types.go b/service/types.go index 75a5a0a..785a30a 100644 --- a/service/types.go +++ b/service/types.go @@ -262,6 +262,7 @@ type RequestData interface { type RequestSignedData interface { RequestData SignKeyPairAccumulator + SignKeyPairSource } // RequestVerifyData is an interface of request information with signature read access. diff --git a/service/verify.go b/service/verify.go index e1caa06..7691220 100644 --- a/service/verify.go +++ b/service/verify.go @@ -2,11 +2,16 @@ package service import ( "crypto/ecdsa" + "io" "github.com/nspcc-dev/neofs-api-go/internal" crypto "github.com/nspcc-dev/neofs-crypto" ) +type signKeyPairsWrapper struct { + items []SignKeyPair +} + // GetSessionToken returns SessionToken interface of Token field. // // If token field value is nil, nil returns. @@ -114,3 +119,48 @@ func (m RequestVerificationHeader) GetBearerToken() BearerToken { return nil } + +// SignKeyPairsSignedData wraps passed SignKeyPair slice and returns SignedDataSource interface. +func SignKeyPairsSignedData(v ...SignKeyPair) SignedDataSource { + return &signKeyPairsWrapper{ + items: v, + } +} + +// SignedData returns signed SignKeyPair slice in a binary representation. +func (s signKeyPairsWrapper) SignedData() ([]byte, error) { + return SignedDataFromReader(s) +} + +// SignedDataSize returns the length of signed SignKeyPair slice. +func (s signKeyPairsWrapper) SignedDataSize() (sz int) { + for i := range s.items { + // add key length + sz += len( + crypto.MarshalPublicKey(s.items[i].GetPublicKey()), + ) + } + + return +} + +// ReadSignedData copies a binary representation of the signed SignKeyPair slice to passed buffer. +// +// If buffer length is less than required, io.ErrUnexpectedEOF returns. +func (s signKeyPairsWrapper) ReadSignedData(p []byte) (int, error) { + sz := s.SignedDataSize() + if len(p) < sz { + return 0, io.ErrUnexpectedEOF + } + + off := 0 + + for i := range s.items { + // copy public key bytes + off += copy(p[off:], crypto.MarshalPublicKey( + s.items[i].GetPublicKey(), + )) + } + + return off, nil +} From 1dd4d48b5f8057cfc69df599403d4087fe61cf35 Mon Sep 17 00:00:00 2001 From: Pavel Korotkov Date: Tue, 7 Jul 2020 18:13:56 +0300 Subject: [PATCH 2/9] alc: add a rich functionality to manage Extended ACL --- acl/action.go | 38 ++ acl/action_test.go | 76 +++ acl/extended.go | 120 ++++ acl/header.go | 290 +++++++++ acl/headers_test.go | 59 ++ acl/match.go | 29 + acl/match_test.go | 44 ++ acl/types.go | 56 ++ acl/types.pb.go | 1350 +++++++++++++++++++++++++++++++++++++++++- acl/types.proto | 79 +++ acl/wrappers.go | 498 ++++++++++++++++ acl/wrappers_test.go | 139 +++++ 12 files changed, 2763 insertions(+), 15 deletions(-) create mode 100644 acl/action.go create mode 100644 acl/action_test.go create mode 100644 acl/extended.go create mode 100644 acl/header.go create mode 100644 acl/headers_test.go create mode 100644 acl/match.go create mode 100644 acl/match_test.go create mode 100644 acl/types.go create mode 100644 acl/wrappers.go create mode 100644 acl/wrappers_test.go diff --git a/acl/action.go b/acl/action.go new file mode 100644 index 0000000..b2986e2 --- /dev/null +++ b/acl/action.go @@ -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 +) diff --git a/acl/action_test.go b/acl/action_test.go new file mode 100644 index 0000000..83022e3 --- /dev/null +++ b/acl/action_test.go @@ -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 +} diff --git a/acl/extended.go b/acl/extended.go new file mode 100644 index 0000000..61ccbcf --- /dev/null +++ b/acl/extended.go @@ -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 +) diff --git a/acl/header.go b/acl/header.go new file mode 100644 index 0000000..9dff79e --- /dev/null +++ b/acl/header.go @@ -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 +} diff --git a/acl/headers_test.go b/acl/headers_test.go new file mode 100644 index 0000000..500d9a4 --- /dev/null +++ b/acl/headers_test.go @@ -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) + } +} diff --git a/acl/match.go b/acl/match.go new file mode 100644 index 0000000..bddee89 --- /dev/null +++ b/acl/match.go @@ -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() +} diff --git a/acl/match_test.go b/acl/match_test.go new file mode 100644 index 0000000..6975722 --- /dev/null +++ b/acl/match_test.go @@ -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 +} diff --git a/acl/types.go b/acl/types.go new file mode 100644 index 0000000..0587b9b --- /dev/null +++ b/acl/types.go @@ -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 +} diff --git a/acl/types.pb.go b/acl/types.pb.go index bcbd199..24ecf28 100644 --- a/acl/types.pb.go +++ b/acl/types.pb.go @@ -7,7 +7,9 @@ import ( fmt "fmt" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/golang/protobuf/proto" + io "io" math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. @@ -63,26 +65,1344 @@ func (Target) EnumDescriptor() ([]byte, []int) { return fileDescriptor_9b63aff5f3a35e32, []int{0} } +// Operation is an enumeration of operation types. +type EACLRecord_Operation int32 + +const ( + EACLRecord_OPERATION_UNKNOWN EACLRecord_Operation = 0 + EACLRecord_GET EACLRecord_Operation = 1 + EACLRecord_HEAD EACLRecord_Operation = 2 + EACLRecord_PUT EACLRecord_Operation = 3 + EACLRecord_DELETE EACLRecord_Operation = 4 + EACLRecord_SEARCH EACLRecord_Operation = 5 + EACLRecord_GETRANGE EACLRecord_Operation = 6 + EACLRecord_GETRANGEHASH EACLRecord_Operation = 7 +) + +var EACLRecord_Operation_name = map[int32]string{ + 0: "OPERATION_UNKNOWN", + 1: "GET", + 2: "HEAD", + 3: "PUT", + 4: "DELETE", + 5: "SEARCH", + 6: "GETRANGE", + 7: "GETRANGEHASH", +} + +var EACLRecord_Operation_value = map[string]int32{ + "OPERATION_UNKNOWN": 0, + "GET": 1, + "HEAD": 2, + "PUT": 3, + "DELETE": 4, + "SEARCH": 5, + "GETRANGE": 6, + "GETRANGEHASH": 7, +} + +func (x EACLRecord_Operation) String() string { + return proto.EnumName(EACLRecord_Operation_name, int32(x)) +} + +func (EACLRecord_Operation) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9b63aff5f3a35e32, []int{0, 0} +} + +// Action is an enumeration of EACL actions. +type EACLRecord_Action int32 + +const ( + EACLRecord_ActionUnknown EACLRecord_Action = 0 + EACLRecord_Allow EACLRecord_Action = 1 + EACLRecord_Deny EACLRecord_Action = 2 +) + +var EACLRecord_Action_name = map[int32]string{ + 0: "ActionUnknown", + 1: "Allow", + 2: "Deny", +} + +var EACLRecord_Action_value = map[string]int32{ + "ActionUnknown": 0, + "Allow": 1, + "Deny": 2, +} + +func (x EACLRecord_Action) String() string { + return proto.EnumName(EACLRecord_Action_name, int32(x)) +} + +func (EACLRecord_Action) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9b63aff5f3a35e32, []int{0, 1} +} + +// Header is an enumeration of filtering header types. +type EACLRecord_FilterInfo_Header int32 + +const ( + EACLRecord_FilterInfo_HeaderUnknown EACLRecord_FilterInfo_Header = 0 + EACLRecord_FilterInfo_Request EACLRecord_FilterInfo_Header = 1 + EACLRecord_FilterInfo_ObjectSystem EACLRecord_FilterInfo_Header = 2 + EACLRecord_FilterInfo_ObjectUser EACLRecord_FilterInfo_Header = 3 +) + +var EACLRecord_FilterInfo_Header_name = map[int32]string{ + 0: "HeaderUnknown", + 1: "Request", + 2: "ObjectSystem", + 3: "ObjectUser", +} + +var EACLRecord_FilterInfo_Header_value = map[string]int32{ + "HeaderUnknown": 0, + "Request": 1, + "ObjectSystem": 2, + "ObjectUser": 3, +} + +func (x EACLRecord_FilterInfo_Header) String() string { + return proto.EnumName(EACLRecord_FilterInfo_Header_name, int32(x)) +} + +func (EACLRecord_FilterInfo_Header) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9b63aff5f3a35e32, []int{0, 0, 0} +} + +// MatchType is an enumeration of match types. +type EACLRecord_FilterInfo_MatchType int32 + +const ( + EACLRecord_FilterInfo_MatchUnknown EACLRecord_FilterInfo_MatchType = 0 + EACLRecord_FilterInfo_StringEqual EACLRecord_FilterInfo_MatchType = 1 + EACLRecord_FilterInfo_StringNotEqual EACLRecord_FilterInfo_MatchType = 2 +) + +var EACLRecord_FilterInfo_MatchType_name = map[int32]string{ + 0: "MatchUnknown", + 1: "StringEqual", + 2: "StringNotEqual", +} + +var EACLRecord_FilterInfo_MatchType_value = map[string]int32{ + "MatchUnknown": 0, + "StringEqual": 1, + "StringNotEqual": 2, +} + +func (x EACLRecord_FilterInfo_MatchType) String() string { + return proto.EnumName(EACLRecord_FilterInfo_MatchType_name, int32(x)) +} + +func (EACLRecord_FilterInfo_MatchType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9b63aff5f3a35e32, []int{0, 0, 1} +} + +// EACLRecord groups information about extended ACL rule. +type EACLRecord struct { + // Operation carries type of operation. + Operation EACLRecord_Operation `protobuf:"varint,1,opt,name=operation,json=Operation,proto3,enum=acl.EACLRecord_Operation" json:"operation,omitempty"` + // Action carries ACL target action. + Action EACLRecord_Action `protobuf:"varint,2,opt,name=action,json=Action,proto3,enum=acl.EACLRecord_Action" json:"action,omitempty"` + // Filters carries set of filters. + Filters []*EACLRecord_FilterInfo `protobuf:"bytes,3,rep,name=Filters,proto3" json:"Filters,omitempty"` + // Targets carries information about extended ACL target list. + Targets []*EACLRecord_TargetInfo `protobuf:"bytes,4,rep,name=Targets,proto3" json:"Targets,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EACLRecord) Reset() { *m = EACLRecord{} } +func (m *EACLRecord) String() string { return proto.CompactTextString(m) } +func (*EACLRecord) ProtoMessage() {} +func (*EACLRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_9b63aff5f3a35e32, []int{0} +} +func (m *EACLRecord) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EACLRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *EACLRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_EACLRecord.Merge(m, src) +} +func (m *EACLRecord) XXX_Size() int { + return m.Size() +} +func (m *EACLRecord) XXX_DiscardUnknown() { + xxx_messageInfo_EACLRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_EACLRecord proto.InternalMessageInfo + +func (m *EACLRecord) GetOperation() EACLRecord_Operation { + if m != nil { + return m.Operation + } + return EACLRecord_OPERATION_UNKNOWN +} + +func (m *EACLRecord) GetAction() EACLRecord_Action { + if m != nil { + return m.Action + } + return EACLRecord_ActionUnknown +} + +func (m *EACLRecord) GetFilters() []*EACLRecord_FilterInfo { + if m != nil { + return m.Filters + } + return nil +} + +func (m *EACLRecord) GetTargets() []*EACLRecord_TargetInfo { + if m != nil { + return m.Targets + } + return nil +} + +// FilterInfo groups information about filter. +type EACLRecord_FilterInfo struct { + // Header carries type of header. + Header EACLRecord_FilterInfo_Header `protobuf:"varint,1,opt,name=header,json=HeaderType,proto3,enum=acl.EACLRecord_FilterInfo_Header" json:"header,omitempty"` + // MatchType carries type of match. + MatchType EACLRecord_FilterInfo_MatchType `protobuf:"varint,2,opt,name=matchType,json=MatchType,proto3,enum=acl.EACLRecord_FilterInfo_MatchType" json:"matchType,omitempty"` + // HeaderName carries name of filtering header. + HeaderName string `protobuf:"bytes,3,opt,name=HeaderName,json=Name,proto3" json:"HeaderName,omitempty"` + // HeaderVal carries value of filtering header. + HeaderVal string `protobuf:"bytes,4,opt,name=HeaderVal,json=Value,proto3" json:"HeaderVal,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EACLRecord_FilterInfo) Reset() { *m = EACLRecord_FilterInfo{} } +func (m *EACLRecord_FilterInfo) String() string { return proto.CompactTextString(m) } +func (*EACLRecord_FilterInfo) ProtoMessage() {} +func (*EACLRecord_FilterInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_9b63aff5f3a35e32, []int{0, 0} +} +func (m *EACLRecord_FilterInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EACLRecord_FilterInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *EACLRecord_FilterInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_EACLRecord_FilterInfo.Merge(m, src) +} +func (m *EACLRecord_FilterInfo) XXX_Size() int { + return m.Size() +} +func (m *EACLRecord_FilterInfo) XXX_DiscardUnknown() { + xxx_messageInfo_EACLRecord_FilterInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_EACLRecord_FilterInfo proto.InternalMessageInfo + +func (m *EACLRecord_FilterInfo) GetHeader() EACLRecord_FilterInfo_Header { + if m != nil { + return m.Header + } + return EACLRecord_FilterInfo_HeaderUnknown +} + +func (m *EACLRecord_FilterInfo) GetMatchType() EACLRecord_FilterInfo_MatchType { + if m != nil { + return m.MatchType + } + return EACLRecord_FilterInfo_MatchUnknown +} + +func (m *EACLRecord_FilterInfo) GetHeaderName() string { + if m != nil { + return m.HeaderName + } + return "" +} + +func (m *EACLRecord_FilterInfo) GetHeaderVal() string { + if m != nil { + return m.HeaderVal + } + return "" +} + +// TargetInfo groups information about extended ACL target. +type EACLRecord_TargetInfo struct { + // Target carries target of ACL rule. + Target Target `protobuf:"varint,1,opt,name=Target,json=Role,proto3,enum=acl.Target" json:"Target,omitempty"` + // KeyList carries public keys of ACL target. + KeyList [][]byte `protobuf:"bytes,2,rep,name=KeyList,json=Keys,proto3" json:"KeyList,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EACLRecord_TargetInfo) Reset() { *m = EACLRecord_TargetInfo{} } +func (m *EACLRecord_TargetInfo) String() string { return proto.CompactTextString(m) } +func (*EACLRecord_TargetInfo) ProtoMessage() {} +func (*EACLRecord_TargetInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_9b63aff5f3a35e32, []int{0, 1} +} +func (m *EACLRecord_TargetInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EACLRecord_TargetInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *EACLRecord_TargetInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_EACLRecord_TargetInfo.Merge(m, src) +} +func (m *EACLRecord_TargetInfo) XXX_Size() int { + return m.Size() +} +func (m *EACLRecord_TargetInfo) XXX_DiscardUnknown() { + xxx_messageInfo_EACLRecord_TargetInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_EACLRecord_TargetInfo proto.InternalMessageInfo + +func (m *EACLRecord_TargetInfo) GetTarget() Target { + if m != nil { + return m.Target + } + return Target_Unknown +} + +func (m *EACLRecord_TargetInfo) GetKeyList() [][]byte { + if m != nil { + return m.KeyList + } + return nil +} + +// EACLRecord carries the information about extended ACL rules. +type EACLTable struct { + // Records carries list of extended ACL rule records. + Records []*EACLRecord `protobuf:"bytes,1,rep,name=Records,proto3" json:"Records,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EACLTable) Reset() { *m = EACLTable{} } +func (m *EACLTable) String() string { return proto.CompactTextString(m) } +func (*EACLTable) ProtoMessage() {} +func (*EACLTable) Descriptor() ([]byte, []int) { + return fileDescriptor_9b63aff5f3a35e32, []int{1} +} +func (m *EACLTable) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EACLTable) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *EACLTable) XXX_Merge(src proto.Message) { + xxx_messageInfo_EACLTable.Merge(m, src) +} +func (m *EACLTable) XXX_Size() int { + return m.Size() +} +func (m *EACLTable) XXX_DiscardUnknown() { + xxx_messageInfo_EACLTable.DiscardUnknown(m) +} + +var xxx_messageInfo_EACLTable proto.InternalMessageInfo + +func (m *EACLTable) GetRecords() []*EACLRecord { + if m != nil { + return m.Records + } + return nil +} + func init() { proto.RegisterEnum("acl.Target", Target_name, Target_value) + proto.RegisterEnum("acl.EACLRecord_Operation", EACLRecord_Operation_name, EACLRecord_Operation_value) + proto.RegisterEnum("acl.EACLRecord_Action", EACLRecord_Action_name, EACLRecord_Action_value) + proto.RegisterEnum("acl.EACLRecord_FilterInfo_Header", EACLRecord_FilterInfo_Header_name, EACLRecord_FilterInfo_Header_value) + proto.RegisterEnum("acl.EACLRecord_FilterInfo_MatchType", EACLRecord_FilterInfo_MatchType_name, EACLRecord_FilterInfo_MatchType_value) + proto.RegisterType((*EACLRecord)(nil), "acl.EACLRecord") + proto.RegisterType((*EACLRecord_FilterInfo)(nil), "acl.EACLRecord.FilterInfo") + proto.RegisterType((*EACLRecord_TargetInfo)(nil), "acl.EACLRecord.TargetInfo") + proto.RegisterType((*EACLTable)(nil), "acl.EACLTable") } func init() { proto.RegisterFile("acl/types.proto", fileDescriptor_9b63aff5f3a35e32) } var fileDescriptor_9b63aff5f3a35e32 = []byte{ - // 216 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4f, 0x4c, 0xce, 0xd1, - 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4e, 0x4c, 0xce, - 0x91, 0xd2, 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0x4f, - 0xcf, 0xd7, 0x07, 0xcb, 0x25, 0x95, 0xa6, 0x81, 0x79, 0x60, 0x0e, 0x98, 0x05, 0xd1, 0xa3, 0xe5, - 0xcc, 0xc5, 0x16, 0x92, 0x58, 0x94, 0x9e, 0x5a, 0x22, 0xc4, 0xcd, 0xc5, 0x1e, 0x9a, 0x97, 0x9d, - 0x97, 0x5f, 0x9e, 0x27, 0xc0, 0x20, 0xc4, 0xc1, 0xc5, 0x12, 0x5a, 0x9c, 0x5a, 0x24, 0xc0, 0x28, - 0xc4, 0xc5, 0xc5, 0x16, 0x5c, 0x59, 0x5c, 0x92, 0x9a, 0x2b, 0xc0, 0x04, 0x62, 0xfb, 0x97, 0x64, - 0xa4, 0x16, 0x15, 0x0b, 0x30, 0x83, 0xd8, 0x01, 0xa5, 0x49, 0xde, 0xa9, 0x95, 0x02, 0x2c, 0x4e, - 0xde, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0x78, 0xe3, 0x91, 0x1c, 0xe3, 0x83, 0x47, - 0x72, 0x8c, 0x33, 0x1e, 0xcb, 0x31, 0x44, 0xa9, 0x22, 0xb9, 0x24, 0xaf, 0xb8, 0x20, 0x39, 0x59, - 0x37, 0x25, 0xb5, 0x4c, 0x3f, 0x2f, 0x35, 0x3f, 0xad, 0x58, 0x37, 0xb1, 0x20, 0x53, 0x37, 0x3d, - 0x5f, 0x3f, 0x31, 0x39, 0x67, 0x15, 0x13, 0xaf, 0x5f, 0x6a, 0xbe, 0x5b, 0xb0, 0x9e, 0x63, 0x80, - 0xa7, 0x9e, 0x63, 0x72, 0x4e, 0x12, 0x1b, 0xd8, 0x61, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xb3, 0xda, 0x09, 0x81, 0xdf, 0x00, 0x00, 0x00, + // 676 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xcd, 0x6e, 0xda, 0x58, + 0x14, 0x8e, 0x7f, 0x62, 0xc2, 0x01, 0x92, 0x9b, 0x2b, 0x65, 0xe4, 0x61, 0x41, 0x08, 0x9a, 0x91, + 0x98, 0x91, 0x30, 0xa3, 0x4c, 0xd5, 0x45, 0x77, 0x26, 0x31, 0x81, 0x92, 0x1a, 0x6a, 0x4c, 0x2a, + 0x75, 0x53, 0x5d, 0x9c, 0x1b, 0xa0, 0x35, 0xbe, 0xc4, 0x36, 0x89, 0x78, 0x93, 0x3e, 0x43, 0x9f, + 0xa4, 0xcb, 0x2e, 0xbb, 0x4a, 0x2b, 0xba, 0xef, 0x33, 0x54, 0xbe, 0x17, 0xc7, 0x51, 0xd4, 0x76, + 0xe5, 0xef, 0x3b, 0xbf, 0xf7, 0x7c, 0xe7, 0xc8, 0xb0, 0x47, 0x3c, 0xbf, 0x19, 0xaf, 0x16, 0x34, + 0x32, 0x16, 0x21, 0x8b, 0x19, 0x56, 0x88, 0xe7, 0x97, 0x1b, 0x93, 0x59, 0x3c, 0x5d, 0x8e, 0x0d, + 0x8f, 0xcd, 0x9b, 0x13, 0x36, 0x61, 0x4d, 0xee, 0x1b, 0x2f, 0xaf, 0x38, 0xe3, 0x84, 0x23, 0x91, + 0x53, 0xfb, 0xa2, 0x01, 0x58, 0xe6, 0xc9, 0xb9, 0x43, 0x3d, 0x16, 0x5e, 0xe2, 0x36, 0xe4, 0xd9, + 0x82, 0x86, 0x24, 0x9e, 0xb1, 0x40, 0x97, 0xaa, 0x52, 0x7d, 0xf7, 0xf8, 0x4f, 0x83, 0x78, 0xbe, + 0x91, 0xc5, 0x18, 0xfd, 0x34, 0xa0, 0x55, 0x5a, 0xdf, 0x1d, 0xe6, 0xef, 0xa9, 0x93, 0x41, 0xfc, + 0x0c, 0x34, 0xe2, 0xf1, 0x22, 0x32, 0x2f, 0xf2, 0xc7, 0xe3, 0x22, 0x26, 0xf7, 0xb6, 0x60, 0x7d, + 0x77, 0xa8, 0x09, 0xec, 0x6c, 0xbe, 0xf8, 0x09, 0xe4, 0xda, 0x33, 0x3f, 0xa6, 0x61, 0xa4, 0x2b, + 0x55, 0xa5, 0x5e, 0x38, 0x2e, 0x3f, 0x4e, 0x16, 0xee, 0x6e, 0x70, 0xc5, 0x9c, 0x34, 0x34, 0xc9, + 0x72, 0x49, 0x38, 0xa1, 0x71, 0xa4, 0xab, 0x3f, 0xcf, 0x12, 0x6e, 0x91, 0xb5, 0x09, 0x2d, 0x7f, + 0x97, 0x01, 0xb2, 0x6a, 0xb8, 0x0b, 0xda, 0x94, 0x92, 0x4b, 0x1a, 0x6e, 0x66, 0x3f, 0xfa, 0x75, + 0x67, 0xa3, 0xc3, 0x03, 0xc5, 0x04, 0x02, 0x3b, 0x20, 0xbe, 0xee, 0x6a, 0x41, 0xf1, 0x4b, 0xc8, + 0xcf, 0x49, 0xec, 0x4d, 0x13, 0xb2, 0x11, 0xe1, 0xaf, 0xdf, 0x54, 0x7b, 0x91, 0xc6, 0x0a, 0x51, + 0xef, 0xa9, 0x93, 0x41, 0xac, 0xc3, 0xa6, 0x81, 0x4d, 0xe6, 0x54, 0x57, 0xaa, 0x52, 0x3d, 0xef, + 0xa8, 0x09, 0xc6, 0x3a, 0xe4, 0x85, 0xe7, 0x82, 0xf8, 0xba, 0xca, 0x1d, 0xdb, 0x17, 0xc4, 0x5f, + 0xd2, 0xda, 0x73, 0xd8, 0x3c, 0x0e, 0xef, 0x43, 0x49, 0xa0, 0x51, 0xf0, 0x2e, 0x60, 0xb7, 0x01, + 0xda, 0xc2, 0x05, 0xc8, 0x39, 0xf4, 0x7a, 0x49, 0xa3, 0x18, 0x49, 0x18, 0x41, 0xb1, 0x3f, 0x7e, + 0x4b, 0xbd, 0x78, 0xb8, 0x8a, 0x62, 0x3a, 0x47, 0x32, 0xde, 0x05, 0x10, 0x96, 0x51, 0x44, 0x43, + 0xa4, 0xd4, 0x5a, 0xf0, 0xe0, 0x31, 0x08, 0x8a, 0x9c, 0x64, 0xd5, 0xf6, 0xa0, 0x30, 0x8c, 0xc3, + 0x59, 0x30, 0xb1, 0xae, 0x97, 0xc4, 0x47, 0x12, 0xc6, 0xb0, 0x2b, 0x0c, 0x36, 0x8b, 0x85, 0x4d, + 0x2e, 0xb7, 0x01, 0xb2, 0x3d, 0xe0, 0x23, 0xd0, 0x04, 0xdb, 0xe8, 0x5d, 0xe0, 0x0a, 0x09, 0x93, + 0xa3, 0x3a, 0xcc, 0xa7, 0xf8, 0x00, 0x72, 0x3d, 0xba, 0x3a, 0x9f, 0x45, 0xb1, 0x2e, 0x57, 0x95, + 0x7a, 0xd1, 0x51, 0x7b, 0x74, 0x15, 0xd5, 0x6e, 0xe0, 0xc1, 0xb5, 0x1d, 0xc0, 0x7e, 0x7f, 0x60, + 0x39, 0xa6, 0xdb, 0xed, 0xdb, 0x6f, 0x46, 0x76, 0xcf, 0xee, 0xbf, 0xb2, 0xd1, 0x16, 0xce, 0x81, + 0x72, 0x66, 0xb9, 0x48, 0xc2, 0x3b, 0xa0, 0x76, 0x2c, 0xf3, 0x14, 0xc9, 0x89, 0x69, 0x30, 0x72, + 0x91, 0x82, 0x01, 0xb4, 0x53, 0xeb, 0xdc, 0x72, 0x2d, 0xa4, 0x26, 0x78, 0x68, 0x99, 0xce, 0x49, + 0x07, 0x6d, 0xe3, 0x22, 0xec, 0x9c, 0x59, 0xae, 0x63, 0xda, 0x67, 0x16, 0xd2, 0x92, 0x21, 0x53, + 0xd6, 0x31, 0x87, 0x1d, 0x94, 0xab, 0xfd, 0x07, 0xe9, 0x99, 0xee, 0x43, 0x49, 0xa0, 0x4c, 0x81, + 0x3c, 0x6c, 0x9b, 0xbe, 0xcf, 0x6e, 0x45, 0xcb, 0x53, 0x1a, 0xac, 0x90, 0x5c, 0x7b, 0x0a, 0xf9, + 0x64, 0xe5, 0x2e, 0x19, 0xfb, 0x14, 0xff, 0x93, 0x28, 0x9e, 0xec, 0x3e, 0xd2, 0x25, 0x7e, 0xa5, + 0x7b, 0x8f, 0x6e, 0xc2, 0x49, 0xfd, 0xff, 0x9e, 0xa4, 0xda, 0x24, 0x6b, 0xca, 0x7a, 0xec, 0x80, + 0xca, 0xd7, 0x21, 0xf1, 0x67, 0xa7, 0xab, 0x02, 0xd0, 0xfa, 0xf1, 0x94, 0x86, 0x91, 0x18, 0x6d, + 0xb0, 0x1c, 0xf7, 0xe8, 0x0a, 0xa9, 0xad, 0xde, 0xc7, 0x75, 0x45, 0xfa, 0xb4, 0xae, 0x48, 0x9f, + 0xd7, 0x15, 0xe9, 0xeb, 0xba, 0x22, 0xbd, 0xff, 0x56, 0xd9, 0x7a, 0xfd, 0xf7, 0x83, 0x7f, 0x44, + 0x10, 0x2d, 0x3c, 0xaf, 0x71, 0x49, 0x6f, 0x9a, 0x01, 0x65, 0x57, 0x51, 0x83, 0x2c, 0x66, 0x8d, + 0x09, 0x6b, 0x12, 0xcf, 0xff, 0x20, 0x97, 0x6c, 0xca, 0xda, 0x43, 0xc3, 0x1c, 0x74, 0x0d, 0xd3, + 0xf3, 0xc7, 0x1a, 0xff, 0x65, 0xfc, 0xff, 0x23, 0x00, 0x00, 0xff, 0xff, 0x39, 0x7b, 0x27, 0xe6, + 0x79, 0x04, 0x00, 0x00, } + +func (m *EACLRecord) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EACLRecord) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EACLRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Targets) > 0 { + for iNdEx := len(m.Targets) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Targets[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.Filters) > 0 { + for iNdEx := len(m.Filters) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Filters[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.Action != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Action)) + i-- + dAtA[i] = 0x10 + } + if m.Operation != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Operation)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *EACLRecord_FilterInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EACLRecord_FilterInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EACLRecord_FilterInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.HeaderVal) > 0 { + i -= len(m.HeaderVal) + copy(dAtA[i:], m.HeaderVal) + i = encodeVarintTypes(dAtA, i, uint64(len(m.HeaderVal))) + i-- + dAtA[i] = 0x22 + } + if len(m.HeaderName) > 0 { + i -= len(m.HeaderName) + copy(dAtA[i:], m.HeaderName) + i = encodeVarintTypes(dAtA, i, uint64(len(m.HeaderName))) + i-- + dAtA[i] = 0x1a + } + if m.MatchType != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.MatchType)) + i-- + dAtA[i] = 0x10 + } + if m.Header != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Header)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *EACLRecord_TargetInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EACLRecord_TargetInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EACLRecord_TargetInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.KeyList) > 0 { + for iNdEx := len(m.KeyList) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.KeyList[iNdEx]) + copy(dAtA[i:], m.KeyList[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.KeyList[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if m.Target != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Target)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *EACLTable) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EACLTable) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EACLTable) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Records) > 0 { + for iNdEx := len(m.Records) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Records[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { + offset -= sovTypes(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *EACLRecord) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Operation != 0 { + n += 1 + sovTypes(uint64(m.Operation)) + } + if m.Action != 0 { + n += 1 + sovTypes(uint64(m.Action)) + } + if len(m.Filters) > 0 { + for _, e := range m.Filters { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Targets) > 0 { + for _, e := range m.Targets { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *EACLRecord_FilterInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Header != 0 { + n += 1 + sovTypes(uint64(m.Header)) + } + if m.MatchType != 0 { + n += 1 + sovTypes(uint64(m.MatchType)) + } + l = len(m.HeaderName) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.HeaderVal) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *EACLRecord_TargetInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Target != 0 { + n += 1 + sovTypes(uint64(m.Target)) + } + if len(m.KeyList) > 0 { + for _, b := range m.KeyList { + l = len(b) + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *EACLTable) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Records) > 0 { + for _, e := range m.Records { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovTypes(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTypes(x uint64) (n int) { + return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *EACLRecord) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EACLRecord: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EACLRecord: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Operation", wireType) + } + m.Operation = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Operation |= EACLRecord_Operation(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + m.Action = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Action |= EACLRecord_Action(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Filters = append(m.Filters, &EACLRecord_FilterInfo{}) + if err := m.Filters[len(m.Filters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Targets", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Targets = append(m.Targets, &EACLRecord_TargetInfo{}) + if err := m.Targets[len(m.Targets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EACLRecord_FilterInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FilterInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FilterInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + m.Header = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Header |= EACLRecord_FilterInfo_Header(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchType", wireType) + } + m.MatchType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MatchType |= EACLRecord_FilterInfo_MatchType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HeaderName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HeaderName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HeaderVal", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HeaderVal = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EACLRecord_TargetInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TargetInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TargetInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + } + m.Target = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Target |= Target(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyList", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyList = append(m.KeyList, make([]byte, postIndex-iNdEx)) + copy(m.KeyList[len(m.KeyList)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EACLTable) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EACLTable: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EACLTable: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Records = append(m.Records, &EACLRecord{}) + if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTypes(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTypes + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTypes + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTypes + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTypes = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTypes = fmt.Errorf("proto: unexpected end of group") +) diff --git a/acl/types.proto b/acl/types.proto index f20423f..6934b36 100644 --- a/acl/types.proto +++ b/acl/types.proto @@ -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"]; +} \ No newline at end of file diff --git a/acl/wrappers.go b/acl/wrappers.go new file mode 100644 index 0000000..b0481f4 --- /dev/null +++ b/acl/wrappers.go @@ -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) +} diff --git a/acl/wrappers_test.go b/acl/wrappers_test.go new file mode 100644 index 0000000..b7dbbe0 --- /dev/null +++ b/acl/wrappers_test.go @@ -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()) + } + } +} From ec4fb22e30f26319e162d6454d7b2b28974220bb Mon Sep 17 00:00:00 2001 From: Pavel Korotkov Date: Tue, 7 Jul 2020 18:17:50 +0300 Subject: [PATCH 3/9] acl: fix an erroneous method name in comments --- acl/wrappers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acl/wrappers.go b/acl/wrappers.go index b0481f4..30c2ee3 100644 --- a/acl/wrappers.go +++ b/acl/wrappers.go @@ -238,7 +238,7 @@ func (s EACLTargetWrapper) SetKeyList(v [][]byte) { } } -// KeyList returns casted result of Operation field getter. +// OperationType returns casted result of Operation field getter. // // If record is not initialized, 0 returns. // From 0db55d31ae0a24a7a603d827522d6960381b582f Mon Sep 17 00:00:00 2001 From: Pavel Korotkov Date: Tue, 7 Jul 2020 19:43:16 +0300 Subject: [PATCH 4/9] acl: remove tests --- acl/action_test.go | 76 --------------------------------------------- acl/headers_test.go | 59 ----------------------------------- acl/match_test.go | 44 -------------------------- 3 files changed, 179 deletions(-) delete mode 100644 acl/action_test.go delete mode 100644 acl/headers_test.go delete mode 100644 acl/match_test.go diff --git a/acl/action_test.go b/acl/action_test.go deleted file mode 100644 index 83022e3..0000000 --- a/acl/action_test.go +++ /dev/null @@ -1,76 +0,0 @@ -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 -} diff --git a/acl/headers_test.go b/acl/headers_test.go deleted file mode 100644 index 500d9a4..0000000 --- a/acl/headers_test.go +++ /dev/null @@ -1,59 +0,0 @@ -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) - } -} diff --git a/acl/match_test.go b/acl/match_test.go deleted file mode 100644 index 6975722..0000000 --- a/acl/match_test.go +++ /dev/null @@ -1,44 +0,0 @@ -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 -} From d0f56e504448b2f820e1c79038796b2d2ac3b5cf Mon Sep 17 00:00:00 2001 From: Pavel Korotkov Date: Tue, 7 Jul 2020 19:44:09 +0300 Subject: [PATCH 5/9] acl: reorganize files --- acl/action.go | 38 ------ acl/header.go | 290 ------------------------------------------- acl/match.go | 29 ----- acl/types.go | 116 +++++++++++++++++ acl/wrappers.go | 8 +- acl/wrappers_test.go | 2 +- 6 files changed, 121 insertions(+), 362 deletions(-) delete mode 100644 acl/action.go delete mode 100644 acl/header.go delete mode 100644 acl/match.go diff --git a/acl/action.go b/acl/action.go deleted file mode 100644 index b2986e2..0000000 --- a/acl/action.go +++ /dev/null @@ -1,38 +0,0 @@ -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 -) diff --git a/acl/header.go b/acl/header.go deleted file mode 100644 index 9dff79e..0000000 --- a/acl/header.go +++ /dev/null @@ -1,290 +0,0 @@ -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 -} diff --git a/acl/match.go b/acl/match.go deleted file mode 100644 index bddee89..0000000 --- a/acl/match.go +++ /dev/null @@ -1,29 +0,0 @@ -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() -} diff --git a/acl/types.go b/acl/types.go index 0587b9b..6a418bc 100644 --- a/acl/types.go +++ b/acl/types.go @@ -1,5 +1,121 @@ package acl +import ( + "github.com/nspcc-dev/neofs-api-go/object" + "github.com/nspcc-dev/neofs-api-go/service" +) + +const ( + _ MatchType = iota + stringEqual + stringNotEqual +) + +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 +) + +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" +) + +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 +} + +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 +} + // SetMatchType is MatchType field setter. func (m *EACLRecord_FilterInfo) SetMatchType(v EACLRecord_FilterInfo_MatchType) { m.MatchType = v diff --git a/acl/wrappers.go b/acl/wrappers.go index 30c2ee3..94e420a 100644 --- a/acl/wrappers.go +++ b/acl/wrappers.go @@ -83,9 +83,9 @@ func (s EACLFilterWrapper) MatchType() (res MatchType) { if s.filter != nil { switch s.filter.GetMatchType() { case EACLRecord_FilterInfo_StringEqual: - res = StringEqual + res = stringEqual case EACLRecord_FilterInfo_StringNotEqual: - res = StringNotEqual + res = stringNotEqual } } @@ -102,9 +102,9 @@ func (s EACLFilterWrapper) MatchType() (res MatchType) { func (s EACLFilterWrapper) SetMatchType(v MatchType) { if s.filter != nil { switch v { - case StringEqual: + case stringEqual: s.filter.SetMatchType(EACLRecord_FilterInfo_StringEqual) - case StringNotEqual: + case stringNotEqual: s.filter.SetMatchType(EACLRecord_FilterInfo_StringNotEqual) default: s.filter.SetMatchType(EACLRecord_FilterInfo_MatchUnknown) diff --git a/acl/wrappers_test.go b/acl/wrappers_test.go index b7dbbe0..a55db8c 100644 --- a/acl/wrappers_test.go +++ b/acl/wrappers_test.go @@ -9,7 +9,7 @@ import ( func TestEACLFilterWrapper(t *testing.T) { s := WrapFilterInfo(nil) - mt := StringEqual + mt := stringEqual s.SetMatchType(mt) require.Equal(t, mt, s.MatchType()) From f82651720726fe9fdc27f7f4fffa5b56b793e4d9 Mon Sep 17 00:00:00 2001 From: Pavel Korotkov Date: Tue, 7 Jul 2020 22:16:56 +0300 Subject: [PATCH 6/9] acl: delete unused types --- acl/extended.go | 27 --------------------------- acl/types.go | 46 ---------------------------------------------- 2 files changed, 73 deletions(-) diff --git a/acl/extended.go b/acl/extended.go index 61ccbcf..df8402a 100644 --- a/acl/extended.go +++ b/acl/extended.go @@ -1,11 +1,5 @@ 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 @@ -35,13 +29,6 @@ type TypedHeader interface { 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. @@ -80,20 +67,6 @@ type ExtendedACLTable interface { 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 diff --git a/acl/types.go b/acl/types.go index 6a418bc..c9bbfd3 100644 --- a/acl/types.go +++ b/acl/types.go @@ -1,10 +1,5 @@ package acl -import ( - "github.com/nspcc-dev/neofs-api-go/object" - "github.com/nspcc-dev/neofs-api-go/service" -) - const ( _ MatchType = iota stringEqual @@ -75,47 +70,6 @@ const ( HdrObjSysLinkSG = "LINK_SG" ) -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 -} - -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 -} - // SetMatchType is MatchType field setter. func (m *EACLRecord_FilterInfo) SetMatchType(v EACLRecord_FilterInfo_MatchType) { m.MatchType = v From 2fba8cb7b33f8cdc1396a143aa6684e69b230eba Mon Sep 17 00:00:00 2001 From: Pavel Korotkov Date: Tue, 7 Jul 2020 23:03:53 +0300 Subject: [PATCH 7/9] acl: make MatchType's constants public back --- acl/types.go | 8 ++++++-- acl/wrappers.go | 8 ++++---- acl/wrappers_test.go | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/acl/types.go b/acl/types.go index c9bbfd3..c80c9cd 100644 --- a/acl/types.go +++ b/acl/types.go @@ -2,8 +2,12 @@ package acl const ( _ MatchType = iota - stringEqual - stringNotEqual + + // StringEqual is a MatchType of string equality. + StringEqual + + // StringNotEqual is a MatchType of string inequality. + StringNotEqual ) const ( diff --git a/acl/wrappers.go b/acl/wrappers.go index 94e420a..30c2ee3 100644 --- a/acl/wrappers.go +++ b/acl/wrappers.go @@ -83,9 +83,9 @@ func (s EACLFilterWrapper) MatchType() (res MatchType) { if s.filter != nil { switch s.filter.GetMatchType() { case EACLRecord_FilterInfo_StringEqual: - res = stringEqual + res = StringEqual case EACLRecord_FilterInfo_StringNotEqual: - res = stringNotEqual + res = StringNotEqual } } @@ -102,9 +102,9 @@ func (s EACLFilterWrapper) MatchType() (res MatchType) { func (s EACLFilterWrapper) SetMatchType(v MatchType) { if s.filter != nil { switch v { - case stringEqual: + case StringEqual: s.filter.SetMatchType(EACLRecord_FilterInfo_StringEqual) - case stringNotEqual: + case StringNotEqual: s.filter.SetMatchType(EACLRecord_FilterInfo_StringNotEqual) default: s.filter.SetMatchType(EACLRecord_FilterInfo_MatchUnknown) diff --git a/acl/wrappers_test.go b/acl/wrappers_test.go index a55db8c..b7dbbe0 100644 --- a/acl/wrappers_test.go +++ b/acl/wrappers_test.go @@ -9,7 +9,7 @@ import ( func TestEACLFilterWrapper(t *testing.T) { s := WrapFilterInfo(nil) - mt := stringEqual + mt := StringEqual s.SetMatchType(mt) require.Equal(t, mt, s.MatchType()) From 504804f80604ad8c2222300dbd5266a9b76308d6 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Wed, 8 Jul 2020 10:50:58 +0300 Subject: [PATCH 8/9] Update to neofs-api v1.2.0 --- Makefile | 2 +- acl/types.proto | 2 +- docs/acl.md | 116 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 117 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 159c7e3..600586e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PROTO_VERSION=v1.1.0 +PROTO_VERSION=v1.2.0 PROTO_URL=https://github.com/nspcc-dev/neofs-api/archive/$(PROTO_VERSION).tar.gz B=\033[0;1m diff --git a/acl/types.proto b/acl/types.proto index 6934b36..7f3efc9 100644 --- a/acl/types.proto +++ b/acl/types.proto @@ -103,4 +103,4 @@ message EACLRecord { message EACLTable { // Records carries list of extended ACL rule records. repeated EACLRecord Records = 1 [json_name="Records"]; -} \ No newline at end of file +} diff --git a/docs/acl.md b/docs/acl.md index 38f328b..f63758b 100644 --- a/docs/acl.md +++ b/docs/acl.md @@ -5,7 +5,12 @@ - [acl/types.proto](#acl/types.proto) - + - Messages + - [EACLRecord](#acl.EACLRecord) + - [EACLRecord.FilterInfo](#acl.EACLRecord.FilterInfo) + - [EACLRecord.TargetInfo](#acl.EACLRecord.TargetInfo) + - [EACLTable](#acl.EACLTable) + - [Scalar Value Types](#scalar-value-types) @@ -19,9 +24,118 @@ + + + +### Message EACLRecord +EACLRecord groups information about extended ACL rule. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| operation | [EACLRecord.Operation](#acl.EACLRecord.Operation) | | Operation carries type of operation. | +| action | [EACLRecord.Action](#acl.EACLRecord.Action) | | Action carries ACL target action. | +| Filters | [EACLRecord.FilterInfo](#acl.EACLRecord.FilterInfo) | repeated | Filters carries set of filters. | +| Targets | [EACLRecord.TargetInfo](#acl.EACLRecord.TargetInfo) | repeated | Targets carries information about extended ACL target list. | + + + + +### Message EACLRecord.FilterInfo +FilterInfo groups information about filter. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [EACLRecord.FilterInfo.Header](#acl.EACLRecord.FilterInfo.Header) | | Header carries type of header. | +| matchType | [EACLRecord.FilterInfo.MatchType](#acl.EACLRecord.FilterInfo.MatchType) | | MatchType carries type of match. | +| HeaderName | [string](#string) | | HeaderName carries name of filtering header. | +| HeaderVal | [string](#string) | | HeaderVal carries value of filtering header. | + + + + +### Message EACLRecord.TargetInfo +TargetInfo groups information about extended ACL target. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| Target | [Target](#acl.Target) | | Target carries target of ACL rule. | +| KeyList | [bytes](#bytes) | repeated | KeyList carries public keys of ACL target. | + + + + +### Message EACLTable +EACLRecord carries the information about extended ACL rules. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| Records | [EACLRecord](#acl.EACLRecord) | repeated | Records carries list of extended ACL rule records. | + + + +### EACLRecord.Action +Action is an enumeration of EACL actions. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| ActionUnknown | 0 | | +| Allow | 1 | | +| Deny | 2 | | + + + + + +### EACLRecord.FilterInfo.Header +Header is an enumeration of filtering header types. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| HeaderUnknown | 0 | | +| Request | 1 | | +| ObjectSystem | 2 | | +| ObjectUser | 3 | | + + + + + +### EACLRecord.FilterInfo.MatchType +MatchType is an enumeration of match types. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| MatchUnknown | 0 | | +| StringEqual | 1 | | +| StringNotEqual | 2 | | + + + + + +### EACLRecord.Operation +Operation is an enumeration of operation types. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| OPERATION_UNKNOWN | 0 | | +| GET | 1 | | +| HEAD | 2 | | +| PUT | 3 | | +| DELETE | 4 | | +| SEARCH | 5 | | +| GETRANGE | 6 | | +| GETRANGEHASH | 7 | | + + + ### Target From 2bf5a0c30b228e68e567bbb1f12716e77b0eb46a Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Wed, 8 Jul 2020 11:09:29 +0300 Subject: [PATCH 9/9] Update changelog and readme for v1.2.0 --- CHANGELOG.md | 18 ++++++++++++++++++ README.md | 6 +++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e771c19..898dcce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ # Changelog This is the changelog for NeoFS-API-Go +## [1.2.0] - 2020-07-08 + +### Added + +- Extended ACL types. +- Getters and setters of ```EACLTable``` and its internal messages. +- Wrappers over ```EACLTable``` and its internal messages. +- Getters, setters and marshaling methods of wrappers. + +### Changed + +- Mechanism for signing requests on the principle of Matryoshka. + +### Updated + +- NeoFS API v1.1.0 => 1.2.0 + ## [1.1.0] - 2020-06-18 ### Added @@ -357,3 +374,4 @@ Initial public release [0.7.6]: https://github.com/nspcc-dev/neofs-api-go/compare/v0.7.5...v0.7.6 [1.0.0]: https://github.com/nspcc-dev/neofs-api-go/compare/v0.7.6...v1.0.0 [1.1.0]: https://github.com/nspcc-dev/neofs-api-go/compare/v1.0.0...v1.1.0 +[1.2.0]: https://github.com/nspcc-dev/neofs-api-go/compare/v1.1.0...v1.2.0 diff --git a/README.md b/README.md index d44e057..4c768b2 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,11 @@ can be used for integration with NeoFS. [neofs-api v1.1.0]: https://github.com/nspcc-dev/neofs-api/releases/tag/v1.1.0 [neofs-api-go v1.1.0]: https://github.com/nspcc-dev/neofs-api-go/releases/tag/v1.1.0 -[neofs-api-go v1.1.0] supports [neofs-api v1.1.0] +* [neofs-api-go v1.1.0] supports [neofs-api v1.1.0] + +[neofs-api v1.2.0]: https://github.com/nspcc-dev/neofs-api/releases/tag/v1.2.0 +[neofs-api-go v1.2.0]: https://github.com/nspcc-dev/neofs-api-go/releases/tag/v1.2.0 +* [neofs-api-go v1.2.0] supports [neofs-api v1.2.0] ## Description