Merge remote-tracking branch 'origin/acl-sync' into acl-invite

# Conflicts:
#	common/commonspace/service.go
#	common/pkg/acl/aclrecordproto/aclrecord.pb.go
#	common/pkg/acl/aclrecordproto/protos/aclrecord.proto
#	common/pkg/acl/list/list.go
#	common/pkg/acl/storage/inmemory.go
#	common/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go
#	node/nodespace/rpchandler.go
#	node/nodespace/service.go
This commit is contained in:
mcrakhman 2022-11-07 12:36:48 +01:00
commit 354ee3b6c7
No known key found for this signature in database
GPG Key ID: DED12CFEF5B8396B
39 changed files with 1707 additions and 242 deletions

View File

@ -42,7 +42,7 @@ func (s *service) Init(a *app.App) (err error) {
s.spaceStorageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider)
s.spaceCache = ocache.New(
func(ctx context.Context, id string) (value ocache.Object, err error) {
return s.commonSpace.GetSpace(ctx, id)
return s.commonSpace.NewSpace(ctx, id)
},
ocache.WithLogger(log.Sugar()),
ocache.WithGCPeriod(time.Minute),

View File

@ -77,7 +77,7 @@ func createListStorage(spaceId string, db *badger.DB, txn *badger.Txn, root *acl
return
}
func (l *listStorage) ID() string {
func (l *listStorage) Id() string {
return l.id
}

View File

@ -10,7 +10,7 @@ import (
)
func testList(t *testing.T, store storage.ListStorage, root *aclrecordproto.RawACLRecordWithId, head string) {
require.Equal(t, store.ID(), root.Id)
require.Equal(t, store.Id(), root.Id)
aclRoot, err := store.Root()
require.NoError(t, err)

View File

@ -3,7 +3,7 @@ package storage
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"github.com/dgraph-io/badger/v3"
"sync"
)
@ -12,7 +12,7 @@ type spaceStorage struct {
spaceId string
objDb *badger.DB
keys spaceKeys
aclStorage storage2.ListStorage
aclStorage storage.ListStorage
header *spacesyncproto.RawSpaceHeaderWithId
mx sync.Mutex
}
@ -77,15 +77,15 @@ func createSpaceStorage(db *badger.DB, payload spacestorage.SpaceStorageCreatePa
return
}
func (s *spaceStorage) ID() string {
func (s *spaceStorage) Id() string {
return s.spaceId
}
func (s *spaceStorage) TreeStorage(id string) (storage2.TreeStorage, error) {
func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) {
return newTreeStorage(s.objDb, s.spaceId, id)
}
func (s *spaceStorage) CreateTreeStorage(payload storage2.TreeStorageCreatePayload) (ts storage2.TreeStorage, err error) {
func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) {
// we have mutex here, so we prevent overwriting the heads of a tree on concurrent creation
s.mx.Lock()
defer s.mx.Unlock()
@ -93,7 +93,7 @@ func (s *spaceStorage) CreateTreeStorage(payload storage2.TreeStorageCreatePaylo
return createTreeStorage(s.objDb, s.spaceId, payload)
}
func (s *spaceStorage) ACLStorage() (storage2.ListStorage, error) {
func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) {
return s.aclStorage, nil
}

View File

@ -2,7 +2,7 @@ package storage
import (
"context"
storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
"github.com/dgraph-io/badger/v3"
)
@ -88,7 +88,7 @@ func createTreeStorage(db *badger.DB, spaceId string, payload storage.TreeStorag
return
}
func (t *treeStorage) ID() string {
func (t *treeStorage) Id() string {
return t.id
}

View File

@ -27,7 +27,7 @@ type fixture struct {
}
func testTreePayload(t *testing.T, store storage.TreeStorage, payload storage.TreeStorageCreatePayload) {
require.Equal(t, payload.RootRawChange.Id, store.ID())
require.Equal(t, payload.RootRawChange.Id, store.Id())
root, err := store.Root()
require.NoError(t, err)

View File

@ -10,7 +10,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
config2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
@ -28,13 +28,13 @@ func New() Service {
type Service interface {
DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (string, error)
CreateSpace(ctx context.Context, payload SpaceCreatePayload) (string, error)
GetSpace(ctx context.Context, id string) (sp Space, err error)
NewSpace(ctx context.Context, id string) (sp Space, err error)
AddSpace(ctx context.Context, spaceDescription SpaceDescription) (err error)
app.Component
}
type service struct {
config config2.Space
config config.Space
account account.Service
configurationService nodeconf.Service
storageProvider storage.SpaceStorageProvider
@ -43,7 +43,7 @@ type service struct {
}
func (s *service) Init(a *app.App) (err error) {
s.config = a.MustComponent(config2.CName).(*config2.Config).Space
s.config = a.MustComponent(config.CName).(*config.Config).Space
s.account = a.MustComponent(account.CName).(account.Service)
s.storageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider)
s.configurationService = a.MustComponent(nodeconf.CName).(nodeconf.Service)
@ -56,9 +56,7 @@ func (s *service) Name() (name string) {
return CName
}
func (s *service) CreateSpace(
ctx context.Context,
payload SpaceCreatePayload) (id string, err error) {
func (s *service) CreateSpace(ctx context.Context, payload SpaceCreatePayload) (id string, err error) {
storageCreate, err := storagePayloadForSpaceCreate(payload)
if err != nil {
return
@ -68,12 +66,10 @@ func (s *service) CreateSpace(
return
}
return store.ID(), nil
return store.Id(), nil
}
func (s *service) DeriveSpace(
ctx context.Context,
payload SpaceDerivePayload) (id string, err error) {
func (s *service) DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (id string, err error) {
storageCreate, err := storagePayloadForSpaceDerive(payload)
if err != nil {
return
@ -83,7 +79,7 @@ func (s *service) DeriveSpace(
return
}
return store.ID(), nil
return store.Id(), nil
}
func (s *service) AddSpace(ctx context.Context, spaceDescription SpaceDescription) (err error) {
@ -116,7 +112,7 @@ func (s *service) AddSpace(ctx context.Context, spaceDescription SpaceDescriptio
return
}
func (s *service) GetSpace(ctx context.Context, id string) (Space, error) {
func (s *service) NewSpace(ctx context.Context, id string) (Space, error) {
st, err := s.storageProvider.SpaceStorage(id)
if err != nil {
if err != spacesyncproto.ErrSpaceMissing {
@ -143,32 +139,23 @@ func (s *service) GetSpace(ctx context.Context, id string) (Space, error) {
configuration: lastConfiguration,
storage: st,
}
if err := sp.Init(ctx); err != nil {
return nil, err
}
return sp, nil
}
func (s *service) getSpaceStorageFromRemote(ctx context.Context, id string) (st storage.SpaceStorage, err error) {
var p peer.Peer
peerId, err := syncservice.GetPeerIdFromStreamContext(ctx)
if err == nil {
p, err = s.pool.Dial(ctx, peerId)
if err != nil {
return
}
} else {
lastConfiguration := s.configurationService.GetLast()
// for nodes we always get remote space only if we have id in the context
if lastConfiguration.IsResponsible(id) {
err = spacesyncproto.ErrSpaceMissing
return
}
p, err = s.pool.DialOneOf(ctx, lastConfiguration.NodeIds(id))
if err != nil {
return
}
lastConfiguration := s.configurationService.GetLast()
// for nodes we always get remote space only if we have id in the context
if lastConfiguration.IsResponsible(id) {
err = spacesyncproto.ErrSpaceMissing
return
}
p, err = s.pool.DialOneOf(ctx, lastConfiguration.NodeIds(id))
if err != nil {
return
}
cl := spacesyncproto.NewDRPCSpaceClient(p)
res, err := cl.PullSpace(ctx, &spacesyncproto.PullSpaceRequest{Id: id})
if err != nil {

View File

@ -15,9 +15,10 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey"
"github.com/zeebo/errs"
"go.uber.org/zap"
"sync"
"sync/atomic"
@ -58,6 +59,8 @@ func NewSpaceId(id string, repKey uint64) string {
type Space interface {
Id() string
Init(ctx context.Context) error
StoredIds() []string
Description() SpaceDescription
@ -206,7 +209,18 @@ func (s *space) Close() error {
s.isClosed.Store(true)
log.With(zap.String("id", s.id)).Debug("space closed")
}()
s.diffService.Close()
s.syncService.Close()
return s.storage.Close()
var mError errs.Group
if err := s.diffService.Close(); err != nil {
mError.Add(err)
}
if err := s.syncService.Close(); err != nil {
mError.Add(err)
}
if err := s.aclList.Close(); err != nil {
mError.Add(err)
}
if err := s.storage.Close(); err != nil {
mError.Add(err)
}
return mError.Err()
}

View File

@ -162,18 +162,18 @@ func (mr *MockSpaceStorageMockRecorder) CreateTreeStorage(arg0 interface{}) *gom
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTreeStorage", reflect.TypeOf((*MockSpaceStorage)(nil).CreateTreeStorage), arg0)
}
// ID mocks base method.
func (m *MockSpaceStorage) ID() string {
// Id mocks base method.
func (m *MockSpaceStorage) Id() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ID")
ret := m.ctrl.Call(m, "Id")
ret0, _ := ret[0].(string)
return ret0
}
// ID indicates an expected call of ID.
func (mr *MockSpaceStorageMockRecorder) ID() *gomock.Call {
// Id indicates an expected call of Id.
func (mr *MockSpaceStorageMockRecorder) Id() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockSpaceStorage)(nil).ID))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockSpaceStorage)(nil).Id))
}
// SpaceHeader mocks base method.

View File

@ -6,7 +6,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
)
const CName = "commonspace.storage"
@ -16,7 +16,7 @@ var ErrSpaceStorageMissing = errors.New("space storage missing")
type SpaceStorage interface {
storage.Provider
ID() string
Id() string
ACLStorage() (storage.ListStorage, error)
SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error)
StoredIds() ([]string, error)

View File

@ -0,0 +1,31 @@
package syncacl
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
)
type syncAclHandler struct {
acl list.ACLList
}
func (s *syncAclHandler) HandleMessage(ctx context.Context, senderId string, req *spacesyncproto.ObjectSyncMessage) (err error) {
aclMsg := &aclrecordproto.ACLSyncMessage{}
if err = aclMsg.Unmarshal(req.Payload); err != nil {
return
}
content := aclMsg.GetContent()
switch {
case content.GetAddRecords() != nil:
return s.handleAddRecords(ctx, senderId, content.GetAddRecords())
default:
return fmt.Errorf("unexpected aclSync message: %T", content.Value)
}
}
func (s *syncAclHandler) handleAddRecords(ctx context.Context, senderId string, addRecord *aclrecordproto.ACLAddRecords) (err error) {
return
}

View File

@ -51,8 +51,10 @@ func (ACLUserPermissions) EnumDescriptor() ([]byte, []int) {
}
type RawACLRecord struct {
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
AcceptorIdentity []byte `protobuf:"bytes,3,opt,name=acceptorIdentity,proto3" json:"acceptorIdentity,omitempty"`
AcceptorSignature []byte `protobuf:"bytes,4,opt,name=acceptorSignature,proto3" json:"acceptorSignature,omitempty"`
}
func (m *RawACLRecord) Reset() { *m = RawACLRecord{} }
@ -102,6 +104,20 @@ func (m *RawACLRecord) GetSignature() []byte {
return nil
}
func (m *RawACLRecord) GetAcceptorIdentity() []byte {
if m != nil {
return m.AcceptorIdentity
}
return nil
}
func (m *RawACLRecord) GetAcceptorSignature() []byte {
if m != nil {
return m.AcceptorSignature
}
return nil
}
type RawACLRecordWithId struct {
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
@ -987,6 +1003,168 @@ func (m *ACLUserPermissionChange) GetPermissions() ACLUserPermissions {
return ACLUserPermissions_Admin
}
type ACLSyncMessage struct {
Content *ACLSyncContentValue `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"`
}
func (m *ACLSyncMessage) Reset() { *m = ACLSyncMessage{} }
func (m *ACLSyncMessage) String() string { return proto.CompactTextString(m) }
func (*ACLSyncMessage) ProtoMessage() {}
func (*ACLSyncMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_14abe0d1b4206d54, []int{14}
}
func (m *ACLSyncMessage) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ACLSyncMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ACLSyncMessage.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *ACLSyncMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_ACLSyncMessage.Merge(m, src)
}
func (m *ACLSyncMessage) XXX_Size() int {
return m.Size()
}
func (m *ACLSyncMessage) XXX_DiscardUnknown() {
xxx_messageInfo_ACLSyncMessage.DiscardUnknown(m)
}
var xxx_messageInfo_ACLSyncMessage proto.InternalMessageInfo
func (m *ACLSyncMessage) GetContent() *ACLSyncContentValue {
if m != nil {
return m.Content
}
return nil
}
// ACLSyncContentValue provides different types for acl sync
type ACLSyncContentValue struct {
// Types that are valid to be assigned to Value:
//
// *ACLSyncContentValue_AddRecords
Value isACLSyncContentValue_Value `protobuf_oneof:"value"`
}
func (m *ACLSyncContentValue) Reset() { *m = ACLSyncContentValue{} }
func (m *ACLSyncContentValue) String() string { return proto.CompactTextString(m) }
func (*ACLSyncContentValue) ProtoMessage() {}
func (*ACLSyncContentValue) Descriptor() ([]byte, []int) {
return fileDescriptor_14abe0d1b4206d54, []int{15}
}
func (m *ACLSyncContentValue) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ACLSyncContentValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ACLSyncContentValue.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *ACLSyncContentValue) XXX_Merge(src proto.Message) {
xxx_messageInfo_ACLSyncContentValue.Merge(m, src)
}
func (m *ACLSyncContentValue) XXX_Size() int {
return m.Size()
}
func (m *ACLSyncContentValue) XXX_DiscardUnknown() {
xxx_messageInfo_ACLSyncContentValue.DiscardUnknown(m)
}
var xxx_messageInfo_ACLSyncContentValue proto.InternalMessageInfo
type isACLSyncContentValue_Value interface {
isACLSyncContentValue_Value()
MarshalTo([]byte) (int, error)
Size() int
}
type ACLSyncContentValue_AddRecords struct {
AddRecords *ACLAddRecords `protobuf:"bytes,1,opt,name=addRecords,proto3,oneof" json:"addRecords,omitempty"`
}
func (*ACLSyncContentValue_AddRecords) isACLSyncContentValue_Value() {}
func (m *ACLSyncContentValue) GetValue() isACLSyncContentValue_Value {
if m != nil {
return m.Value
}
return nil
}
func (m *ACLSyncContentValue) GetAddRecords() *ACLAddRecords {
if x, ok := m.GetValue().(*ACLSyncContentValue_AddRecords); ok {
return x.AddRecords
}
return nil
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*ACLSyncContentValue) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*ACLSyncContentValue_AddRecords)(nil),
}
}
type ACLAddRecords struct {
Records []*RawACLRecordWithId `protobuf:"bytes,1,rep,name=records,proto3" json:"records,omitempty"`
}
func (m *ACLAddRecords) Reset() { *m = ACLAddRecords{} }
func (m *ACLAddRecords) String() string { return proto.CompactTextString(m) }
func (*ACLAddRecords) ProtoMessage() {}
func (*ACLAddRecords) Descriptor() ([]byte, []int) {
return fileDescriptor_14abe0d1b4206d54, []int{16}
}
func (m *ACLAddRecords) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ACLAddRecords) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ACLAddRecords.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *ACLAddRecords) XXX_Merge(src proto.Message) {
xxx_messageInfo_ACLAddRecords.Merge(m, src)
}
func (m *ACLAddRecords) XXX_Size() int {
return m.Size()
}
func (m *ACLAddRecords) XXX_DiscardUnknown() {
xxx_messageInfo_ACLAddRecords.DiscardUnknown(m)
}
var xxx_messageInfo_ACLAddRecords proto.InternalMessageInfo
func (m *ACLAddRecords) GetRecords() []*RawACLRecordWithId {
if m != nil {
return m.Records
}
return nil
}
func init() {
proto.RegisterEnum("aclrecord.ACLUserPermissions", ACLUserPermissions_name, ACLUserPermissions_value)
proto.RegisterType((*RawACLRecord)(nil), "aclrecord.RawACLRecord")
@ -1004,6 +1182,9 @@ func init() {
proto.RegisterType((*ACLUserRemove)(nil), "aclrecord.ACLUserRemove")
proto.RegisterType((*ACLReadKeyReplace)(nil), "aclrecord.ACLReadKeyReplace")
proto.RegisterType((*ACLUserPermissionChange)(nil), "aclrecord.ACLUserPermissionChange")
proto.RegisterType((*ACLSyncMessage)(nil), "aclrecord.ACLSyncMessage")
proto.RegisterType((*ACLSyncContentValue)(nil), "aclrecord.ACLSyncContentValue")
proto.RegisterType((*ACLAddRecords)(nil), "aclrecord.ACLAddRecords")
}
func init() {
@ -1011,61 +1192,67 @@ func init() {
}
var fileDescriptor_14abe0d1b4206d54 = []byte{
// 854 bytes of a gzipped FileDescriptorProto
// 954 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xdf, 0x59, 0x3b, 0x71, 0xf6, 0xd9, 0x6d, 0xdc, 0x11, 0xa4, 0xab, 0xa8, 0x58, 0xd6, 0x8a,
0x83, 0x55, 0x81, 0x0b, 0x06, 0xa9, 0x28, 0x07, 0x90, 0x6b, 0x5a, 0x39, 0x24, 0x87, 0x6a, 0x02,
0x14, 0x71, 0x9b, 0xee, 0x8e, 0xe2, 0x51, 0xed, 0xdd, 0xd5, 0xec, 0xd8, 0xc8, 0x47, 0xce, 0x5c,
0xe0, 0x23, 0xf0, 0x41, 0xb8, 0x23, 0x71, 0xe9, 0x05, 0xc4, 0x11, 0x25, 0x1f, 0x83, 0x0b, 0x9a,
0xd9, 0xff, 0xbb, 0xb6, 0x45, 0x25, 0xab, 0x87, 0xc4, 0xf3, 0xde, 0xfb, 0xbd, 0xe7, 0xdf, 0xfc,
0xe6, 0xcd, 0x1b, 0xc3, 0x87, 0xe1, 0xab, 0xeb, 0x47, 0xd4, 0x9d, 0xab, 0x3f, 0xc1, 0xdc, 0x40,
0x78, 0xa1, 0x08, 0x64, 0xf0, 0x48, 0xff, 0x8f, 0x72, 0xef, 0x50, 0x3b, 0xb0, 0x95, 0x39, 0x9c,
0x67, 0xd0, 0x21, 0xf4, 0x87, 0xf1, 0xe4, 0x92, 0x68, 0x1b, 0xdb, 0xd0, 0x0a, 0xe9, 0x7a, 0x1e,
0x50, 0xcf, 0x46, 0x7d, 0x34, 0xe8, 0x90, 0xd4, 0xc4, 0x0f, 0xc0, 0x8a, 0xf8, 0xb5, 0x4f, 0xe5,
0x52, 0x30, 0xdb, 0xd4, 0xb1, 0xdc, 0xe1, 0x7c, 0x0e, 0xb8, 0x58, 0xe7, 0x05, 0x97, 0xb3, 0xf3,
0x5d, 0xd5, 0xee, 0x82, 0xc9, 0x3d, 0x5d, 0xc6, 0x22, 0x26, 0xf7, 0x9c, 0x5f, 0x11, 0x58, 0x39,
0x8b, 0x13, 0x38, 0x0c, 0x05, 0x5b, 0x9d, 0xc7, 0x69, 0x16, 0x49, 0x2c, 0x7c, 0x0a, 0x47, 0xdc,
0x63, 0xbe, 0xe4, 0x72, 0x9d, 0x50, 0xc8, 0x6c, 0x8c, 0xa1, 0xe9, 0x51, 0x49, 0xed, 0x86, 0xf6,
0xeb, 0x35, 0x1e, 0x02, 0x76, 0x97, 0x42, 0x30, 0x5f, 0x12, 0x46, 0xbd, 0x0b, 0xb6, 0x9e, 0xd2,
0x68, 0x66, 0x37, 0xfb, 0x68, 0xd0, 0x24, 0x1b, 0x22, 0x6a, 0x8f, 0x92, 0x2f, 0x58, 0x24, 0xe9,
0x22, 0xb4, 0x0f, 0xfa, 0x68, 0xd0, 0x20, 0xb9, 0xc3, 0xf9, 0xc9, 0x84, 0x96, 0xe2, 0x18, 0x04,
0xb2, 0xc4, 0x04, 0x55, 0x98, 0xbc, 0x0f, 0x77, 0x98, 0xef, 0x8a, 0x75, 0x28, 0x79, 0xe0, 0x5f,
0xb0, 0x94, 0x6a, 0xd9, 0xa9, 0xb4, 0x89, 0x42, 0xea, 0xb2, 0x73, 0x4f, 0x53, 0xb6, 0x48, 0x6a,
0xe2, 0x87, 0xd0, 0x4d, 0xa0, 0xcc, 0x4b, 0xd8, 0x69, 0xce, 0x1d, 0x52, 0xf3, 0x2b, 0xac, 0xc7,
0x04, 0x5f, 0x51, 0x55, 0xf6, 0xca, 0x9d, 0xb1, 0x05, 0xd3, 0xc4, 0x2d, 0x52, 0xf3, 0x6f, 0x51,
0xe3, 0xf0, 0xff, 0xa9, 0xd1, 0xaa, 0xaa, 0xf1, 0xa7, 0x09, 0xc7, 0xe3, 0xc9, 0xe5, 0x24, 0xf0,
0x25, 0xf3, 0xe5, 0xb7, 0x74, 0xbe, 0x64, 0xf8, 0x63, 0x68, 0x2d, 0x23, 0x26, 0xc6, 0x5e, 0x7c,
0x70, 0xed, 0xd1, 0xbb, 0xc3, 0xbc, 0xf7, 0xc6, 0x93, 0xcb, 0x6f, 0xe2, 0xe0, 0xd4, 0x20, 0x29,
0x0e, 0x9f, 0x01, 0xa8, 0x25, 0x61, 0x8b, 0x60, 0x15, 0xf7, 0x55, 0x7b, 0x64, 0xd7, 0xb3, 0xe2,
0xf8, 0xd4, 0x20, 0x05, 0x34, 0xfe, 0x0e, 0xde, 0x51, 0xd6, 0x73, 0x26, 0x16, 0x3c, 0x8a, 0x78,
0xe0, 0x4f, 0x66, 0xd4, 0xbf, 0x66, 0x5a, 0xcf, 0xf6, 0xc8, 0xa9, 0x57, 0xa9, 0x22, 0xa7, 0x06,
0xd9, 0x58, 0x21, 0x65, 0x75, 0xee, 0xaf, 0xb8, 0x64, 0x5a, 0xfc, 0x8d, 0xac, 0xe2, 0x78, 0xca,
0x2a, 0xb6, 0xf0, 0xa7, 0x70, 0xa4, 0xac, 0xaf, 0x02, 0xee, 0xeb, 0xa3, 0x68, 0x8f, 0x4e, 0xea,
0x99, 0x2a, 0x3a, 0x35, 0x48, 0x86, 0x7c, 0xd2, 0x82, 0x83, 0x95, 0xd2, 0xd0, 0x79, 0xaa, 0x9b,
0xec, 0x4b, 0xd5, 0xbe, 0x67, 0x00, 0xd4, 0x9d, 0x27, 0x0a, 0xdb, 0xa8, 0xdf, 0x18, 0xb4, 0x47,
0xa7, 0xe5, 0x5a, 0x45, 0xf9, 0x49, 0x01, 0xed, 0xfc, 0x8b, 0xe0, 0x68, 0x3c, 0xb9, 0xbc, 0x92,
0x54, 0x32, 0xd5, 0x91, 0x22, 0x3f, 0x58, 0x16, 0xe9, 0x5a, 0x4d, 0x52, 0x76, 0xe2, 0xc7, 0xf1,
0xa6, 0x75, 0x4a, 0x64, 0x9b, 0xfa, 0xeb, 0xee, 0xd7, 0xa9, 0xeb, 0x38, 0x29, 0x40, 0xf1, 0x19,
0xb4, 0xb8, 0xde, 0x7b, 0x64, 0x37, 0x74, 0x56, 0xbf, 0x9c, 0xa5, 0x61, 0xc3, 0x58, 0x9e, 0xe8,
0xa9, 0x2f, 0xc5, 0x9a, 0xa4, 0x09, 0xa7, 0x5f, 0x43, 0xa7, 0x18, 0xc0, 0x5d, 0x68, 0xbc, 0x62,
0xeb, 0xe4, 0xde, 0xab, 0x25, 0x1e, 0x26, 0xca, 0x6c, 0x6f, 0x8e, 0xb8, 0x00, 0x89, 0x61, 0x67,
0xe6, 0x67, 0xc8, 0xf9, 0x05, 0x41, 0xa7, 0x48, 0x77, 0x0f, 0xf7, 0xf5, 0x0b, 0x68, 0x87, 0x59,
0x9b, 0x44, 0xba, 0xc7, 0xee, 0x8e, 0xde, 0xdb, 0xd5, 0x63, 0x11, 0x29, 0x66, 0x38, 0xbf, 0x21,
0x80, 0xfc, 0x0e, 0xec, 0x81, 0xd1, 0x07, 0x70, 0xaf, 0x3a, 0x0f, 0xe2, 0x03, 0xe8, 0x90, 0x7a,
0xa0, 0xca, 0xbf, 0xf9, 0xc6, 0xfc, 0xff, 0x42, 0x70, 0xa7, 0x24, 0x38, 0x1e, 0xc0, 0x31, 0x75,
0x5d, 0x16, 0xca, 0xe7, 0xcb, 0x97, 0x73, 0xee, 0x5e, 0xb0, 0x74, 0x27, 0x55, 0x77, 0x81, 0xea,
0xd5, 0x7a, 0x91, 0x4e, 0x1e, 0x53, 0x4f, 0x9e, 0x7a, 0xe0, 0x6d, 0x6f, 0xec, 0x0f, 0x04, 0xed,
0xc2, 0xb5, 0xdc, 0xc3, 0xc9, 0x64, 0xc2, 0x5c, 0x65, 0x2f, 0x66, 0xa3, 0x28, 0x4c, 0xe6, 0xc6,
0x0e, 0x74, 0x32, 0xad, 0xf2, 0x39, 0x5f, 0xf2, 0x6d, 0x96, 0xe3, 0x60, 0x8b, 0x1c, 0x4e, 0x94,
0x9d, 0x52, 0x32, 0x25, 0x77, 0x6d, 0xe7, 0x19, 0x1c, 0x27, 0x33, 0x80, 0xb0, 0x70, 0x4e, 0xdd,
0xec, 0xde, 0x3f, 0x28, 0xeb, 0x47, 0x4a, 0x20, 0x52, 0x4d, 0x72, 0x7e, 0x44, 0x70, 0xaf, 0x06,
0xdb, 0x83, 0x90, 0x9b, 0x9e, 0xc2, 0xc6, 0xe6, 0xa7, 0xd0, 0x59, 0xc1, 0xfd, 0x2d, 0x63, 0x7e,
0x27, 0x91, 0x4a, 0xfb, 0x98, 0x6f, 0xda, 0x3e, 0x0f, 0x1f, 0x03, 0xae, 0x43, 0xb0, 0x05, 0x07,
0x63, 0x6f, 0xc1, 0xfd, 0xae, 0x81, 0x01, 0x0e, 0x5f, 0x08, 0x2e, 0x99, 0xe8, 0x22, 0xb5, 0x56,
0x7c, 0x99, 0xe8, 0x9a, 0x4f, 0x3e, 0xfa, 0xfd, 0xa6, 0x87, 0x5e, 0xdf, 0xf4, 0xd0, 0x3f, 0x37,
0x3d, 0xf4, 0xf3, 0x6d, 0xcf, 0x78, 0x7d, 0xdb, 0x33, 0xfe, 0xbe, 0xed, 0x19, 0xdf, 0x9f, 0x6c,
0xfe, 0x3d, 0xf7, 0xf2, 0x50, 0x7f, 0x7c, 0xf2, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0xdf,
0xf6, 0x6c, 0xf0, 0x09, 0x00, 0x00,
0x14, 0xf7, 0xac, 0x9d, 0x38, 0x7e, 0x76, 0x13, 0x67, 0x80, 0x74, 0x15, 0x15, 0x2b, 0x5a, 0x71,
0x88, 0xaa, 0xe2, 0x82, 0x41, 0x4a, 0x95, 0x03, 0xc8, 0x35, 0x45, 0x76, 0x13, 0xa4, 0x6a, 0x02,
0x14, 0xf5, 0x36, 0xdd, 0x1d, 0x25, 0xab, 0xda, 0xbb, 0xab, 0x99, 0xb1, 0xd1, 0x1e, 0x39, 0x73,
0x81, 0x6f, 0x00, 0x1f, 0x84, 0x3b, 0x12, 0x97, 0x5e, 0x40, 0x1c, 0x51, 0xf2, 0x31, 0xb8, 0xa0,
0x99, 0xd9, 0xff, 0xeb, 0x44, 0x54, 0x8a, 0x7a, 0x48, 0x32, 0xf3, 0xde, 0xef, 0x4d, 0x7e, 0xef,
0xf7, 0xde, 0xbc, 0x59, 0xf8, 0x30, 0x7a, 0x75, 0xfe, 0x90, 0xba, 0x73, 0xf5, 0xc3, 0x99, 0x1b,
0x72, 0x2f, 0xe2, 0xa1, 0x0c, 0x1f, 0xea, 0xdf, 0x22, 0xb7, 0x0e, 0xb5, 0x01, 0x77, 0x32, 0x83,
0xf3, 0x0b, 0x82, 0x1e, 0xa1, 0xdf, 0x8f, 0x27, 0xa7, 0x44, 0x1b, 0xb0, 0x0d, 0xed, 0x88, 0xc6,
0xf3, 0x90, 0x7a, 0x36, 0x3a, 0x40, 0x87, 0x3d, 0x92, 0x6e, 0xf1, 0x3d, 0xe8, 0x08, 0xff, 0x3c,
0xa0, 0x72, 0xc9, 0x99, 0x6d, 0x69, 0x5f, 0x6e, 0xc0, 0xf7, 0xa1, 0x4f, 0x5d, 0x97, 0x45, 0x32,
0xe4, 0x33, 0x8f, 0x05, 0xd2, 0x97, 0xb1, 0xdd, 0xd4, 0xa0, 0x9a, 0x1d, 0x3f, 0x80, 0xdd, 0xd4,
0x76, 0x96, 0x9d, 0xd8, 0xd2, 0xe0, 0xba, 0xc3, 0xf9, 0x0c, 0x70, 0x91, 0xe1, 0x73, 0x5f, 0x5e,
0xcc, 0x6e, 0xe2, 0xb9, 0x0d, 0x96, 0xef, 0x69, 0x82, 0x1d, 0x62, 0xf9, 0x9e, 0xf3, 0x2b, 0x82,
0x4e, 0x9e, 0xdf, 0x1e, 0x6c, 0x46, 0x9c, 0xad, 0x66, 0x26, 0xac, 0x43, 0x92, 0x1d, 0xde, 0x87,
0x2d, 0x3f, 0xe5, 0x6d, 0x92, 0xcb, 0xf6, 0x18, 0x43, 0xcb, 0xa3, 0x92, 0x26, 0xf9, 0xe8, 0x35,
0x1e, 0x02, 0x76, 0x97, 0x9c, 0xb3, 0x40, 0x12, 0x46, 0xbd, 0x13, 0x16, 0x4f, 0xa9, 0xb8, 0xd0,
0x49, 0xb4, 0xc8, 0x1a, 0x8f, 0x52, 0x4f, 0xfa, 0x0b, 0x26, 0x24, 0x5d, 0x44, 0xf6, 0xc6, 0x01,
0x3a, 0x6c, 0x92, 0xdc, 0xe0, 0xfc, 0x68, 0x41, 0x5b, 0x71, 0x0c, 0x43, 0x59, 0x62, 0x82, 0x2a,
0x4c, 0x3e, 0x80, 0x3b, 0x2c, 0x70, 0x79, 0x1c, 0x49, 0x3f, 0x0c, 0x4e, 0x58, 0x4a, 0xb5, 0x6c,
0x54, 0xda, 0x88, 0x88, 0xba, 0x6c, 0xe6, 0x69, 0xca, 0x1d, 0x92, 0x6e, 0x55, 0x95, 0x12, 0x28,
0xf3, 0x12, 0x76, 0x89, 0xf0, 0x35, 0xbb, 0xc2, 0x7a, 0x8c, 0xfb, 0x2b, 0xaa, 0x8e, 0x3d, 0x73,
0x2f, 0xd8, 0x82, 0x69, 0xe2, 0x1d, 0x52, 0xb3, 0x5f, 0xa3, 0xc6, 0xe6, 0xff, 0x53, 0xa3, 0x5d,
0x55, 0xe3, 0x4f, 0x0b, 0x76, 0xc6, 0x93, 0xd3, 0x49, 0x18, 0x48, 0x16, 0xc8, 0x6f, 0xe9, 0x7c,
0xc9, 0xf0, 0xc7, 0xd0, 0x5e, 0x0a, 0xc6, 0xc7, 0x9e, 0x29, 0x5c, 0x77, 0xf4, 0xde, 0x30, 0x6f,
0xeb, 0xf1, 0xe4, 0xf4, 0x1b, 0xe3, 0x9c, 0x36, 0x48, 0x8a, 0xc3, 0xc7, 0x00, 0x6a, 0x49, 0xd8,
0x22, 0x5c, 0x99, 0x8e, 0xed, 0x8e, 0xec, 0x7a, 0x94, 0xf1, 0x4f, 0x1b, 0xa4, 0x80, 0xc6, 0xdf,
0xc1, 0xbb, 0x6a, 0xf7, 0x8c, 0xf1, 0x85, 0x2f, 0x84, 0x1f, 0x06, 0x93, 0x0b, 0x1a, 0x9c, 0x33,
0xad, 0x67, 0x77, 0xe4, 0xd4, 0x4f, 0xa9, 0x22, 0xa7, 0x0d, 0xb2, 0xf6, 0x84, 0x94, 0xd5, 0x2c,
0x58, 0xf9, 0xd2, 0x74, 0xfd, 0x5a, 0x56, 0xc6, 0x9f, 0xb2, 0x32, 0x3b, 0xfc, 0x29, 0x6c, 0xa9,
0xdd, 0xd3, 0xd0, 0x0f, 0x74, 0x29, 0xba, 0xa3, 0xbd, 0x7a, 0xa4, 0xf2, 0x4e, 0x1b, 0x24, 0x43,
0x3e, 0x6e, 0xc3, 0xc6, 0x4a, 0x69, 0xe8, 0x3c, 0xd1, 0x4d, 0xf6, 0x85, 0x6a, 0xdf, 0x63, 0x00,
0xea, 0xce, 0x13, 0x85, 0x6d, 0x74, 0xd0, 0x3c, 0xec, 0x8e, 0xf6, 0xcb, 0x67, 0x15, 0xe5, 0x27,
0x05, 0xb4, 0xf3, 0x2f, 0x82, 0xad, 0xf1, 0xe4, 0xf4, 0x4c, 0x52, 0xc9, 0x54, 0x47, 0xf2, 0xbc,
0xb0, 0x4c, 0xe8, 0xb3, 0x5a, 0xa4, 0x6c, 0xc4, 0x47, 0x26, 0x69, 0x1d, 0x22, 0x6c, 0x4b, 0xff,
0xbb, 0xbb, 0x75, 0xea, 0xda, 0x4f, 0x0a, 0x50, 0x7c, 0x0c, 0x6d, 0x5f, 0xe7, 0x2e, 0xec, 0xa6,
0x8e, 0x3a, 0x28, 0x47, 0x69, 0xd8, 0xd0, 0xc8, 0x23, 0x9e, 0x04, 0x92, 0xc7, 0x24, 0x0d, 0xd8,
0xff, 0x1a, 0x7a, 0x45, 0x07, 0xee, 0x43, 0xf3, 0x15, 0x8b, 0x93, 0x7b, 0xaf, 0x96, 0x78, 0x98,
0x28, 0x73, 0x7d, 0x73, 0x98, 0x03, 0x88, 0x81, 0x1d, 0x5b, 0x8f, 0x90, 0xf3, 0x33, 0x82, 0x5e,
0x91, 0xee, 0x2d, 0xdc, 0xd7, 0xcf, 0xa1, 0x1b, 0x65, 0x6d, 0x22, 0x74, 0x8f, 0x6d, 0x8f, 0xde,
0xbf, 0xa9, 0xc7, 0x04, 0x29, 0x46, 0x38, 0xbf, 0x21, 0x80, 0xfc, 0x0e, 0xdc, 0x02, 0xa3, 0x07,
0xb0, 0x5b, 0x9d, 0x07, 0xa6, 0x00, 0x3d, 0x52, 0x77, 0x54, 0xf9, 0xb7, 0xde, 0x98, 0xff, 0x5f,
0x08, 0xee, 0x94, 0x04, 0xc7, 0x87, 0xb0, 0x63, 0x5e, 0x82, 0x67, 0xcb, 0x97, 0x73, 0xdf, 0x3d,
0x61, 0x69, 0x26, 0x55, 0x73, 0x81, 0xea, 0x59, 0xbc, 0x48, 0x27, 0x8f, 0xa5, 0x27, 0x4f, 0xdd,
0xf1, 0xb6, 0x13, 0xfb, 0x03, 0x41, 0xb7, 0x70, 0x2d, 0x6f, 0xa1, 0x32, 0x99, 0x30, 0xf9, 0xcb,
0xd9, 0x2c, 0x0a, 0x93, 0x99, 0xb1, 0x03, 0xbd, 0x4c, 0xab, 0x7c, 0xce, 0x97, 0x6c, 0xeb, 0xe5,
0xd8, 0xb8, 0x46, 0x0e, 0x47, 0x64, 0x55, 0x4a, 0xa6, 0xe4, 0x4d, 0xe9, 0x7c, 0x09, 0x3b, 0xc9,
0x0c, 0x20, 0x2c, 0x9a, 0x53, 0x37, 0xbb, 0xf7, 0xf7, 0xca, 0xfa, 0x91, 0x12, 0x88, 0x54, 0x83,
0x9c, 0x1f, 0x10, 0xec, 0xd6, 0x60, 0xb7, 0x20, 0xe4, 0xba, 0xa7, 0xb0, 0xb9, 0xfe, 0x29, 0x74,
0x56, 0x70, 0xf7, 0x9a, 0x31, 0x7f, 0x23, 0x91, 0x4a, 0xfb, 0x58, 0x6f, 0xdc, 0x3e, 0x4f, 0x61,
0x5b, 0xcd, 0xb8, 0x38, 0x70, 0xbf, 0x62, 0x42, 0xd0, 0x73, 0x86, 0x1f, 0x41, 0xdb, 0x4d, 0x86,
0xb6, 0x99, 0x59, 0x83, 0xca, 0x3c, 0x8c, 0x03, 0xb7, 0x34, 0xb8, 0x53, 0xb8, 0xf3, 0x02, 0xde,
0x59, 0xe3, 0xd7, 0x0f, 0x81, 0xe7, 0x99, 0x8f, 0x23, 0x91, 0x3c, 0xad, 0x95, 0x39, 0x38, 0xce,
0xfc, 0xea, 0x39, 0xca, 0xd1, 0xf9, 0xc3, 0x32, 0xd5, 0x8d, 0x91, 0xe3, 0xf0, 0x11, 0xb4, 0x79,
0x76, 0xa4, 0x2a, 0x7a, 0x31, 0xeb, 0xfa, 0xd7, 0x1c, 0x49, 0xd1, 0xf7, 0x8f, 0x00, 0xd7, 0x45,
0xc1, 0x1d, 0xd8, 0x18, 0x7b, 0x0b, 0x3f, 0xe8, 0x37, 0x30, 0xc0, 0xe6, 0x73, 0xee, 0x4b, 0xc6,
0xfb, 0x48, 0xad, 0x55, 0x85, 0x18, 0xef, 0x5b, 0x8f, 0x3f, 0xfa, 0xfd, 0x72, 0x80, 0x5e, 0x5f,
0x0e, 0xd0, 0x3f, 0x97, 0x03, 0xf4, 0xd3, 0xd5, 0xa0, 0xf1, 0xfa, 0x6a, 0xd0, 0xf8, 0xfb, 0x6a,
0xd0, 0x78, 0xb1, 0xb7, 0xfe, 0xe3, 0xf8, 0xe5, 0xa6, 0xfe, 0xf3, 0xc9, 0x7f, 0x01, 0x00, 0x00,
0xff, 0xff, 0xa9, 0xbd, 0x7e, 0xe0, 0x3d, 0x0b, 0x00, 0x00,
}
func (m *RawACLRecord) Marshal() (dAtA []byte, err error) {
@ -1088,6 +1275,20 @@ func (m *RawACLRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.AcceptorSignature) > 0 {
i -= len(m.AcceptorSignature)
copy(dAtA[i:], m.AcceptorSignature)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptorSignature)))
i--
dAtA[i] = 0x22
}
if len(m.AcceptorIdentity) > 0 {
i -= len(m.AcceptorIdentity)
copy(dAtA[i:], m.AcceptorIdentity)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptorIdentity)))
i--
dAtA[i] = 0x1a
}
if len(m.Signature) > 0 {
i -= len(m.Signature)
copy(dAtA[i:], m.Signature)
@ -1844,6 +2045,131 @@ func (m *ACLUserPermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error)
return len(dAtA) - i, nil
}
func (m *ACLSyncMessage) 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 *ACLSyncMessage) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLSyncMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Content != nil {
{
size, err := m.Content.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintAclrecord(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
return len(dAtA) - i, nil
}
func (m *ACLSyncContentValue) 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 *ACLSyncContentValue) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLSyncContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Value != nil {
{
size := m.Value.Size()
i -= size
if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil {
return 0, err
}
}
}
return len(dAtA) - i, nil
}
func (m *ACLSyncContentValue_AddRecords) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLSyncContentValue_AddRecords) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.AddRecords != nil {
{
size, err := m.AddRecords.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintAclrecord(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *ACLAddRecords) 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 *ACLAddRecords) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLAddRecords) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
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 = encodeVarintAclrecord(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintAclrecord(dAtA []byte, offset int, v uint64) int {
offset -= sovAclrecord(v)
base := offset
@ -1869,6 +2195,14 @@ func (m *RawACLRecord) Size() (n int) {
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
l = len(m.AcceptorIdentity)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
l = len(m.AcceptorSignature)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
return n
}
@ -2231,6 +2565,58 @@ func (m *ACLUserPermissionChange) Size() (n int) {
return n
}
func (m *ACLSyncMessage) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Content != nil {
l = m.Content.Size()
n += 1 + l + sovAclrecord(uint64(l))
}
return n
}
func (m *ACLSyncContentValue) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Value != nil {
n += m.Value.Size()
}
return n
}
func (m *ACLSyncContentValue_AddRecords) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.AddRecords != nil {
l = m.AddRecords.Size()
n += 1 + l + sovAclrecord(uint64(l))
}
return n
}
func (m *ACLAddRecords) 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 + sovAclrecord(uint64(l))
}
}
return n
}
func sovAclrecord(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@ -2334,6 +2720,74 @@ func (m *RawACLRecord) Unmarshal(dAtA []byte) error {
m.Signature = []byte{}
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AcceptorIdentity", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthAclrecord
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthAclrecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AcceptorIdentity = append(m.AcceptorIdentity[:0], dAtA[iNdEx:postIndex]...)
if m.AcceptorIdentity == nil {
m.AcceptorIdentity = []byte{}
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AcceptorSignature", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthAclrecord
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthAclrecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AcceptorSignature = append(m.AcceptorSignature[:0], dAtA[iNdEx:postIndex]...)
if m.AcceptorSignature == nil {
m.AcceptorSignature = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAclrecord(dAtA[iNdEx:])
@ -4562,6 +5016,261 @@ func (m *ACLUserPermissionChange) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ACLSyncMessage) 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 ErrIntOverflowAclrecord
}
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: ACLSyncMessage: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ACLSyncMessage: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Content", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthAclrecord
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthAclrecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Content == nil {
m.Content = &ACLSyncContentValue{}
}
if err := m.Content.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAclrecord(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthAclrecord
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ACLSyncContentValue) 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 ErrIntOverflowAclrecord
}
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: ACLSyncContentValue: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ACLSyncContentValue: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AddRecords", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthAclrecord
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthAclrecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
v := &ACLAddRecords{}
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ACLSyncContentValue_AddRecords{v}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAclrecord(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthAclrecord
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ACLAddRecords) 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 ErrIntOverflowAclrecord
}
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: ACLAddRecords: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ACLAddRecords: 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 ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthAclrecord
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthAclrecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Records = append(m.Records, &RawACLRecordWithId{})
if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAclrecord(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthAclrecord
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipAclrecord(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@ -3,64 +3,66 @@ package aclrecord;
option go_package = "pkg/acl/aclrecordproto";
message RawACLRecord {
bytes payload = 1;
bytes signature = 2;
bytes payload = 1;
bytes signature = 2;
bytes acceptorIdentity = 3;
bytes acceptorSignature = 4;
}
message RawACLRecordWithId {
bytes payload = 1;
string id = 2;
bytes payload = 1;
string id = 2;
}
message ACLRecord {
string prevId = 1;
bytes identity = 2;
bytes data = 3;
uint64 currentReadKeyHash = 4;
int64 timestamp = 5;
string prevId = 1;
bytes identity = 2;
bytes data = 3;
uint64 currentReadKeyHash = 4;
int64 timestamp = 5;
}
message ACLRoot {
bytes identity = 1;
bytes encryptionKey = 2;
string spaceId = 3;
bytes encryptedReadKey = 4;
string derivationScheme = 5;
uint64 currentReadKeyHash = 6;
int64 timestamp = 7;
bytes identity = 1;
bytes encryptionKey = 2;
string spaceId = 3;
bytes encryptedReadKey = 4;
string derivationScheme = 5;
uint64 currentReadKeyHash = 6;
int64 timestamp = 7;
}
message ACLContentValue {
oneof value {
ACLUserAdd userAdd = 1;
ACLUserRemove userRemove = 2;
ACLUserPermissionChange userPermissionChange = 3;
ACLUserInvite userInvite = 4;
ACLUserJoin userJoin = 5;
}
oneof value {
ACLUserAdd userAdd = 1;
ACLUserRemove userRemove = 2;
ACLUserPermissionChange userPermissionChange = 3;
ACLUserInvite userInvite = 4;
ACLUserJoin userJoin = 5;
}
}
message ACLData {
repeated ACLContentValue aclContent = 1;
repeated ACLContentValue aclContent = 1;
}
message ACLState {
repeated uint64 readKeyHashes = 1;
repeated ACLUserState userStates = 2;
map<string, ACLUserInvite> invites = 3;
repeated uint64 readKeyHashes = 1;
repeated ACLUserState userStates = 2;
map<string, ACLUserInvite> invites = 3;
}
message ACLUserState {
bytes identity = 1;
bytes encryptionKey = 2;
ACLUserPermissions permissions = 3;
bytes identity = 1;
bytes encryptionKey = 2;
ACLUserPermissions permissions = 3;
}
message ACLUserAdd {
bytes identity = 1;
bytes encryptionKey = 2;
repeated bytes encryptedReadKeys = 3;
ACLUserPermissions permissions = 4;
bytes identity = 1;
bytes encryptionKey = 2;
repeated bytes encryptedReadKeys = 3;
ACLUserPermissions permissions = 4;
}
message ACLUserInvite {
@ -84,18 +86,33 @@ message ACLUserRemove {
}
message ACLReadKeyReplace {
bytes identity = 1;
bytes encryptionKey = 2;
bytes encryptedReadKey = 3;
bytes identity = 1;
bytes encryptionKey = 2;
bytes encryptedReadKey = 3;
}
message ACLUserPermissionChange {
bytes identity = 1;
ACLUserPermissions permissions = 2;
bytes identity = 1;
ACLUserPermissions permissions = 2;
}
enum ACLUserPermissions {
Admin = 0;
Writer = 1;
Reader = 2;
Admin = 0;
Writer = 1;
Reader = 2;
}
message ACLSyncMessage {
ACLSyncContentValue content = 2;
}
// ACLSyncContentValue provides different types for acl sync
message ACLSyncContentValue {
oneof value {
ACLAddRecords addRecords = 1;
}
}
message ACLAddRecords {
repeated RawACLRecordWithId records = 1;
}

View File

@ -10,6 +10,7 @@ import (
"time"
)
// remove interface
type ACLRecordBuilder interface {
ConvertFromRaw(rawIdRecord *aclrecordproto.RawACLRecordWithId) (rec *ACLRecord, err error)
BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *ACLState) (rec *aclrecordproto.RawACLRecord, err error)

View File

@ -29,11 +29,13 @@ type ACLList interface {
Records() []*ACLRecord
ACLState() *ACLState
IsAfter(first string, second string) (bool, error)
AddRawRecords(ctx context.Context, rec []*aclrecordproto.RawACLRecordWithId) (err error)
Head() *ACLRecord
Get(id string) (*ACLRecord, error)
Iterate(iterFunc IterFunc)
IterateFrom(startId string, iterFunc IterFunc)
AddRawRecord(rawRec *aclrecordproto.RawACLRecordWithId) (added bool, err error)
Close() (err error)
}
@ -53,14 +55,12 @@ type aclList struct {
}
func BuildACLListWithIdentity(acc *account.AccountData, storage storage.ListStorage) (ACLList, error) {
id := storage.ID()
builder := newACLStateBuilderWithIdentity(acc)
return build(id, builder, newACLRecordBuilder(id, common.NewKeychain()), storage)
return build(storage.Id(), builder, newACLRecordBuilder(storage.Id(), common.NewKeychain()), storage)
}
func BuildACLList(storage storage.ListStorage) (ACLList, error) {
id := storage.ID()
return build(id, newACLStateBuilder(), newACLRecordBuilder(id, common.NewKeychain()), storage)
return build(storage.Id(), newACLStateBuilder(), newACLRecordBuilder(storage.Id(), common.NewKeychain()), storage)
}
func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder, storage storage.ListStorage) (list ACLList, err error) {
@ -110,6 +110,7 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder
return
}
// TODO: check if this is correct (raw model instead of unmarshalled)
rootWithId, err := storage.Root()
if err != nil {
return
@ -124,7 +125,6 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder
aclState: state,
storage: storage,
id: id,
RWMutex: sync.RWMutex{},
}
return
}
@ -133,6 +133,37 @@ func (a *aclList) Records() []*ACLRecord {
return a.records
}
func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawACLRecordWithId) (added bool, err error) {
if _, ok := a.indexes[rawRec.Id]; ok {
return
}
record, err := a.recordBuilder.ConvertFromRaw(rawRec)
if err != nil {
return
}
if err = a.aclState.applyRecord(record); err != nil {
return
}
a.records = append(a.records, record)
a.indexes[record.Id] = len(a.records) - 1
if err = a.storage.AddRawRecord(context.Background(), rawRec); err != nil {
return
}
if err = a.storage.SetHead(rawRec.Id); err != nil {
return
}
return true, nil
}
func (a *aclList) IsValidNext(rawRec *aclrecordproto.RawACLRecordWithId) (err error) {
_, err = a.recordBuilder.ConvertFromRaw(rawRec)
if err != nil {
return
}
// TODO: change state and add "check" method for records
return
}
func (a *aclList) ID() string {
return a.id
}
@ -141,40 +172,6 @@ func (a *aclList) Root() *aclrecordproto.RawACLRecordWithId {
return a.root
}
func (a *aclList) AddRawRecords(ctx context.Context, records []*aclrecordproto.RawACLRecordWithId) (err error) {
if len(records) == 0 {
return
}
// converting and verifying
var aclRecords []*ACLRecord
for _, rec := range records {
var record *ACLRecord
record, err = a.recordBuilder.ConvertFromRaw(rec)
if err != nil {
return
}
aclRecords = append(aclRecords, record)
}
// trying to append them to state
err = a.stateBuilder.Append(a.aclState, aclRecords)
if err != nil {
return
}
// saving to storage
for _, rec := range records {
err = a.storage.AddRawRecord(ctx, rec)
if err != nil {
return
}
}
// setting new head
err = a.storage.SetHead(records[len(records)-1].Id)
return
}
func (a *aclList) ACLState() *ACLState {
return a.aclState
}

View File

@ -89,3 +89,7 @@ func TestAclList_ACLState_UserJoinAndRemove(t *testing.T) {
_, err = aclList.ACLState().PermissionsAtRecord(records[3].Id, idB)
assert.Error(t, err, "B should have no permissions at record 3, because user should be removed")
}
func TestAclList_AddRawRecord(t *testing.T) {
}

View File

@ -33,11 +33,10 @@ func NewInMemoryACLListStorage(
root: root,
head: head.Id,
records: allRecords,
RWMutex: sync.RWMutex{},
}, nil
}
func (t *inMemoryACLListStorage) ID() string {
func (t *inMemoryACLListStorage) Id() string {
t.RLock()
defer t.RUnlock()
return t.id
@ -112,7 +111,7 @@ func (t *inMemoryTreeStorage) HasChange(ctx context.Context, id string) (bool, e
return exists, nil
}
func (t *inMemoryTreeStorage) ID() string {
func (t *inMemoryTreeStorage) Id() string {
t.RLock()
defer t.RUnlock()
return t.id

View File

@ -12,7 +12,7 @@ var ErrACLExists = errors.New("acl already exists")
var ErrUnknownRecord = errors.New("record doesn't exist")
type ListStorage interface {
ID() string
Id() string
Root() (*aclrecordproto.RawACLRecordWithId, error)
Head() (string, error)
SetHead(headId string) error

View File

@ -80,18 +80,18 @@ func (mr *MockListStorageMockRecorder) Head() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Head", reflect.TypeOf((*MockListStorage)(nil).Head))
}
// ID mocks base method.
func (m *MockListStorage) ID() string {
// Id mocks base method.
func (m *MockListStorage) Id() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ID")
ret := m.ctrl.Call(m, "Id")
ret0, _ := ret[0].(string)
return ret0
}
// ID indicates an expected call of ID.
func (mr *MockListStorageMockRecorder) ID() *gomock.Call {
// Id indicates an expected call of Id.
func (mr *MockListStorageMockRecorder) Id() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockListStorage)(nil).ID))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockListStorage)(nil).Id))
}
// Root mocks base method.
@ -205,18 +205,18 @@ func (mr *MockTreeStorageMockRecorder) Heads() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Heads", reflect.TypeOf((*MockTreeStorage)(nil).Heads))
}
// ID mocks base method.
func (m *MockTreeStorage) ID() string {
// Id mocks base method.
func (m *MockTreeStorage) Id() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ID")
ret := m.ctrl.Call(m, "Id")
ret0, _ := ret[0].(string)
return ret0
}
// ID indicates an expected call of ID.
func (mr *MockTreeStorageMockRecorder) ID() *gomock.Call {
// Id indicates an expected call of Id.
func (mr *MockTreeStorageMockRecorder) Id() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockTreeStorage)(nil).ID))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockTreeStorage)(nil).Id))
}
// Root mocks base method.

View File

@ -6,7 +6,7 @@ import (
)
type TreeStorage interface {
ID() string
Id() string
Root() (*treechangeproto.RawTreeChangeWithId, error)
Heads() ([]string, error)
SetHeads(heads []string) error

View File

@ -3,14 +3,14 @@ package tree
import (
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
list2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
)
type ObjectTreeValidator interface {
// ValidateFullTree should always be entered while holding a read lock on ACLList
ValidateFullTree(tree *Tree, aclList list2.ACLList) error
ValidateFullTree(tree *Tree, aclList list.ACLList) error
// ValidateNewChanges should always be entered while holding a read lock on ACLList
ValidateNewChanges(tree *Tree, aclList list2.ACLList, newChanges []*Change) error
ValidateNewChanges(tree *Tree, aclList list.ACLList, newChanges []*Change) error
}
type objectTreeValidator struct{}
@ -19,7 +19,7 @@ func newTreeValidator() ObjectTreeValidator {
return &objectTreeValidator{}
}
func (v *objectTreeValidator) ValidateFullTree(tree *Tree, aclList list2.ACLList) (err error) {
func (v *objectTreeValidator) ValidateFullTree(tree *Tree, aclList list.ACLList) (err error) {
tree.Iterate(tree.RootId(), func(c *Change) (isContinue bool) {
err = v.validateChange(tree, aclList, c)
return err == nil
@ -27,7 +27,7 @@ func (v *objectTreeValidator) ValidateFullTree(tree *Tree, aclList list2.ACLList
return err
}
func (v *objectTreeValidator) ValidateNewChanges(tree *Tree, aclList list2.ACLList, newChanges []*Change) (err error) {
func (v *objectTreeValidator) ValidateNewChanges(tree *Tree, aclList list.ACLList, newChanges []*Change) (err error) {
for _, c := range newChanges {
err = v.validateChange(tree, aclList, c)
if err != nil {
@ -37,9 +37,9 @@ func (v *objectTreeValidator) ValidateNewChanges(tree *Tree, aclList list2.ACLLi
return
}
func (v *objectTreeValidator) validateChange(tree *Tree, aclList list2.ACLList, c *Change) (err error) {
func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.ACLList, c *Change) (err error) {
var (
perm list2.UserPermissionPair
perm list.UserPermissionPair
state = aclList.ACLState()
)
// checking if the user could write
@ -49,7 +49,7 @@ func (v *objectTreeValidator) validateChange(tree *Tree, aclList list2.ACLList,
}
if perm.Permission != aclrecordproto.ACLUserPermissions_Writer && perm.Permission != aclrecordproto.ACLUserPermissions_Admin {
err = list2.ErrInsufficientPermissions
err = list.ErrInsufficientPermissions
return
}

View File

@ -126,7 +126,9 @@ func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) {
}
}
objTree.id = objTree.treeStorage.ID()
objTree.id = objTree.treeStorage.Id()
objTree.id = objTree.treeStorage.Id()
objTree.root, err = objTree.treeStorage.Root()
if err != nil {
return nil, err

View File

@ -0,0 +1,44 @@
package testaccount
import (
accountService "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey"
)
// AccountTestService provides service for test purposes, generates new random account every Init
type AccountTestService struct {
acc *account.AccountData
}
func (s *AccountTestService) Init(a *app.App) (err error) {
encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048)
if err != nil {
return
}
signKey, _, err := signingkey.GenerateRandomEd25519KeyPair()
if err != nil {
return
}
ident, err := signKey.GetPublic().Raw()
if err != nil {
return
}
s.acc = &account.AccountData{
Identity: ident,
SignKey: signKey,
EncKey: encKey,
}
return nil
}
func (s *AccountTestService) Name() (name string) {
return accountService.CName
}
func (s *AccountTestService) Account() *account.AccountData {
return s.acc
}

View File

@ -1,3 +1,4 @@
//go:generate mockgen -destination mock_consensusclient/mock_consensusclient.go github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient Service
package consensusclient
import (

View File

@ -13,6 +13,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sync"
"testing"
"time"
)
@ -22,7 +23,7 @@ func TestService_Watch(t *testing.T) {
fx := newFixture(t).run(t)
defer fx.Finish()
var logId = []byte{'1'}
w := &testWatcher{}
w := &testWatcher{ready: make(chan struct{})}
require.NoError(t, fx.Watch(logId, w))
st := fx.testServer.waitStream(t)
req, err := st.Recv()
@ -34,6 +35,7 @@ func TestService_Watch(t *testing.T) {
Error: consensusproto.ErrCodes_ErrorOffset + consensusproto.ErrCodes_LogNotFound,
},
}))
<-w.ready
assert.Equal(t, consensuserr.ErrLogNotFound, w.err)
fx.testServer.releaseStream <- nil
})
@ -188,7 +190,6 @@ func (t *testServer) AddRecord(ctx context.Context, req *consensusproto.AddRecor
}
func (t *testServer) WatchLog(stream consensusproto.DRPCConsensus_WatchLogStream) error {
fmt.Println("watchLog", t.watchErrOnce)
if t.watchErrOnce {
t.watchErrOnce = false
return fmt.Errorf("error")
@ -208,14 +209,22 @@ func (t *testServer) waitStream(test *testing.T) consensusproto.DRPCConsensus_Wa
}
type testWatcher struct {
recs [][]*consensusproto.Record
err error
recs [][]*consensusproto.Record
err error
ready chan struct{}
once sync.Once
}
func (t *testWatcher) AddConsensusRecords(recs []*consensusproto.Record) {
t.recs = append(t.recs, recs)
t.once.Do(func() {
close(t.ready)
})
}
func (t *testWatcher) AddConsensusError(err error) {
t.err = err
t.once.Do(func() {
close(t.ready)
})
}

View File

@ -0,0 +1,150 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient (interfaces: Service)
// Package mock_consensusclient is a generated GoMock package.
package mock_consensusclient
import (
context "context"
reflect "reflect"
app "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
consensusclient "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient"
consensusproto "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto"
gomock "github.com/golang/mock/gomock"
)
// MockService is a mock of Service interface.
type MockService struct {
ctrl *gomock.Controller
recorder *MockServiceMockRecorder
}
// MockServiceMockRecorder is the mock recorder for MockService.
type MockServiceMockRecorder struct {
mock *MockService
}
// NewMockService creates a new mock instance.
func NewMockService(ctrl *gomock.Controller) *MockService {
mock := &MockService{ctrl: ctrl}
mock.recorder = &MockServiceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockService) EXPECT() *MockServiceMockRecorder {
return m.recorder
}
// AddLog mocks base method.
func (m *MockService) AddLog(arg0 context.Context, arg1 *consensusproto.Log) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddLog", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// AddLog indicates an expected call of AddLog.
func (mr *MockServiceMockRecorder) AddLog(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLog", reflect.TypeOf((*MockService)(nil).AddLog), arg0, arg1)
}
// AddRecord mocks base method.
func (m *MockService) AddRecord(arg0 context.Context, arg1 []byte, arg2 *consensusproto.Record) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddRecord", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// AddRecord indicates an expected call of AddRecord.
func (mr *MockServiceMockRecorder) AddRecord(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRecord", reflect.TypeOf((*MockService)(nil).AddRecord), arg0, arg1, arg2)
}
// Close mocks base method.
func (m *MockService) Close(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Close indicates an expected call of Close.
func (mr *MockServiceMockRecorder) Close(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0)
}
// Init mocks base method.
func (m *MockService) Init(arg0 *app.App) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Init", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Init indicates an expected call of Init.
func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0)
}
// Name mocks base method.
func (m *MockService) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
return ret0
}
// Name indicates an expected call of Name.
func (mr *MockServiceMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name))
}
// Run mocks base method.
func (m *MockService) Run(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Run", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Run indicates an expected call of Run.
func (mr *MockServiceMockRecorder) Run(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0)
}
// UnWatch mocks base method.
func (m *MockService) UnWatch(arg0 []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UnWatch", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// UnWatch indicates an expected call of UnWatch.
func (mr *MockServiceMockRecorder) UnWatch(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnWatch", reflect.TypeOf((*MockService)(nil).UnWatch), arg0)
}
// Watch mocks base method.
func (m *MockService) Watch(arg0 []byte, arg1 consensusclient.Watcher) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Watch", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// Watch indicates an expected call of Watch.
func (mr *MockServiceMockRecorder) Watch(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockService)(nil).Watch), arg0, arg1)
}

View File

@ -3,6 +3,7 @@ package consensusclient
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto"
"github.com/cheggaaa/mb/v2"
"sync"
)
func runStream(rpcStream consensusproto.DRPCConsensus_WatchLogClient) *stream {
@ -17,6 +18,7 @@ func runStream(rpcStream consensusproto.DRPCConsensus_WatchLogClient) *stream {
type stream struct {
rpcStream consensusproto.DRPCConsensus_WatchLogClient
mb *mb.MB[*consensusproto.WatchLogEvent]
mu sync.Mutex
err error
}
@ -37,6 +39,8 @@ func (s *stream) WaitLogs() []*consensusproto.WatchLogEvent {
}
func (s *stream) Err() error {
s.mu.Lock()
defer s.mu.Unlock()
return s.err
}
@ -45,7 +49,9 @@ func (s *stream) readStream() {
for {
event, err := s.rpcStream.Recv()
if err != nil {
s.mu.Lock()
s.err = err
s.mu.Unlock()
return
}
if err = s.mb.Add(event); err != nil {

134
node/acl/service.go Normal file
View File

@ -0,0 +1,134 @@
package acl
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto"
"time"
)
const CName = "node.acl"
var log = logger.NewNamed(CName)
func New() Service {
return &service{}
}
type Service interface {
CreateLog(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (firstRecId string, err error)
AddRecord(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (id string, err error)
Watch(ctx context.Context, spaceId, aclId string, h synchandler.SyncHandler) (err error)
UnWatch(aclId string) (err error)
app.Component
}
type service struct {
consService consensusclient.Service
account account.Service
}
func (s *service) Init(a *app.App) (err error) {
s.consService = a.MustComponent(consensusclient.CName).(consensusclient.Service)
s.account = a.MustComponent(account.CName).(account.Service)
return
}
func (s *service) Name() (name string) {
return CName
}
func (s *service) CreateLog(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (firstRecId string, err error) {
logId, err := cidToByte(aclId)
if err != nil {
return
}
recId, _, payload, err := s.signAndMarshal(rawRec)
if err != nil {
return
}
if err = s.consService.AddLog(ctx, &consensusproto.Log{
Id: logId,
Records: []*consensusproto.Record{
{
Id: recId,
Payload: payload,
CreatedUnix: uint64(time.Now().Unix()),
},
},
}); err != nil {
return
}
return cidToString(recId)
}
func (s *service) AddRecord(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (id string, err error) {
logId, err := cidToByte(aclId)
if err != nil {
return
}
recId, prevId, payload, err := s.signAndMarshal(rawRec)
if err != nil {
return
}
if err = s.consService.AddRecord(ctx, logId, &consensusproto.Record{
Id: recId,
PrevId: prevId,
Payload: payload,
CreatedUnix: uint64(time.Now().Unix()),
}); err != nil {
return
}
return cidToString(recId)
}
func (s *service) Watch(ctx context.Context, spaceId, aclId string, h synchandler.SyncHandler) (err error) {
w, err := newWatcher(spaceId, aclId, h)
if err != nil {
return
}
if err = s.consService.Watch(w.logId, w); err != nil {
return err
}
return w.Ready(ctx)
}
func (s *service) UnWatch(aclId string) (err error) {
logId, err := cidToByte(aclId)
if err != nil {
return
}
return s.consService.UnWatch(logId)
}
func (s *service) signAndMarshal(rawRec *aclrecordproto.RawACLRecord) (recId, prevId, payload []byte, err error) {
var rec = &aclrecordproto.ACLRecord{}
if err = rec.Unmarshal(rawRec.Payload); err != nil {
return
}
if rec.PrevId != "" {
if prevId, err = cidToByte(rec.PrevId); err != nil {
return
}
}
rawRec.AcceptorIdentity = s.account.Account().Identity
if rawRec.AcceptorSignature, err = s.account.Account().SignKey.Sign(rawRec.Payload); err != nil {
return
}
if payload, err = rawRec.Marshal(); err != nil {
return
}
recCid, err := cid.NewCIDFromBytes(payload)
if err != nil {
return
}
recId, err = cidToByte(recCid)
return
}

195
node/acl/service_test.go Normal file
View File

@ -0,0 +1,195 @@
package acl
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/testutil/testaccount"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient/mock_consensusclient"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
"time"
)
var ctx = context.Background()
func TestService_CreateLog(t *testing.T) {
fx := newFixture(t)
defer fx.Finish(t)
var clog *consensusproto.Log
fx.mockClient.EXPECT().AddLog(ctx, gomock.Any()).Do(func(ctx context.Context, l *consensusproto.Log) {
clog = l
})
aclId, _ := cid.NewCIDFromBytes([]byte("aclId"))
rec := &aclrecordproto.ACLRecord{
PrevId: "",
Identity: fx.account.Account().Identity,
Data: []byte{'1', '2', '3'},
Timestamp: time.Now().Unix(),
}
pl, _ := rec.Marshal()
firstRecId, err := fx.CreateLog(ctx, aclId, &aclrecordproto.RawACLRecord{
Payload: pl,
})
require.NoError(t, err)
aclIdBytes, _ := cidToByte(aclId)
firstRecIdBytes, _ := cidToByte(firstRecId)
assert.Equal(t, aclIdBytes, clog.Id)
assert.NotEmpty(t, firstRecIdBytes)
require.Len(t, clog.Records, 1)
var resultRawAcl = &aclrecordproto.RawACLRecord{}
require.NoError(t, resultRawAcl.Unmarshal(clog.Records[0].Payload))
valid, err := fx.account.Account().SignKey.GetPublic().Verify(resultRawAcl.Payload, resultRawAcl.AcceptorSignature)
require.NoError(t, err)
require.True(t, valid)
}
func TestService_AddRecord(t *testing.T) {
fx := newFixture(t)
defer fx.Finish(t)
var clog *consensusproto.Log
fx.mockClient.EXPECT().AddLog(ctx, gomock.Any()).Do(func(ctx context.Context, l *consensusproto.Log) {
clog = l
})
aclId, _ := cid.NewCIDFromBytes([]byte("aclId"))
rec := &aclrecordproto.ACLRecord{
PrevId: "",
Identity: fx.account.Account().Identity,
Data: []byte{'1', '2', '3'},
Timestamp: time.Now().Unix(),
}
pl, _ := rec.Marshal()
firstRecId, err := fx.CreateLog(ctx, aclId, &aclrecordproto.RawACLRecord{
Payload: pl,
})
require.NoError(t, err)
aclIdBytes, _ := cidToByte(aclId)
firstRecIdBytes, _ := cidToByte(firstRecId)
assert.Equal(t, aclIdBytes, clog.Id)
assert.NotEmpty(t, firstRecIdBytes)
var addRec *consensusproto.Record
fx.mockClient.EXPECT().AddRecord(ctx, aclIdBytes, gomock.Any()).Do(func(ctx context.Context, logId []byte, rec *consensusproto.Record) {
addRec = rec
})
rec = &aclrecordproto.ACLRecord{
PrevId: firstRecId,
Identity: fx.account.Account().Identity,
Data: []byte{'1', '2', '3', '4'},
Timestamp: time.Now().Unix(),
}
pl, _ = rec.Marshal()
newRecId, err := fx.AddRecord(ctx, aclId, &aclrecordproto.RawACLRecord{
Payload: pl,
})
require.NoError(t, err)
assert.NotEmpty(t, newRecId)
assert.Equal(t, firstRecIdBytes, addRec.PrevId)
}
func TestService_Watch(t *testing.T) {
t.Run("remote error", func(t *testing.T) {
fx := newFixture(t)
defer fx.Finish(t)
var expErr = fmt.Errorf("error")
aclId, _ := cid.NewCIDFromBytes([]byte("aclId"))
aclIdBytes, _ := cidToByte(aclId)
fx.mockClient.EXPECT().Watch(aclIdBytes, gomock.Any()).Do(func(aid []byte, w consensusclient.Watcher) {
assert.Equal(t, aclIdBytes, aid)
go func() {
time.Sleep(time.Millisecond * 10)
w.AddConsensusError(expErr)
}()
})
th := &testHandler{}
err := fx.Watch(ctx, "123", aclId, th)
assert.Equal(t, expErr, err)
})
t.Run("success", func(t *testing.T) {
fx := newFixture(t)
defer fx.Finish(t)
aclId, _ := cid.NewCIDFromBytes([]byte("aclId"))
aclIdBytes, _ := cidToByte(aclId)
fx.mockClient.EXPECT().Watch(aclIdBytes, gomock.Any()).Do(func(aid []byte, w consensusclient.Watcher) {
assert.Equal(t, aclIdBytes, aid)
go func() {
time.Sleep(time.Millisecond * 10)
r1cid, _ := cid.NewCIDFromBytes([]byte("r1"))
r2cid, _ := cid.NewCIDFromBytes([]byte("r2"))
r1cidB, _ := cidToByte(r1cid)
r2cidB, _ := cidToByte(r2cid)
w.AddConsensusRecords([]*consensusproto.Record{
{
Id: r2cidB,
PrevId: r1cidB,
Payload: []byte("p1"),
},
{
Id: r1cidB,
Payload: []byte("p1"),
},
})
}()
})
th := &testHandler{}
err := fx.Watch(ctx, "123", aclId, th)
require.NoError(t, err)
})
}
func newFixture(t *testing.T) *fixture {
fx := &fixture{
a: new(app.App),
ctrl: gomock.NewController(t),
account: &testaccount.AccountTestService{},
}
fx.mockClient = mock_consensusclient.NewMockService(fx.ctrl)
fx.mockClient.EXPECT().Name().Return(consensusclient.CName).AnyTimes()
fx.mockClient.EXPECT().Init(gomock.Any()).AnyTimes()
fx.mockClient.EXPECT().Run(gomock.Any()).AnyTimes()
fx.mockClient.EXPECT().Close(gomock.Any()).AnyTimes()
fx.Service = New()
fx.a.Register(fx.account).Register(fx.mockClient).Register(fx.Service)
require.NoError(t, fx.a.Start(ctx))
return fx
}
type fixture struct {
Service
mockClient *mock_consensusclient.MockService
ctrl *gomock.Controller
a *app.App
account *testaccount.AccountTestService
}
func (fx *fixture) Finish(t *testing.T) {
require.NoError(t, fx.a.Close(ctx))
fx.ctrl.Finish()
}
type testHandler struct {
req *spacesyncproto.ObjectSyncMessage
}
func (t *testHandler) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) {
t.req = request
return
}

19
node/acl/util.go Normal file
View File

@ -0,0 +1,19 @@
package acl
import "github.com/ipfs/go-cid"
func cidToString(b []byte) (s string, err error) {
rcid, err := cid.Cast(b)
if err != nil {
return
}
return rcid.String(), nil
}
func cidToByte(s string) (b []byte, err error) {
rcid, err := cid.Decode(s)
if err != nil {
return
}
return rcid.Bytes(), nil
}

16
node/acl/util_test.go Normal file
View File

@ -0,0 +1,16 @@
package acl
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid"
"github.com/stretchr/testify/assert"
"testing"
)
func TestCIDLen(t *testing.T) {
s, _ := cid.NewCIDFromBytes([]byte("some data"))
t.Log(s, len(s))
b, _ := cidToByte(s)
t.Log(b, len(b))
s2, _ := cidToString(b)
assert.Equal(t, s, s2)
}

93
node/acl/watcher.go Normal file
View File

@ -0,0 +1,93 @@
package acl
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto"
"go.uber.org/zap"
"sync"
)
func newWatcher(spaceId, aclId string, h synchandler.SyncHandler) (w *watcher, err error) {
w = &watcher{
aclId: aclId,
spaceId: spaceId,
handler: h,
ready: make(chan struct{}),
}
if w.logId, err = cidToByte(aclId); err != nil {
return nil, err
}
return
}
type watcher struct {
spaceId string
aclId string
logId []byte
handler synchandler.SyncHandler
ready chan struct{}
isReady sync.Once
err error
}
func (w *watcher) AddConsensusRecords(recs []*consensusproto.Record) {
w.isReady.Do(func() {
close(w.ready)
})
records := make([]*aclrecordproto.RawACLRecordWithId, 0, len(recs))
for _, rec := range recs {
recId, err := cidToString(rec.Id)
if err != nil {
log.Error("received invalid id from consensus node", zap.Error(err))
continue
}
records = append(records, &aclrecordproto.RawACLRecordWithId{
Payload: rec.Payload,
Id: recId,
})
}
aclReq := &aclrecordproto.ACLSyncMessage{
Content: &aclrecordproto.ACLSyncContentValue{
Value: &aclrecordproto.ACLSyncContentValue_AddRecords{
AddRecords: &aclrecordproto.ACLAddRecords{
Records: records,
},
},
},
}
payload, err := aclReq.Marshal()
if err != nil {
log.Error("acl payload marshal error", zap.Error(err))
return
}
req := &spacesyncproto.ObjectSyncMessage{
SpaceId: w.spaceId,
Payload: payload,
ObjectId: w.aclId,
}
if err = w.handler.HandleMessage(context.TODO(), "", req); err != nil {
log.Warn("handle message error", zap.Error(err))
}
}
func (w *watcher) AddConsensusError(err error) {
w.isReady.Do(func() {
w.err = err
close(w.ready)
})
}
func (w *watcher) Ready(ctx context.Context) (err error) {
select {
case <-w.ready:
return w.err
case <-ctx.Done():
return ctx.Err()
}
}

View File

@ -7,7 +7,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
config2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache"
"time"
@ -28,20 +28,18 @@ type Service interface {
}
type service struct {
conf config2.Space
conf config.Space
spaceCache ocache.OCache
commonSpace commonspace.Service
spaceStorageProvider storage.SpaceStorageProvider
}
func (s *service) Init(a *app.App) (err error) {
s.conf = a.MustComponent(config2.CName).(*config2.Config).Space
s.conf = a.MustComponent(config.CName).(*config.Config).Space
s.commonSpace = a.MustComponent(commonspace.CName).(commonspace.Service)
s.spaceStorageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider)
s.spaceCache = ocache.New(
func(ctx context.Context, id string) (value ocache.Object, err error) {
return s.commonSpace.GetSpace(ctx, id)
},
s.loadSpace,
ocache.WithLogger(log.Sugar()),
ocache.WithGCPeriod(time.Minute),
ocache.WithTTL(time.Duration(s.conf.GCTTL)*time.Second),
@ -69,6 +67,21 @@ func (s *service) AddSpace(ctx context.Context, description commonspace.SpaceDes
return s.commonSpace.AddSpace(ctx, description)
}
func (s *service) loadSpace(ctx context.Context, id string) (value ocache.Object, err error) {
cc, err := s.commonSpace.NewSpace(ctx, id)
if err != nil {
return
}
ns, err := newNodeSpace(cc)
if err != nil {
return
}
if err = ns.Init(ctx); err != nil {
return
}
return ns, nil
}
func (s *service) Close(ctx context.Context) (err error) {
return s.spaceCache.Close()
}

24
node/nodespace/space.go Normal file
View File

@ -0,0 +1,24 @@
package nodespace
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace"
)
func newNodeSpace(cc commonspace.Space) (commonspace.Space, error) {
return &nodeSpace{cc}, nil
}
type nodeSpace struct {
commonspace.Space
}
func (s *nodeSpace) Init(ctx context.Context) (err error) {
// try to push acl to consensus node
//
return s.Space.Init(ctx)
}
func (s *nodeSpace) Close() (err error) {
return s.Space.Close()
}

View File

@ -82,7 +82,7 @@ func createListStorage(db *pogreb.DB, root *aclrecordproto.RawACLRecordWithId) (
return
}
func (l *listStorage) ID() string {
func (l *listStorage) Id() string {
return l.id
}

View File

@ -9,7 +9,7 @@ import (
)
func testList(t *testing.T, store storage.ListStorage, root *aclrecordproto.RawACLRecordWithId, head string) {
require.Equal(t, store.ID(), root.Id)
require.Equal(t, store.Id(), root.Id)
aclRoot, err := store.Root()
require.NoError(t, err)

View File

@ -5,7 +5,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"go.uber.org/zap"
"path"
"sync"
@ -22,7 +22,7 @@ type spaceStorage struct {
spaceId string
objDb *pogreb.DB
keys spaceKeys
aclStorage storage2.ListStorage
aclStorage storage.ListStorage
header *spacesyncproto.RawSpaceHeaderWithId
mx sync.Mutex
}
@ -129,15 +129,15 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate
return
}
func (s *spaceStorage) ID() string {
func (s *spaceStorage) Id() string {
return s.spaceId
}
func (s *spaceStorage) TreeStorage(id string) (storage2.TreeStorage, error) {
func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) {
return newTreeStorage(s.objDb, id)
}
func (s *spaceStorage) CreateTreeStorage(payload storage2.TreeStorageCreatePayload) (ts storage2.TreeStorage, err error) {
func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) {
// we have mutex here, so we prevent overwriting the heads of a tree on concurrent creation
s.mx.Lock()
defer s.mx.Unlock()
@ -145,7 +145,7 @@ func (s *spaceStorage) CreateTreeStorage(payload storage2.TreeStorageCreatePaylo
return createTreeStorage(s.objDb, payload)
}
func (s *spaceStorage) ACLStorage() (storage2.ListStorage, error) {
func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) {
return s.aclStorage, nil
}

View File

@ -3,7 +3,7 @@ package storage
import (
"context"
"github.com/akrylysov/pogreb"
storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
)
@ -86,7 +86,7 @@ func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload)
return
}
func (t *treeStorage) ID() string {
func (t *treeStorage) Id() string {
return t.id
}

View File

@ -43,7 +43,7 @@ func (fx *fixture) stop(t *testing.T) {
}
func testTreePayload(t *testing.T, store storage.TreeStorage, payload storage.TreeStorageCreatePayload) {
require.Equal(t, payload.RootRawChange.Id, store.ID())
require.Equal(t, payload.RootRawChange.Id, store.Id())
root, err := store.Root()
require.NoError(t, err)