WIP root change refactoring
This commit is contained in:
parent
41709d7dd3
commit
d41045aa63
17
Makefile
17
Makefile
@ -12,26 +12,25 @@ endif
|
||||
|
||||
export PATH=$(GOPATH)/bin:$(shell echo $$PATH)
|
||||
|
||||
# TODO: folders were changed, so we should update Makefile and protos generation
|
||||
proto:
|
||||
@echo 'Generating protobuf packages (Go)...'
|
||||
# Uncomment if needed
|
||||
@$(eval ROOT_PKG := pkg)
|
||||
@$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1)
|
||||
@$(eval P_ACL_CHANGES_PATH_PB := $(ROOT_PKG)/acl/aclchanges/aclpb)
|
||||
@$(eval P_ACL_RECORDS_PATH_PB := $(ROOT_PKG)/acl/aclrecordproto)
|
||||
@$(eval P_TREE_CHANGES_PATH_PB := $(ROOT_PKG)/acl/treechangeproto)
|
||||
@$(eval P_SYNC_CHANGES_PATH_PB := syncproto)
|
||||
@$(eval P_TEST_CHANGES_PATH_PB := $(ROOT_PKG)/acl/testutils/testchanges)
|
||||
@$(eval P_TIMESTAMP := Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types)
|
||||
@$(eval P_STRUCT := Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types)
|
||||
@$(eval P_ACL_CHANGES := M$(P_ACL_CHANGES_PATH_PB)/protos/aclchanges.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/$(P_ACL_CHANGES_PATH_PB))
|
||||
@$(eval P_ACL_RECORDS := M$(P_ACL_RECORDS_PATH_PB)/protos/aclrecord.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/$(P_ACL_RECORDS_PATH_PB))
|
||||
@$(eval P_TREE_CHANGES := M$(P_TREE_CHANGES_PATH_PB)/protos/treechange.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/$(P_TREE_CHANGES_PATH_PB))
|
||||
|
||||
# use if needed $(eval PKGMAP := $$(P_TIMESTAMP),$$(P_STRUCT))
|
||||
$(GOGO_START) protoc --gogofaster_out=:. $(P_ACL_CHANGES_PATH_PB)/protos/*.proto
|
||||
$(GOGO_START) protoc --gogofaster_out=:. $(P_ACL_RECORDS_PATH_PB)/protos/*.proto
|
||||
$(GOGO_START) protoc --gogofaster_out=:. $(P_TREE_CHANGES_PATH_PB)/protos/*.proto
|
||||
$(GOGO_START) protoc --gogofaster_out=:. $(P_TEST_CHANGES_PATH_PB)/proto/*.proto
|
||||
$(eval PKGMAP := $$(P_ACL_CHANGES))
|
||||
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. $(P_SYNC_CHANGES_PATH_PB)/proto/*.proto
|
||||
$(eval PKGMAP := $$(P_TREE_CHANGES))
|
||||
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. common/commonspace/spacesyncproto/protos/*.proto
|
||||
|
||||
|
||||
build:
|
||||
@$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/app))
|
||||
go build -v -o bin/anytype-node -ldflags "$(FLAGS)" cmd/node/node.go
|
||||
@ -2,7 +2,7 @@ syntax = "proto3";
|
||||
package anySpace;
|
||||
|
||||
option go_package = "common/commonspace/spacesyncproto";
|
||||
import "pkg/acl/aclchanges/aclpb/protos/aclchanges.proto";
|
||||
import "pkg/acl/treechangeproto/protos/treechange.proto";
|
||||
|
||||
enum ErrCodes {
|
||||
Unexpected = 0;
|
||||
@ -49,7 +49,7 @@ message HeadSyncResponse {
|
||||
message ObjectSyncMessage {
|
||||
string spaceId = 1;
|
||||
ObjectSyncContentValue content = 2;
|
||||
acl.TreeHeader treeHeader = 3;
|
||||
treechange.RootChange treeHeader = 3;
|
||||
string treeId = 4;
|
||||
string trackingId = 5;
|
||||
//
|
||||
@ -70,24 +70,32 @@ message ObjectSyncContentValue {
|
||||
// ObjectHeadUpdate is a message sent on document head update
|
||||
message ObjectHeadUpdate {
|
||||
repeated string heads = 1;
|
||||
repeated acl.RawTreeChangeWithId changes = 2;
|
||||
repeated treechange.RawTreeChangeWithId changes = 2;
|
||||
repeated string snapshotPath = 3;
|
||||
}
|
||||
|
||||
// ObjectHeadUpdate is a message sent when document needs full sync
|
||||
message ObjectFullSyncRequest {
|
||||
repeated string heads = 1;
|
||||
repeated acl.RawTreeChangeWithId changes = 2;
|
||||
repeated treechange.RawTreeChangeWithId changes = 2;
|
||||
repeated string snapshotPath = 3;
|
||||
}
|
||||
|
||||
// ObjectFullSyncResponse is a message sent as a response for a specific full sync
|
||||
message ObjectFullSyncResponse {
|
||||
repeated string heads = 1;
|
||||
repeated acl.RawTreeChangeWithId changes = 2;
|
||||
repeated treechange.RawTreeChangeWithId changes = 2;
|
||||
repeated string snapshotPath = 3;
|
||||
}
|
||||
|
||||
message ObjectErrorResponse {
|
||||
string error = 1;
|
||||
}
|
||||
|
||||
message SpaceHeader {
|
||||
bytes identity = 1;
|
||||
int64 timestamp = 2;
|
||||
string spaceType = 3;
|
||||
uint64 replicationKey = 4;
|
||||
bytes seed = 5;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package spacesyncproto
|
||||
|
||||
import "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
import "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
|
||||
type SpaceStream = DRPCSpace_StreamStream
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ package spacesyncproto
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
aclpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
treechangeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
@ -322,7 +322,7 @@ func (m *HeadSyncResponse) GetResults() []*HeadSyncResult {
|
||||
type ObjectSyncMessage struct {
|
||||
SpaceId string `protobuf:"bytes,1,opt,name=spaceId,proto3" json:"spaceId,omitempty"`
|
||||
Content *ObjectSyncContentValue `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"`
|
||||
TreeHeader *aclpb.TreeHeader `protobuf:"bytes,3,opt,name=treeHeader,proto3" json:"treeHeader,omitempty"`
|
||||
TreeHeader *treechangeproto.RootChange `protobuf:"bytes,3,opt,name=treeHeader,proto3" json:"treeHeader,omitempty"`
|
||||
TreeId string `protobuf:"bytes,4,opt,name=treeId,proto3" json:"treeId,omitempty"`
|
||||
TrackingId string `protobuf:"bytes,5,opt,name=trackingId,proto3" json:"trackingId,omitempty"`
|
||||
}
|
||||
@ -374,7 +374,7 @@ func (m *ObjectSyncMessage) GetContent() *ObjectSyncContentValue {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ObjectSyncMessage) GetTreeHeader() *aclpb.TreeHeader {
|
||||
func (m *ObjectSyncMessage) GetTreeHeader() *treechangeproto.RootChange {
|
||||
if m != nil {
|
||||
return m.TreeHeader
|
||||
}
|
||||
@ -510,7 +510,7 @@ func (*ObjectSyncContentValue) XXX_OneofWrappers() []interface{} {
|
||||
// ObjectHeadUpdate is a message sent on document head update
|
||||
type ObjectHeadUpdate struct {
|
||||
Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"`
|
||||
Changes []*aclpb.RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"`
|
||||
Changes []*treechangeproto.RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"`
|
||||
SnapshotPath []string `protobuf:"bytes,3,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"`
|
||||
}
|
||||
|
||||
@ -554,7 +554,7 @@ func (m *ObjectHeadUpdate) GetHeads() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ObjectHeadUpdate) GetChanges() []*aclpb.RawTreeChangeWithId {
|
||||
func (m *ObjectHeadUpdate) GetChanges() []*treechangeproto.RawTreeChangeWithId {
|
||||
if m != nil {
|
||||
return m.Changes
|
||||
}
|
||||
@ -571,7 +571,7 @@ func (m *ObjectHeadUpdate) GetSnapshotPath() []string {
|
||||
// ObjectHeadUpdate is a message sent when document needs full sync
|
||||
type ObjectFullSyncRequest struct {
|
||||
Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"`
|
||||
Changes []*aclpb.RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"`
|
||||
Changes []*treechangeproto.RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"`
|
||||
SnapshotPath []string `protobuf:"bytes,3,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"`
|
||||
}
|
||||
|
||||
@ -615,7 +615,7 @@ func (m *ObjectFullSyncRequest) GetHeads() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ObjectFullSyncRequest) GetChanges() []*aclpb.RawTreeChangeWithId {
|
||||
func (m *ObjectFullSyncRequest) GetChanges() []*treechangeproto.RawTreeChangeWithId {
|
||||
if m != nil {
|
||||
return m.Changes
|
||||
}
|
||||
@ -632,7 +632,7 @@ func (m *ObjectFullSyncRequest) GetSnapshotPath() []string {
|
||||
// ObjectFullSyncResponse is a message sent as a response for a specific full sync
|
||||
type ObjectFullSyncResponse struct {
|
||||
Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"`
|
||||
Changes []*aclpb.RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"`
|
||||
Changes []*treechangeproto.RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"`
|
||||
SnapshotPath []string `protobuf:"bytes,3,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"`
|
||||
}
|
||||
|
||||
@ -676,7 +676,7 @@ func (m *ObjectFullSyncResponse) GetHeads() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ObjectFullSyncResponse) GetChanges() []*aclpb.RawTreeChangeWithId {
|
||||
func (m *ObjectFullSyncResponse) GetChanges() []*treechangeproto.RawTreeChangeWithId {
|
||||
if m != nil {
|
||||
return m.Changes
|
||||
}
|
||||
@ -734,6 +734,82 @@ func (m *ObjectErrorResponse) GetError() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type SpaceHeader struct {
|
||||
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||
Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
SpaceType string `protobuf:"bytes,3,opt,name=spaceType,proto3" json:"spaceType,omitempty"`
|
||||
ReplicationKey uint64 `protobuf:"varint,4,opt,name=replicationKey,proto3" json:"replicationKey,omitempty"`
|
||||
Seed []byte `protobuf:"bytes,5,opt,name=seed,proto3" json:"seed,omitempty"`
|
||||
}
|
||||
|
||||
func (m *SpaceHeader) Reset() { *m = SpaceHeader{} }
|
||||
func (m *SpaceHeader) String() string { return proto.CompactTextString(m) }
|
||||
func (*SpaceHeader) ProtoMessage() {}
|
||||
func (*SpaceHeader) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5855f4ef9cf24cdb, []int{11}
|
||||
}
|
||||
func (m *SpaceHeader) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *SpaceHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_SpaceHeader.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 *SpaceHeader) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SpaceHeader.Merge(m, src)
|
||||
}
|
||||
func (m *SpaceHeader) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *SpaceHeader) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SpaceHeader.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SpaceHeader proto.InternalMessageInfo
|
||||
|
||||
func (m *SpaceHeader) GetIdentity() []byte {
|
||||
if m != nil {
|
||||
return m.Identity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SpaceHeader) GetTimestamp() int64 {
|
||||
if m != nil {
|
||||
return m.Timestamp
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *SpaceHeader) GetSpaceType() string {
|
||||
if m != nil {
|
||||
return m.SpaceType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *SpaceHeader) GetReplicationKey() uint64 {
|
||||
if m != nil {
|
||||
return m.ReplicationKey
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *SpaceHeader) GetSeed() []byte {
|
||||
if m != nil {
|
||||
return m.Seed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("anySpace.ErrCodes", ErrCodes_name, ErrCodes_value)
|
||||
proto.RegisterType((*HeadSyncRange)(nil), "anySpace.HeadSyncRange")
|
||||
@ -747,6 +823,7 @@ func init() {
|
||||
proto.RegisterType((*ObjectFullSyncRequest)(nil), "anySpace.ObjectFullSyncRequest")
|
||||
proto.RegisterType((*ObjectFullSyncResponse)(nil), "anySpace.ObjectFullSyncResponse")
|
||||
proto.RegisterType((*ObjectErrorResponse)(nil), "anySpace.ObjectErrorResponse")
|
||||
proto.RegisterType((*SpaceHeader)(nil), "anySpace.SpaceHeader")
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -754,52 +831,57 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_5855f4ef9cf24cdb = []byte{
|
||||
// 712 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4b, 0x6f, 0xd3, 0x40,
|
||||
0x10, 0xf6, 0xa6, 0x79, 0x75, 0xd2, 0x47, 0x58, 0x68, 0x31, 0x41, 0xa4, 0xc1, 0xa7, 0x08, 0xa4,
|
||||
0xa4, 0x0a, 0x17, 0x44, 0xb9, 0xd0, 0x2a, 0x55, 0x22, 0xc4, 0x43, 0x5b, 0x0a, 0x12, 0xe2, 0xb2,
|
||||
0xb5, 0xb7, 0x49, 0xa8, 0x63, 0x1b, 0xef, 0x86, 0xd2, 0x1b, 0x17, 0x38, 0x23, 0xfe, 0x12, 0x17,
|
||||
0x8e, 0x15, 0x27, 0x8e, 0xa8, 0xfd, 0x23, 0x68, 0xc7, 0x76, 0x5e, 0xb8, 0xe5, 0xd6, 0x43, 0xec,
|
||||
0x9d, 0xd9, 0xf9, 0xbe, 0xfd, 0xf6, 0x9b, 0xf5, 0x06, 0x1e, 0xda, 0xfe, 0x70, 0xe8, 0x7b, 0xcd,
|
||||
0xe8, 0x25, 0x03, 0x6e, 0x8b, 0x26, 0x3e, 0xe5, 0x89, 0x67, 0x07, 0xa1, 0xaf, 0xfc, 0x26, 0x3e,
|
||||
0xe5, 0x24, 0xdb, 0xc0, 0x04, 0x2d, 0x72, 0xef, 0x64, 0x4f, 0xe7, 0x2a, 0x9b, 0xc1, 0x51, 0xaf,
|
||||
0xc9, 0x6d, 0x57, 0xff, 0xec, 0x3e, 0xf7, 0x7a, 0x42, 0xea, 0x61, 0x70, 0x90, 0x40, 0x27, 0xf9,
|
||||
0x08, 0x6b, 0x75, 0x61, 0xb9, 0x23, 0xb8, 0xb3, 0x77, 0xe2, 0xd9, 0x4c, 0xe7, 0x29, 0x85, 0xec,
|
||||
0x61, 0xe8, 0x0f, 0x4d, 0x52, 0x23, 0xf5, 0x2c, 0xc3, 0x31, 0x5d, 0x81, 0x8c, 0xf2, 0xcd, 0x0c,
|
||||
0x66, 0x32, 0xca, 0xa7, 0x37, 0x20, 0xe7, 0x0e, 0x86, 0x03, 0x65, 0x2e, 0xd4, 0x48, 0x7d, 0x99,
|
||||
0x45, 0x81, 0x75, 0x0c, 0x2b, 0x63, 0x2a, 0x21, 0x47, 0xae, 0xd2, 0x5c, 0x7d, 0x2e, 0xfb, 0xc8,
|
||||
0xb5, 0xc4, 0x70, 0x4c, 0xb7, 0xa0, 0x28, 0x5c, 0x31, 0x14, 0x9e, 0x92, 0x66, 0xa6, 0xb6, 0x50,
|
||||
0x2f, 0xb5, 0x36, 0x1a, 0x89, 0xfe, 0xc6, 0x2c, 0xbe, 0x1d, 0xd5, 0xb1, 0x31, 0x40, 0x2f, 0x6c,
|
||||
0xfb, 0x23, 0x6f, 0xbc, 0x30, 0x06, 0xd6, 0x16, 0xac, 0xa5, 0x02, 0xb5, 0xee, 0x81, 0x83, 0xab,
|
||||
0x2f, 0xb2, 0xcc, 0xc0, 0x41, 0x3d, 0x82, 0x3b, 0xb8, 0x93, 0x45, 0x86, 0x63, 0xeb, 0x1d, 0xac,
|
||||
0x4e, 0xc0, 0x1f, 0x46, 0x42, 0x2a, 0x6a, 0x42, 0x01, 0x2d, 0xee, 0x26, 0xd8, 0x24, 0xa4, 0x4d,
|
||||
0xc8, 0x87, 0xe8, 0x5e, 0x2c, 0xfd, 0x66, 0x8a, 0x74, 0x3d, 0xcf, 0xe2, 0x32, 0x6b, 0x17, 0xca,
|
||||
0x53, 0xd2, 0x02, 0xdf, 0x93, 0x82, 0xb6, 0xa0, 0x10, 0xa2, 0x4c, 0x69, 0x12, 0x64, 0x31, 0x2f,
|
||||
0x32, 0x80, 0x25, 0x85, 0xd6, 0x2f, 0x02, 0xd7, 0x5e, 0x1c, 0xbc, 0x17, 0xb6, 0xd2, 0xb3, 0xcf,
|
||||
0x84, 0x94, 0xbc, 0x27, 0x2e, 0x11, 0xfa, 0x08, 0x0a, 0xb6, 0xef, 0x29, 0xe1, 0x29, 0xdc, 0x6c,
|
||||
0xa9, 0x55, 0x9b, 0xac, 0x31, 0xe1, 0xd9, 0x89, 0x4a, 0x5e, 0x73, 0x77, 0x24, 0x58, 0x02, 0xa0,
|
||||
0x4d, 0x00, 0x15, 0x0a, 0xa1, 0xa5, 0x88, 0x10, 0x9d, 0x2e, 0xb5, 0x56, 0x1b, 0xdc, 0x76, 0x1b,
|
||||
0xaf, 0xc6, 0x69, 0x36, 0x55, 0x42, 0xd7, 0x21, 0xaf, 0xa3, 0xae, 0x63, 0x66, 0x51, 0x45, 0x1c,
|
||||
0xd1, 0xaa, 0x26, 0xe2, 0xf6, 0xd1, 0xc0, 0xeb, 0x75, 0x1d, 0x33, 0x87, 0x73, 0x53, 0x19, 0xeb,
|
||||
0x47, 0x06, 0xd6, 0xd3, 0xc5, 0xd0, 0xc7, 0x00, 0xba, 0x3b, 0xfb, 0x81, 0xc3, 0x95, 0xc0, 0xcd,
|
||||
0x95, 0x5a, 0x95, 0xf9, 0x2d, 0x74, 0xc6, 0x15, 0x1d, 0x83, 0x4d, 0xd5, 0xd3, 0xa7, 0xb0, 0x7a,
|
||||
0x38, 0x72, 0xdd, 0xa9, 0x9e, 0xc6, 0x2e, 0x6c, 0xcc, 0x53, 0xec, 0xce, 0x96, 0x75, 0x0c, 0x36,
|
||||
0x8f, 0xa4, 0xcf, 0xa1, 0x3c, 0x49, 0x45, 0x2d, 0x8c, 0x4d, 0xa9, 0x5d, 0xcc, 0x16, 0xd5, 0x75,
|
||||
0x0c, 0xf6, 0x0f, 0x96, 0xb6, 0x61, 0x59, 0x84, 0xa1, 0x1f, 0x8e, 0xc9, 0xb2, 0x48, 0x76, 0x67,
|
||||
0x9e, 0xac, 0x3d, 0x5d, 0xd4, 0x31, 0xd8, 0x2c, 0x6a, 0xbb, 0x00, 0xb9, 0x8f, 0xda, 0x2a, 0xeb,
|
||||
0x33, 0x81, 0xf2, 0xbc, 0x1f, 0xfa, 0x43, 0xd1, 0x7e, 0x44, 0x27, 0x6c, 0x91, 0x45, 0x81, 0x3e,
|
||||
0x79, 0xf1, 0xd7, 0x1f, 0x9f, 0x5f, 0x13, 0xdb, 0xca, 0xf8, 0xb1, 0xee, 0xec, 0x0e, 0x4e, 0xbd,
|
||||
0x19, 0xa8, 0x7e, 0xd7, 0x61, 0x49, 0x21, 0xb5, 0x60, 0x49, 0x7a, 0x3c, 0x90, 0x7d, 0x5f, 0xbd,
|
||||
0xe4, 0xaa, 0x6f, 0x2e, 0x20, 0xe1, 0x4c, 0xce, 0xfa, 0x42, 0x60, 0x2d, 0xd5, 0xcf, 0x2b, 0xd6,
|
||||
0xf1, 0x95, 0x24, 0x07, 0x6a, 0xbe, 0x13, 0x57, 0x2c, 0xe4, 0x3e, 0x5c, 0x4f, 0x69, 0xa2, 0x16,
|
||||
0x81, 0x4d, 0x8c, 0xbf, 0xd6, 0x28, 0xb8, 0x57, 0x81, 0x62, 0x3b, 0x0c, 0x77, 0x7c, 0x47, 0x48,
|
||||
0xba, 0x02, 0xb0, 0xef, 0x89, 0x4f, 0x81, 0xb0, 0x95, 0x70, 0xca, 0x46, 0xeb, 0x3b, 0x81, 0x1c,
|
||||
0x1e, 0x0a, 0xfa, 0x04, 0x8a, 0xc9, 0xe5, 0x40, 0x6f, 0xa5, 0x5d, 0x18, 0x68, 0x78, 0xa5, 0x92,
|
||||
0x7a, 0x97, 0x44, 0xcb, 0xef, 0x42, 0x7e, 0x4f, 0x85, 0x82, 0x0f, 0xe9, 0xed, 0xb4, 0xdb, 0x20,
|
||||
0xbe, 0x55, 0x2a, 0x97, 0x4d, 0xd6, 0xc9, 0x26, 0xd9, 0xde, 0xfa, 0x79, 0x56, 0x25, 0xa7, 0x67,
|
||||
0x55, 0xf2, 0xe7, 0xac, 0x4a, 0xbe, 0x9d, 0x57, 0x8d, 0xd3, 0xf3, 0xaa, 0xf1, 0xfb, 0xbc, 0x6a,
|
||||
0xbc, 0xbd, 0xfb, 0xdf, 0xff, 0xb0, 0x83, 0x3c, 0xbe, 0x1e, 0xfc, 0x0d, 0x00, 0x00, 0xff, 0xff,
|
||||
0x93, 0x27, 0x56, 0x41, 0xef, 0x06, 0x00, 0x00,
|
||||
// 797 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x55, 0xcd, 0x8e, 0xe3, 0x44,
|
||||
0x10, 0xb6, 0x33, 0x99, 0x49, 0x52, 0x99, 0x99, 0x0d, 0x0d, 0x3b, 0x98, 0x00, 0xd9, 0xe0, 0x03,
|
||||
0x8a, 0x40, 0x4a, 0x50, 0x90, 0x10, 0x30, 0x5c, 0xd8, 0x51, 0x46, 0x89, 0x56, 0xfc, 0xa8, 0x67,
|
||||
0x17, 0x24, 0xc4, 0xa5, 0xd7, 0xae, 0x4d, 0xcc, 0xda, 0x6e, 0xe3, 0xee, 0xb0, 0xe4, 0x09, 0xb8,
|
||||
0x80, 0x84, 0x78, 0x03, 0x9e, 0x85, 0x0b, 0xc7, 0x3d, 0xc2, 0x0d, 0xcd, 0xbc, 0x08, 0xea, 0xb2,
|
||||
0x1d, 0x3b, 0xc1, 0xbb, 0x1c, 0xf7, 0x12, 0x77, 0x7d, 0x5d, 0xf5, 0xf5, 0xd7, 0x55, 0xd5, 0x15,
|
||||
0xf8, 0xd0, 0x93, 0x51, 0x24, 0xe3, 0x49, 0xf6, 0x51, 0x89, 0xf0, 0x70, 0x42, 0xbf, 0x6a, 0x13,
|
||||
0x7b, 0x49, 0x2a, 0xb5, 0x9c, 0xd0, 0xaf, 0x2a, 0xd1, 0x31, 0x01, 0xac, 0x2d, 0xe2, 0xcd, 0x95,
|
||||
0xc1, 0xfa, 0x93, 0xe4, 0xf1, 0x72, 0x22, 0xbc, 0x70, 0xa2, 0x53, 0x44, 0x6f, 0x25, 0xe2, 0x25,
|
||||
0xee, 0x44, 0x96, 0x70, 0x16, 0xea, 0x2e, 0xe0, 0x64, 0x8e, 0xc2, 0xbf, 0xda, 0xc4, 0x1e, 0x37,
|
||||
0x30, 0x63, 0xd0, 0x7c, 0x94, 0xca, 0xc8, 0xb1, 0x87, 0xf6, 0xa8, 0xc9, 0x69, 0xcd, 0x4e, 0xa1,
|
||||
0xa1, 0xa5, 0xd3, 0x20, 0xa4, 0xa1, 0x25, 0x7b, 0x05, 0x0e, 0xc3, 0x20, 0x0a, 0xb4, 0x73, 0x30,
|
||||
0xb4, 0x47, 0x27, 0x3c, 0x33, 0xdc, 0x27, 0x70, 0xba, 0xa5, 0x42, 0xb5, 0x0e, 0xb5, 0xe1, 0x5a,
|
||||
0x09, 0xb5, 0x22, 0xae, 0x63, 0x4e, 0x6b, 0x76, 0x0e, 0x6d, 0x0c, 0x31, 0xc2, 0x58, 0x2b, 0xa7,
|
||||
0x31, 0x3c, 0x18, 0x75, 0xa7, 0x77, 0xc6, 0x85, 0xfc, 0xf1, 0x6e, 0xfc, 0x2c, 0xf3, 0xe3, 0xdb,
|
||||
0x00, 0x73, 0xb0, 0x27, 0xd7, 0xf1, 0xf6, 0x60, 0x32, 0xdc, 0x73, 0xb8, 0x5d, 0x1b, 0x68, 0x74,
|
||||
0x07, 0x3e, 0x9d, 0xde, 0xe1, 0x8d, 0xc0, 0x27, 0x3d, 0x28, 0x7c, 0xba, 0x49, 0x87, 0xd3, 0xda,
|
||||
0xfd, 0x16, 0x6e, 0x95, 0xc1, 0xdf, 0xaf, 0x51, 0x69, 0xe6, 0x40, 0x8b, 0x32, 0xbc, 0x28, 0x62,
|
||||
0x0b, 0x93, 0x4d, 0xe0, 0x28, 0x35, 0x59, 0x2a, 0xa4, 0xbf, 0x5a, 0x23, 0xdd, 0xec, 0xf3, 0xdc,
|
||||
0xcd, 0xbd, 0x84, 0x5e, 0x45, 0x5a, 0x22, 0x63, 0x85, 0x6c, 0x0a, 0xad, 0x94, 0x64, 0x2a, 0xc7,
|
||||
0x26, 0x16, 0xe7, 0x59, 0x09, 0xe0, 0x85, 0xa3, 0xfb, 0xb7, 0x0d, 0x2f, 0x7d, 0xf1, 0xf0, 0x3b,
|
||||
0xf4, 0xb4, 0xd9, 0xfd, 0x0c, 0x95, 0x12, 0x4b, 0x7c, 0x8e, 0xd0, 0x8f, 0xa1, 0xe5, 0xc9, 0x58,
|
||||
0x63, 0xac, 0xe9, 0xb2, 0xdd, 0xe9, 0xb0, 0x3c, 0xa3, 0xe4, 0xb9, 0xc8, 0x5c, 0xbe, 0x12, 0xe1,
|
||||
0x1a, 0x79, 0x11, 0xc0, 0x3e, 0x00, 0x30, 0x6d, 0x62, 0xa4, 0x60, 0x4a, 0x99, 0xee, 0x4e, 0xcf,
|
||||
0xc6, 0x95, 0xce, 0xe1, 0x52, 0xea, 0x0b, 0x5a, 0xf2, 0x8a, 0x27, 0x3b, 0x83, 0x23, 0x63, 0x2d,
|
||||
0x7c, 0xa7, 0x49, 0x62, 0x72, 0x8b, 0x0d, 0x0c, 0x9f, 0xf0, 0x1e, 0x07, 0xf1, 0x72, 0xe1, 0x3b,
|
||||
0x87, 0xb4, 0x57, 0x41, 0xdc, 0x3f, 0x1a, 0x70, 0x56, 0xaf, 0x89, 0x7d, 0x02, 0x60, 0x8a, 0xf4,
|
||||
0x20, 0xf1, 0x85, 0x46, 0xba, 0x63, 0x77, 0xda, 0xdf, 0xbf, 0xc9, 0x7c, 0xeb, 0x31, 0xb7, 0x78,
|
||||
0xc5, 0x9f, 0xdd, 0x83, 0x5b, 0x8f, 0xd6, 0x61, 0x58, 0x29, 0x6d, 0x9e, 0x8c, 0x3b, 0xfb, 0x14,
|
||||
0x97, 0xbb, 0x6e, 0x73, 0x8b, 0xef, 0x47, 0xb2, 0xcf, 0xa1, 0x57, 0x42, 0x59, 0x25, 0xf3, 0xdc,
|
||||
0x0c, 0x9f, 0xcd, 0x96, 0xf9, 0xcd, 0x2d, 0xfe, 0x9f, 0x58, 0x36, 0x83, 0x13, 0x4c, 0x53, 0x99,
|
||||
0x6e, 0xc9, 0x9a, 0x44, 0xf6, 0xe6, 0x3e, 0xd9, 0xac, 0xea, 0x34, 0xb7, 0xf8, 0x6e, 0xd4, 0xdd,
|
||||
0x16, 0x1c, 0xfe, 0x60, 0x52, 0xe5, 0xfe, 0x64, 0x43, 0x6f, 0x3f, 0x1f, 0xe6, 0xbd, 0x98, 0x7c,
|
||||
0x64, 0x8d, 0xd6, 0xe1, 0x99, 0xc1, 0x3e, 0x82, 0x56, 0x56, 0xc9, 0xf2, 0x05, 0x56, 0xab, 0x2b,
|
||||
0x9e, 0xdc, 0x4f, 0x11, 0xb3, 0x02, 0x7f, 0x1d, 0xe8, 0xd5, 0xc2, 0xe7, 0x85, 0x3f, 0x73, 0xe1,
|
||||
0x58, 0xc5, 0x22, 0x51, 0x2b, 0xa9, 0xbf, 0x14, 0x7a, 0xe5, 0x1c, 0x10, 0xef, 0x0e, 0xe6, 0xfe,
|
||||
0x6c, 0xc3, 0xed, 0xda, 0xb4, 0xbe, 0x18, 0x39, 0xbf, 0xd8, 0x45, 0x7b, 0xed, 0xd7, 0xe5, 0xc5,
|
||||
0xe8, 0x79, 0x17, 0x5e, 0xae, 0xa9, 0xac, 0xd1, 0x42, 0x95, 0xcd, 0x5f, 0x72, 0x66, 0xb8, 0xbf,
|
||||
0xdb, 0xd0, 0xa5, 0x6e, 0xc8, 0xdf, 0x58, 0x1f, 0xda, 0x81, 0x8f, 0xb1, 0x0e, 0xf4, 0x26, 0x9f,
|
||||
0xaa, 0x5b, 0x9b, 0xbd, 0x01, 0x1d, 0x1d, 0x44, 0xa8, 0xb4, 0x88, 0x12, 0x6a, 0xf4, 0x03, 0x5e,
|
||||
0x02, 0x66, 0x97, 0x86, 0xc3, 0xfd, 0x4d, 0x92, 0x35, 0x6e, 0x87, 0x97, 0x00, 0x7b, 0x1b, 0x4e,
|
||||
0x53, 0x4c, 0xc2, 0xc0, 0x13, 0x3a, 0x90, 0xf1, 0x3d, 0xdc, 0x50, 0x3b, 0x36, 0xf9, 0x1e, 0x6a,
|
||||
0x26, 0xa8, 0x42, 0xcc, 0x5e, 0xf1, 0x31, 0xa7, 0xf5, 0x3b, 0x7d, 0x68, 0xcf, 0xd2, 0xf4, 0x42,
|
||||
0xfa, 0xa8, 0xd8, 0x29, 0xc0, 0x83, 0x18, 0x7f, 0x4c, 0xd0, 0xd3, 0xe8, 0xf7, 0xac, 0xe9, 0x6f,
|
||||
0x36, 0x1c, 0x92, 0x7e, 0xf6, 0x29, 0xb4, 0x8b, 0xe1, 0xc6, 0x5e, 0xab, 0x1b, 0x78, 0xd4, 0x22,
|
||||
0xfd, 0x7e, 0xed, 0x2c, 0xcc, 0x52, 0x74, 0x09, 0x47, 0x57, 0x3a, 0x45, 0x11, 0xb1, 0xd7, 0xeb,
|
||||
0xa6, 0x59, 0x3e, 0x15, 0xfb, 0xcf, 0xdb, 0x1c, 0xd9, 0xef, 0xd9, 0x77, 0xcf, 0xff, 0xbc, 0x1e,
|
||||
0xd8, 0x4f, 0xaf, 0x07, 0xf6, 0x3f, 0xd7, 0x03, 0xfb, 0xd7, 0x9b, 0x81, 0xf5, 0xf4, 0x66, 0x60,
|
||||
0xfd, 0x75, 0x33, 0xb0, 0xbe, 0x79, 0xeb, 0x7f, 0xff, 0x82, 0x1f, 0x1e, 0xd1, 0xe7, 0xfd, 0x7f,
|
||||
0x03, 0x00, 0x00, 0xff, 0xff, 0x7b, 0x1f, 0x02, 0x55, 0xae, 0x07, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *HeadSyncRange) Marshal() (dAtA []byte, err error) {
|
||||
@ -1386,6 +1468,60 @@ func (m *ObjectErrorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *SpaceHeader) 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 *SpaceHeader) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *SpaceHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Seed) > 0 {
|
||||
i -= len(m.Seed)
|
||||
copy(dAtA[i:], m.Seed)
|
||||
i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Seed)))
|
||||
i--
|
||||
dAtA[i] = 0x2a
|
||||
}
|
||||
if m.ReplicationKey != 0 {
|
||||
i = encodeVarintSpacesync(dAtA, i, uint64(m.ReplicationKey))
|
||||
i--
|
||||
dAtA[i] = 0x20
|
||||
}
|
||||
if len(m.SpaceType) > 0 {
|
||||
i -= len(m.SpaceType)
|
||||
copy(dAtA[i:], m.SpaceType)
|
||||
i = encodeVarintSpacesync(dAtA, i, uint64(len(m.SpaceType)))
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if m.Timestamp != 0 {
|
||||
i = encodeVarintSpacesync(dAtA, i, uint64(m.Timestamp))
|
||||
i--
|
||||
dAtA[i] = 0x10
|
||||
}
|
||||
if len(m.Identity) > 0 {
|
||||
i -= len(m.Identity)
|
||||
copy(dAtA[i:], m.Identity)
|
||||
i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Identity)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintSpacesync(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovSpacesync(v)
|
||||
base := offset
|
||||
@ -1671,6 +1807,33 @@ func (m *ObjectErrorResponse) Size() (n int) {
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *SpaceHeader) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Identity)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovSpacesync(uint64(l))
|
||||
}
|
||||
if m.Timestamp != 0 {
|
||||
n += 1 + sovSpacesync(uint64(m.Timestamp))
|
||||
}
|
||||
l = len(m.SpaceType)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovSpacesync(uint64(l))
|
||||
}
|
||||
if m.ReplicationKey != 0 {
|
||||
n += 1 + sovSpacesync(uint64(m.ReplicationKey))
|
||||
}
|
||||
l = len(m.Seed)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovSpacesync(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovSpacesync(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
@ -2362,7 +2525,7 @@ func (m *ObjectSyncMessage) Unmarshal(dAtA []byte) error {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.TreeHeader == nil {
|
||||
m.TreeHeader = &aclpb.TreeHeader{}
|
||||
m.TreeHeader = &treechangeproto.RootChange{}
|
||||
}
|
||||
if err := m.TreeHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
@ -2733,7 +2896,7 @@ func (m *ObjectHeadUpdate) Unmarshal(dAtA []byte) error {
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Changes = append(m.Changes, &aclpb.RawTreeChangeWithId{})
|
||||
m.Changes = append(m.Changes, &treechangeproto.RawTreeChangeWithId{})
|
||||
if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2881,7 +3044,7 @@ func (m *ObjectFullSyncRequest) Unmarshal(dAtA []byte) error {
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Changes = append(m.Changes, &aclpb.RawTreeChangeWithId{})
|
||||
m.Changes = append(m.Changes, &treechangeproto.RawTreeChangeWithId{})
|
||||
if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -3029,7 +3192,7 @@ func (m *ObjectFullSyncResponse) Unmarshal(dAtA []byte) error {
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Changes = append(m.Changes, &aclpb.RawTreeChangeWithId{})
|
||||
m.Changes = append(m.Changes, &treechangeproto.RawTreeChangeWithId{})
|
||||
if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -3169,6 +3332,194 @@ func (m *ObjectErrorResponse) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *SpaceHeader) 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 ErrIntOverflowSpacesync
|
||||
}
|
||||
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: SpaceHeader: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: SpaceHeader: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowSpacesync
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthSpacesync
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthSpacesync
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Identity == nil {
|
||||
m.Identity = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType)
|
||||
}
|
||||
m.Timestamp = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowSpacesync
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Timestamp |= int64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field SpaceType", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowSpacesync
|
||||
}
|
||||
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 ErrInvalidLengthSpacesync
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthSpacesync
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.SpaceType = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ReplicationKey", wireType)
|
||||
}
|
||||
m.ReplicationKey = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowSpacesync
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.ReplicationKey |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Seed", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowSpacesync
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthSpacesync
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthSpacesync
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Seed = append(m.Seed[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Seed == nil {
|
||||
m.Seed = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipSpacesync(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthSpacesync
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipSpacesync(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/tree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||
)
|
||||
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/tree"
|
||||
|
||||
6
go.mod
6
go.mod
@ -3,6 +3,7 @@ module github.com/anytypeio/go-anytype-infrastructure-experiments
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232
|
||||
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/goccy/go-graphviz v0.0.9
|
||||
@ -16,6 +17,7 @@ require (
|
||||
github.com/multiformats/go-multihash v0.1.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/zeebo/blake3 v0.2.3
|
||||
github.com/zeebo/errs v1.3.0
|
||||
go.uber.org/zap v1.21.0
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
@ -24,7 +26,6 @@ require (
|
||||
|
||||
require (
|
||||
github.com/OneOfOne/xxhash v1.2.8 // indirect
|
||||
github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 // indirect
|
||||
github.com/btcsuite/btcd v0.22.1 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.1.3 // indirect
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
|
||||
@ -32,7 +33,6 @@ require (
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
|
||||
github.com/fogleman/gg v1.3.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
||||
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
|
||||
github.com/libp2p/go-openssl v0.0.7 // indirect
|
||||
@ -47,13 +47,11 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/zeebo/errs v1.3.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
|
||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
lukechampine.com/blake3 v1.1.6 // indirect
|
||||
|
||||
10
go.sum
10
go.sum
@ -32,10 +32,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c=
|
||||
github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U=
|
||||
github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw=
|
||||
@ -117,8 +113,6 @@ github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN
|
||||
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
||||
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
|
||||
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
|
||||
github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g=
|
||||
github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
|
||||
github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs=
|
||||
github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
|
||||
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
@ -184,10 +178,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
|
||||
@ -1,143 +0,0 @@
|
||||
syntax = "proto3";
|
||||
package acl;
|
||||
option go_package = "pkg/acl/aclchanges/aclpb";
|
||||
|
||||
// ACL protos
|
||||
|
||||
message RawACLRecord {
|
||||
bytes payload = 1;
|
||||
bytes signature = 2;
|
||||
string id = 3; // this field is only used on user side for convenience, it should be empty when saving to db
|
||||
}
|
||||
|
||||
message ACLContentValue {
|
||||
oneof value {
|
||||
ACLUserAdd userAdd = 1;
|
||||
ACLUserRemove userRemove = 2;
|
||||
ACLUserPermissionChange userPermissionChange = 3;
|
||||
ACLUserInvite userInvite = 4;
|
||||
ACLUserJoin userJoin = 5;
|
||||
ACLUserConfirm userConfirm = 6;
|
||||
}
|
||||
}
|
||||
|
||||
message ACLData {
|
||||
repeated ACLContentValue aclContent = 1;
|
||||
}
|
||||
|
||||
message ACLState {
|
||||
repeated uint64 readKeyHashes = 1;
|
||||
repeated ACLUserState userStates = 2;
|
||||
map<string, ACLUserInvite> invites = 3; // TODO: later
|
||||
// repeated string unconfirmedUsers = 4; // TODO: later
|
||||
}
|
||||
|
||||
message ACLUserState {
|
||||
bytes identity = 1;
|
||||
bytes encryptionKey = 2;
|
||||
repeated bytes encryptedReadKeys = 3; // all read keys that we know
|
||||
ACLUserPermissions permissions = 4;
|
||||
bool isConfirmed = 5;
|
||||
}
|
||||
|
||||
// we already know identity and encryptionKey
|
||||
message ACLUserAdd {
|
||||
bytes identity = 1; // public signing key
|
||||
bytes encryptionKey = 2; // public encryption key
|
||||
repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user
|
||||
ACLUserPermissions permissions = 4;
|
||||
}
|
||||
|
||||
// TODO: this is not used as of now
|
||||
message ACLUserConfirm { // not needed for read permissions
|
||||
bytes identity = 1; // not needed
|
||||
string userAddId = 2;
|
||||
}
|
||||
|
||||
message ACLUserInvite {
|
||||
bytes acceptPublicKey = 1;
|
||||
bytes encryptPublicKey = 2;
|
||||
repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user
|
||||
ACLUserPermissions permissions = 4;
|
||||
string inviteId = 5;
|
||||
}
|
||||
|
||||
message ACLUserJoin {
|
||||
bytes identity = 1;
|
||||
bytes encryptionKey = 2;
|
||||
bytes acceptSignature = 3; // sign acceptPublicKey
|
||||
string userInviteId = 4;
|
||||
repeated bytes encryptedReadKeys = 5; // the idea is that user should itself reencrypt the keys with the pub key
|
||||
}
|
||||
|
||||
message ACLUserRemove {
|
||||
bytes identity = 1;
|
||||
repeated ACLReadKeyReplace readKeyReplaces = 3; // new read key encrypted for all users
|
||||
}
|
||||
|
||||
message ACLReadKeyReplace {
|
||||
bytes identity = 1;
|
||||
bytes encryptionKey = 2;
|
||||
bytes encryptedReadKey = 3;
|
||||
}
|
||||
|
||||
message ACLUserPermissionChange {
|
||||
bytes identity = 1;
|
||||
ACLUserPermissions permissions = 2;
|
||||
}
|
||||
|
||||
enum ACLUserPermissions {
|
||||
Admin = 0;
|
||||
Writer = 1;
|
||||
Reader = 2;
|
||||
Removed = 3;
|
||||
}
|
||||
|
||||
message ACLRecord {
|
||||
string prevId = 1;
|
||||
bytes identity = 2;
|
||||
bytes data = 3;
|
||||
uint64 currentReadKeyHash = 4;
|
||||
int64 timestamp = 5;
|
||||
}
|
||||
|
||||
message ACLHeader {
|
||||
string firstId = 1;
|
||||
bytes identity = 2; // the identity of the creator
|
||||
}
|
||||
|
||||
// Tree protos
|
||||
|
||||
message RawTreeChange {
|
||||
bytes payload = 1;
|
||||
bytes signature = 2;
|
||||
}
|
||||
|
||||
message RawTreeChangeWithId {
|
||||
bytes rawChange = 1;
|
||||
string id = 2;
|
||||
}
|
||||
|
||||
message TreeChange {
|
||||
repeated string treeHeadIds = 1;
|
||||
string aclHeadId = 2;
|
||||
string snapshotBaseId = 3;
|
||||
bytes changesData = 4;
|
||||
uint64 currentReadKeyHash = 5;
|
||||
int64 timestamp = 6;
|
||||
bytes identity = 7;
|
||||
bool isSnapshot = 8;
|
||||
}
|
||||
|
||||
enum TreeHeaderType {
|
||||
Object = 0;
|
||||
Space = 1;
|
||||
}
|
||||
|
||||
message TreeHeader {
|
||||
string firstId = 1;
|
||||
string aclId = 2;
|
||||
TreeHeaderType treeHeaderType = 3;
|
||||
bytes identity = 4;
|
||||
bytes data = 5; // this should be reserved for the client to add the data it needs
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
package aclchanges
|
||||
|
||||
import (
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
type Change interface {
|
||||
ProtoChange() proto.Marshaler
|
||||
DecryptedChangeContent() []byte
|
||||
Signature() []byte
|
||||
CID() string
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
102
pkg/acl/aclrecordproto/protos/aclrecord.proto
Normal file
102
pkg/acl/aclrecordproto/protos/aclrecord.proto
Normal file
@ -0,0 +1,102 @@
|
||||
syntax = "proto3";
|
||||
package aclrecord;
|
||||
option go_package = "pkg/acl/aclrecordproto";
|
||||
|
||||
message RawACLRecord {
|
||||
bytes payload = 1;
|
||||
bytes signature = 2;
|
||||
}
|
||||
|
||||
message RawACLRecordWithId {
|
||||
bytes payload = 1;
|
||||
string id = 2;
|
||||
}
|
||||
|
||||
message ACLRecord {
|
||||
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;
|
||||
}
|
||||
|
||||
message ACLContentValue {
|
||||
oneof value {
|
||||
ACLUserAdd userAdd = 1;
|
||||
ACLUserRemove userRemove = 2;
|
||||
ACLUserPermissionChange userPermissionChange = 3;
|
||||
ACLUserInvite userInvite = 4;
|
||||
ACLUserJoin userJoin = 5;
|
||||
}
|
||||
}
|
||||
|
||||
message ACLData {
|
||||
repeated ACLContentValue aclContent = 1;
|
||||
}
|
||||
|
||||
message ACLState {
|
||||
repeated uint64 readKeyHashes = 1;
|
||||
repeated ACLUserState userStates = 2;
|
||||
map<string, ACLUserInvite> invites = 3;
|
||||
}
|
||||
|
||||
message ACLUserState {
|
||||
bytes identity = 1;
|
||||
bytes encryptionKey = 2;
|
||||
repeated bytes encryptedReadKeys = 3;
|
||||
ACLUserPermissions permissions = 4;
|
||||
bool isConfirmed = 5;
|
||||
}
|
||||
|
||||
message ACLUserAdd {
|
||||
bytes identity = 1;
|
||||
bytes encryptionKey = 2;
|
||||
repeated bytes encryptedReadKeys = 3;
|
||||
ACLUserPermissions permissions = 4;
|
||||
}
|
||||
|
||||
message ACLUserInvite {
|
||||
bytes acceptPublicKey = 1;
|
||||
bytes encryptPublicKey = 2;
|
||||
repeated bytes encryptedReadKeys = 3;
|
||||
ACLUserPermissions permissions = 4;
|
||||
string inviteId = 5;
|
||||
}
|
||||
|
||||
message ACLUserJoin {
|
||||
bytes identity = 1;
|
||||
bytes encryptionKey = 2;
|
||||
bytes acceptSignature = 3;
|
||||
string inviteId = 4;
|
||||
repeated bytes encryptedReadKeys = 5;
|
||||
}
|
||||
|
||||
message ACLUserRemove {
|
||||
bytes identity = 1;
|
||||
repeated ACLReadKeyReplace readKeyReplaces = 3;
|
||||
}
|
||||
|
||||
message ACLReadKeyReplace {
|
||||
bytes identity = 1;
|
||||
bytes encryptionKey = 2;
|
||||
bytes encryptedReadKey = 3;
|
||||
}
|
||||
|
||||
message ACLUserPermissionChange {
|
||||
bytes identity = 1;
|
||||
ACLUserPermissions permissions = 2;
|
||||
}
|
||||
|
||||
enum ACLUserPermissions {
|
||||
Admin = 0;
|
||||
Writer = 1;
|
||||
Reader = 2;
|
||||
}
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
|
||||
@ -30,14 +30,14 @@ var ErrInvalidSignature = errors.New("signature is invalid")
|
||||
|
||||
type UserPermissionPair struct {
|
||||
Identity string
|
||||
Permission aclpb.ACLUserPermissions
|
||||
Permission aclrecordproto.ACLUserPermissions
|
||||
}
|
||||
|
||||
type ACLState struct {
|
||||
currentReadKeyHash uint64
|
||||
userReadKeys map[uint64]*symmetric.Key
|
||||
userStates map[string]*aclpb.ACLUserState
|
||||
userInvites map[string]*aclpb.ACLUserInvite
|
||||
userStates map[string]*aclrecordproto.ACLUserState
|
||||
userInvites map[string]*aclrecordproto.ACLUserInvite
|
||||
|
||||
signingPubKeyDecoder keys.Decoder
|
||||
encryptionKey encryptionkey.PrivKey
|
||||
@ -56,8 +56,8 @@ func newACLStateWithIdentity(
|
||||
identity: identity,
|
||||
encryptionKey: encryptionKey,
|
||||
userReadKeys: make(map[uint64]*symmetric.Key),
|
||||
userStates: make(map[string]*aclpb.ACLUserState),
|
||||
userInvites: make(map[string]*aclpb.ACLUserInvite),
|
||||
userStates: make(map[string]*aclrecordproto.ACLUserState),
|
||||
userInvites: make(map[string]*aclrecordproto.ACLUserInvite),
|
||||
signingPubKeyDecoder: decoder,
|
||||
permissionsAtRecord: make(map[string][]UserPermissionPair),
|
||||
keychain: common.NewKeychain(),
|
||||
@ -68,8 +68,8 @@ func newACLState(decoder keys.Decoder) *ACLState {
|
||||
return &ACLState{
|
||||
signingPubKeyDecoder: decoder,
|
||||
userReadKeys: make(map[uint64]*symmetric.Key),
|
||||
userStates: make(map[string]*aclpb.ACLUserState),
|
||||
userInvites: make(map[string]*aclpb.ACLUserInvite),
|
||||
userStates: make(map[string]*aclrecordproto.ACLUserState),
|
||||
userInvites: make(map[string]*aclrecordproto.ACLUserInvite),
|
||||
permissionsAtRecord: make(map[string][]UserPermissionPair),
|
||||
keychain: common.NewKeychain(),
|
||||
}
|
||||
@ -106,8 +106,8 @@ func (st *ACLState) PermissionsAtRecord(id string, identity string) (UserPermiss
|
||||
return UserPermissionPair{}, ErrNoSuchUser
|
||||
}
|
||||
|
||||
func (st *ACLState) applyRecord(record *aclpb.ACLRecord) (err error) {
|
||||
aclData := &aclpb.ACLData{}
|
||||
func (st *ACLState) applyRecord(record *aclrecordproto.ACLRecord) (err error) {
|
||||
aclData := &aclrecordproto.ACLData{}
|
||||
|
||||
err = proto.Unmarshal(record.Data, aclData)
|
||||
if err != nil {
|
||||
@ -126,11 +126,11 @@ func (st *ACLState) applyRecord(record *aclpb.ACLRecord) (err error) {
|
||||
func (st *ACLState) applyChangeAndUpdate(recordWrapper *ACLRecord) (err error) {
|
||||
var (
|
||||
change = recordWrapper.Content
|
||||
aclData = &aclpb.ACLData{}
|
||||
aclData = &aclrecordproto.ACLData{}
|
||||
)
|
||||
|
||||
if recordWrapper.Model != nil {
|
||||
aclData = recordWrapper.Model.(*aclpb.ACLData)
|
||||
aclData = recordWrapper.Model.(*aclrecordproto.ACLData)
|
||||
} else {
|
||||
err = proto.Unmarshal(change.Data, aclData)
|
||||
if err != nil {
|
||||
@ -158,7 +158,7 @@ func (st *ACLState) applyChangeAndUpdate(recordWrapper *ACLRecord) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *ACLState) applyChangeData(changeData *aclpb.ACLData, hash uint64, identity []byte) (err error) {
|
||||
func (st *ACLState) applyChangeData(changeData *aclrecordproto.ACLData, hash uint64, identity []byte) (err error) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
return
|
||||
@ -176,7 +176,7 @@ func (st *ACLState) applyChangeData(changeData *aclpb.ACLData, hash uint64, iden
|
||||
return
|
||||
}
|
||||
|
||||
if !st.hasPermission(identity, aclpb.ACLUserPermissions_Admin) {
|
||||
if !st.hasPermission(identity, aclrecordproto.ACLUserPermissions_Admin) {
|
||||
err = fmt.Errorf("user %s must have admin permissions", identity)
|
||||
return
|
||||
}
|
||||
@ -192,7 +192,7 @@ func (st *ACLState) applyChangeData(changeData *aclpb.ACLData, hash uint64, iden
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *ACLState) applyChangeContent(ch *aclpb.ACLContentValue) error {
|
||||
func (st *ACLState) applyChangeContent(ch *aclrecordproto.ACLContentValue) error {
|
||||
switch {
|
||||
case ch.GetUserPermissionChange() != nil:
|
||||
return st.applyUserPermissionChange(ch.GetUserPermissionChange())
|
||||
@ -211,7 +211,7 @@ func (st *ACLState) applyChangeContent(ch *aclpb.ACLContentValue) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (st *ACLState) applyUserPermissionChange(ch *aclpb.ACLUserPermissionChange) error {
|
||||
func (st *ACLState) applyUserPermissionChange(ch *aclrecordproto.ACLUserPermissionChange) error {
|
||||
chIdentity := string(ch.Identity)
|
||||
state, exists := st.userStates[chIdentity]
|
||||
if !exists {
|
||||
@ -222,12 +222,12 @@ func (st *ACLState) applyUserPermissionChange(ch *aclpb.ACLUserPermissionChange)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *ACLState) applyUserInvite(ch *aclpb.ACLUserInvite) error {
|
||||
func (st *ACLState) applyUserInvite(ch *aclrecordproto.ACLUserInvite) error {
|
||||
st.userInvites[ch.InviteId] = ch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *ACLState) applyUserJoin(ch *aclpb.ACLUserJoin) error {
|
||||
func (st *ACLState) applyUserJoin(ch *aclrecordproto.ACLUserJoin) error {
|
||||
invite, exists := st.userInvites[ch.UserInviteId]
|
||||
if !exists {
|
||||
return fmt.Errorf("no such invite with id %s", ch.UserInviteId)
|
||||
@ -266,7 +266,7 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLUserJoin) error {
|
||||
}
|
||||
|
||||
// adding user to the list
|
||||
userState := &aclpb.ACLUserState{
|
||||
userState := &aclrecordproto.ACLUserState{
|
||||
Identity: ch.Identity,
|
||||
EncryptionKey: ch.EncryptionKey,
|
||||
EncryptedReadKeys: ch.EncryptedReadKeys,
|
||||
@ -277,13 +277,13 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLUserJoin) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *ACLState) applyUserAdd(ch *aclpb.ACLUserAdd) error {
|
||||
func (st *ACLState) applyUserAdd(ch *aclrecordproto.ACLUserAdd) error {
|
||||
chIdentity := string(ch.Identity)
|
||||
if _, exists := st.userStates[chIdentity]; exists {
|
||||
return ErrUserAlreadyExists
|
||||
}
|
||||
|
||||
st.userStates[chIdentity] = &aclpb.ACLUserState{
|
||||
st.userStates[chIdentity] = &aclrecordproto.ACLUserState{
|
||||
Identity: ch.Identity,
|
||||
EncryptionKey: ch.EncryptionKey,
|
||||
Permissions: ch.Permissions,
|
||||
@ -304,7 +304,7 @@ func (st *ACLState) applyUserAdd(ch *aclpb.ACLUserAdd) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *ACLState) applyUserRemove(ch *aclpb.ACLUserRemove) error {
|
||||
func (st *ACLState) applyUserRemove(ch *aclrecordproto.ACLUserRemove) error {
|
||||
chIdentity := string(ch.Identity)
|
||||
if chIdentity == st.identity {
|
||||
return ErrDocumentForbidden
|
||||
@ -338,7 +338,7 @@ func (st *ACLState) applyUserRemove(ch *aclpb.ACLUserRemove) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *ACLState) applyUserConfirm(ch *aclpb.ACLUserConfirm) error {
|
||||
func (st *ACLState) applyUserConfirm(ch *aclrecordproto.ACLUserConfirm) error {
|
||||
chIdentity := string(ch.Identity)
|
||||
state, exists := st.userStates[chIdentity]
|
||||
if !exists {
|
||||
@ -365,7 +365,7 @@ func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, e
|
||||
return key, hasher.Sum64(), nil
|
||||
}
|
||||
|
||||
func (st *ACLState) hasPermission(identity []byte, permission aclpb.ACLUserPermissions) bool {
|
||||
func (st *ACLState) hasPermission(identity []byte, permission aclrecordproto.ACLUserPermissions) bool {
|
||||
state, exists := st.userStates[string(identity)]
|
||||
if !exists {
|
||||
return false
|
||||
@ -374,17 +374,17 @@ func (st *ACLState) hasPermission(identity []byte, permission aclpb.ACLUserPermi
|
||||
return state.Permissions == permission
|
||||
}
|
||||
|
||||
func (st *ACLState) isUserJoin(data *aclpb.ACLData) bool {
|
||||
func (st *ACLState) isUserJoin(data *aclrecordproto.ACLData) bool {
|
||||
// if we have a UserJoin, then it should always be the first one applied
|
||||
return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil
|
||||
}
|
||||
|
||||
func (st *ACLState) isUserAdd(data *aclpb.ACLData, identity []byte) bool {
|
||||
func (st *ACLState) isUserAdd(data *aclrecordproto.ACLData, identity []byte) bool {
|
||||
// if we have a UserAdd, then it should always be the first one applied
|
||||
userAdd := data.GetAclContent()[0].GetUserAdd()
|
||||
return data.GetAclContent() != nil && userAdd != nil && bytes.Compare(userAdd.GetIdentity(), identity) == 0
|
||||
}
|
||||
|
||||
func (st *ACLState) GetUserStates() map[string]*aclpb.ACLUserState {
|
||||
func (st *ACLState) GetUserStates() map[string]*aclrecordproto.ACLUserState {
|
||||
return st.userStates
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ package list
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
|
||||
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
|
||||
@ -60,7 +60,7 @@ func BuildACLList(decoder keys.Decoder, storage storage.ListStorage) (ACLList, e
|
||||
}
|
||||
|
||||
func buildWithACLStateBuilder(builder *aclStateBuilder, storage storage.ListStorage) (list ACLList, err error) {
|
||||
header, err := storage.Header()
|
||||
header, err := storage.Root()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/acllistbuilder"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
type ACLRecord struct {
|
||||
Id string
|
||||
Content *aclpb.ACLRecord
|
||||
Content *aclrecordproto.ACLRecord
|
||||
Identity string
|
||||
Model interface{}
|
||||
Sign []byte
|
||||
}
|
||||
|
||||
func NewRecord(id string, aclRecord *aclpb.ACLRecord) *ACLRecord {
|
||||
func NewRecord(id string, aclRecord *aclrecordproto.ACLRecord) *ACLRecord {
|
||||
return &ACLRecord{
|
||||
Id: id,
|
||||
Content: aclRecord,
|
||||
@ -21,17 +21,45 @@ func NewRecord(id string, aclRecord *aclpb.ACLRecord) *ACLRecord {
|
||||
}
|
||||
}
|
||||
|
||||
func NewFromRawRecord(rawRec *aclpb.RawACLRecord) (*ACLRecord, error) {
|
||||
aclRec := &aclpb.ACLRecord{}
|
||||
err := proto.Unmarshal(rawRec.Payload, aclRec)
|
||||
func NewFromRawRecord(rawRecWithId *aclrecordproto.RawACLRecordWithId) (aclRec *ACLRecord, err error) {
|
||||
rawRec := &aclrecordproto.RawACLRecord{}
|
||||
err = proto.Unmarshal(rawRecWithId.Payload, rawRec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
|
||||
protoAclRec := &aclrecordproto.ACLRecord{}
|
||||
err = proto.Unmarshal(rawRec.Payload, protoAclRec)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return &ACLRecord{
|
||||
Id: rawRec.Id,
|
||||
Content: aclRec,
|
||||
Id: rawRecWithId.Id,
|
||||
Content: protoAclRec,
|
||||
Sign: rawRec.Signature,
|
||||
Identity: string(aclRec.Identity),
|
||||
Identity: string(protoAclRec.Identity),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewFromRawRoot(rawRecWithId *aclrecordproto.RawACLRecordWithId) (aclRec *ACLRecord, err error) {
|
||||
rawRec := &aclrecordproto.RawACLRecord{}
|
||||
err = proto.Unmarshal(rawRecWithId.Payload, rawRec)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
protoAclRec := &aclrecordproto.ACLRecord{}
|
||||
err = proto.Unmarshal(rawRec.Payload, protoAclRec)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return &ACLRecord{
|
||||
Id: rawRecWithId.Id,
|
||||
Content: protoAclRec,
|
||||
Sign: rawRec.Signature,
|
||||
Identity: string(protoAclRec.Identity),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@ -3,14 +3,13 @@ package storage
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type inMemoryACLListStorage struct {
|
||||
header *aclpb.ACLHeader
|
||||
records []*aclpb.RawACLRecord
|
||||
|
||||
records []*aclrecordproto.RawACLRecordWithId
|
||||
id string
|
||||
|
||||
sync.RWMutex
|
||||
@ -18,29 +17,27 @@ type inMemoryACLListStorage struct {
|
||||
|
||||
func NewInMemoryACLListStorage(
|
||||
id string,
|
||||
header *aclpb.ACLHeader,
|
||||
records []*aclpb.RawACLRecord) (ListStorage, error) {
|
||||
records []*aclrecordproto.RawACLRecordWithId) (ListStorage, error) {
|
||||
return &inMemoryACLListStorage{
|
||||
id: id,
|
||||
header: header,
|
||||
records: records,
|
||||
RWMutex: sync.RWMutex{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *inMemoryACLListStorage) Header() (*aclpb.ACLHeader, error) {
|
||||
func (i *inMemoryACLListStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) {
|
||||
i.RLock()
|
||||
defer i.RUnlock()
|
||||
return i.header, nil
|
||||
return i.records[0], nil
|
||||
}
|
||||
|
||||
func (i *inMemoryACLListStorage) Head() (*aclpb.RawACLRecord, error) {
|
||||
func (i *inMemoryACLListStorage) Head() (*aclrecordproto.RawACLRecordWithId, error) {
|
||||
i.RLock()
|
||||
defer i.RUnlock()
|
||||
return i.records[len(i.records)-1], nil
|
||||
}
|
||||
|
||||
func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*aclpb.RawACLRecord, error) {
|
||||
func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*aclrecordproto.RawACLRecordWithId, error) {
|
||||
i.RLock()
|
||||
defer i.RUnlock()
|
||||
for _, rec := range i.records {
|
||||
@ -51,7 +48,7 @@ func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*
|
||||
return nil, fmt.Errorf("no such record")
|
||||
}
|
||||
|
||||
func (i *inMemoryACLListStorage) AddRawRecord(ctx context.Context, rec *aclpb.RawACLRecord) error {
|
||||
func (i *inMemoryACLListStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@ -63,26 +60,27 @@ func (i *inMemoryACLListStorage) ID() (string, error) {
|
||||
|
||||
type inMemoryTreeStorage struct {
|
||||
id string
|
||||
header *aclpb.TreeHeader
|
||||
root *treechangeproto.RawTreeChangeWithId
|
||||
heads []string
|
||||
changes map[string]*aclpb.RawTreeChangeWithId
|
||||
changes map[string]*treechangeproto.RawTreeChangeWithId
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewInMemoryTreeStorage(
|
||||
treeId string,
|
||||
header *aclpb.TreeHeader,
|
||||
root *treechangeproto.RawTreeChangeWithId,
|
||||
heads []string,
|
||||
changes []*aclpb.RawTreeChangeWithId) (TreeStorage, error) {
|
||||
allChanges := make(map[string]*aclpb.RawTreeChangeWithId)
|
||||
changes []*treechangeproto.RawTreeChangeWithId) (TreeStorage, error) {
|
||||
allChanges := make(map[string]*treechangeproto.RawTreeChangeWithId)
|
||||
for _, ch := range changes {
|
||||
allChanges[ch.Id] = ch
|
||||
}
|
||||
allChanges[treeId] = root
|
||||
|
||||
return &inMemoryTreeStorage{
|
||||
id: treeId,
|
||||
header: header,
|
||||
root: root,
|
||||
heads: heads,
|
||||
changes: allChanges,
|
||||
RWMutex: sync.RWMutex{},
|
||||
@ -95,10 +93,10 @@ func (t *inMemoryTreeStorage) ID() (string, error) {
|
||||
return t.id, nil
|
||||
}
|
||||
|
||||
func (t *inMemoryTreeStorage) Header() (*aclpb.TreeHeader, error) {
|
||||
func (t *inMemoryTreeStorage) Root() (*treechangeproto.RawTreeChangeWithId, error) {
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
return t.header, nil
|
||||
return t.root, nil
|
||||
}
|
||||
|
||||
func (t *inMemoryTreeStorage) Heads() ([]string, error) {
|
||||
@ -118,7 +116,7 @@ func (t *inMemoryTreeStorage) SetHeads(heads []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawTreeChangeWithId) error {
|
||||
func (t *inMemoryTreeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) error {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
// TODO: better to do deep copy
|
||||
@ -126,7 +124,7 @@ func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawTreeChangeWithId) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *inMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string) (*aclpb.RawTreeChangeWithId, error) {
|
||||
func (t *inMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string) (*treechangeproto.RawTreeChangeWithId, error) {
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
if res, exists := t.changes[changeId]; exists {
|
||||
@ -163,7 +161,7 @@ func (i *inMemoryStorageProvider) Storage(id string) (Storage, error) {
|
||||
func (i *inMemoryStorageProvider) CreateTreeStorage(payload TreeStorageCreatePayload) (TreeStorage, error) {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
res, err := NewInMemoryTreeStorage(payload.TreeId, payload.Header, payload.Heads, payload.Changes)
|
||||
res, err := NewInMemoryTreeStorage(payload.TreeId, payload.RootRawChange, payload.Heads, payload.Changes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -175,7 +173,7 @@ func (i *inMemoryStorageProvider) CreateTreeStorage(payload TreeStorageCreatePay
|
||||
func (i *inMemoryStorageProvider) CreateACLListStorage(payload ACLListStorageCreatePayload) (ListStorage, error) {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
res, err := NewInMemoryACLListStorage(payload.ListId, payload.Header, payload.Records)
|
||||
res, err := NewInMemoryACLListStorage(payload.ListId, payload.Records)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -2,14 +2,14 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
|
||||
)
|
||||
|
||||
type ListStorage interface {
|
||||
Storage
|
||||
Header() (*aclpb.ACLHeader, error)
|
||||
Head() (*aclpb.RawACLRecord, error)
|
||||
Root() (*aclrecordproto.RawACLRecordWithId, error)
|
||||
Head() (*aclrecordproto.RawACLRecordWithId, error)
|
||||
|
||||
GetRawRecord(ctx context.Context, id string) (*aclpb.RawACLRecord, error)
|
||||
AddRawRecord(ctx context.Context, rec *aclpb.RawACLRecord) error
|
||||
GetRawRecord(ctx context.Context, id string) (*aclrecordproto.RawACLRecordWithId, error)
|
||||
AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error
|
||||
}
|
||||
|
||||
@ -2,27 +2,26 @@ package storage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
)
|
||||
|
||||
var ErrUnknownTreeId = errors.New("tree does not exist")
|
||||
|
||||
type TreeStorageCreatePayload struct {
|
||||
TreeId string
|
||||
Header *aclpb.TreeHeader
|
||||
Changes []*aclpb.RawTreeChangeWithId
|
||||
RootRawChange *treechangeproto.RawTreeChangeWithId
|
||||
Changes []*treechangeproto.RawTreeChangeWithId
|
||||
Heads []string
|
||||
}
|
||||
|
||||
type ACLListStorageCreatePayload struct {
|
||||
ListId string
|
||||
Header *aclpb.ACLHeader
|
||||
Records []*aclpb.RawACLRecord
|
||||
Records []*aclrecordproto.RawACLRecordWithId
|
||||
}
|
||||
|
||||
type Provider interface {
|
||||
Storage(id string) (Storage, error)
|
||||
AddStorage(id string, st Storage) error
|
||||
CreateTreeStorage(payload TreeStorageCreatePayload) (TreeStorage, error)
|
||||
CreateACLListStorage(payload ACLListStorageCreatePayload) (ListStorage, error)
|
||||
}
|
||||
|
||||
@ -2,17 +2,17 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
)
|
||||
|
||||
type TreeStorage interface {
|
||||
Storage
|
||||
Header() (*aclpb.TreeHeader, error)
|
||||
Root() (*treechangeproto.RawTreeChangeWithId, error)
|
||||
Heads() ([]string, error)
|
||||
SetHeads(heads []string) error
|
||||
|
||||
AddRawChange(change *aclpb.RawTreeChangeWithId) error
|
||||
GetRawChange(ctx context.Context, recordID string) (*aclpb.RawTreeChangeWithId, error)
|
||||
AddRawChange(change *treechangeproto.RawTreeChangeWithId) error
|
||||
GetRawChange(ctx context.Context, id string) (*treechangeproto.RawTreeChangeWithId, error)
|
||||
}
|
||||
|
||||
type TreeStorageCreatorFunc = func(payload TreeStorageCreatePayload) (TreeStorage, error)
|
||||
|
||||
@ -2,11 +2,7 @@ package tree
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -14,68 +10,52 @@ var (
|
||||
ErrIncorrectCID = errors.New("change has incorrect CID")
|
||||
)
|
||||
|
||||
type ChangeContent struct {
|
||||
ChangesData proto.Marshaler
|
||||
ACLData *aclpb.ACLData
|
||||
Id string // TODO: this is just for testing, because id should be created automatically from content
|
||||
}
|
||||
|
||||
// Change is an abstract type for all types of changes
|
||||
type Change struct {
|
||||
Next []*Change
|
||||
PreviousIds []string
|
||||
AclHeadId string
|
||||
Id string
|
||||
SnapshotId string
|
||||
IsSnapshot bool
|
||||
DecryptedChange []byte // TODO: check if we need it
|
||||
ParsedModel interface{} // TODO: check if we need it
|
||||
Timestamp int64
|
||||
ReadKeyHash uint64
|
||||
Identity string
|
||||
Data []byte
|
||||
Model interface{}
|
||||
|
||||
// iterator helpers
|
||||
visited bool
|
||||
branchesFinished bool
|
||||
|
||||
Content *aclpb.TreeChange
|
||||
Identity string
|
||||
Sign []byte
|
||||
Signature []byte
|
||||
}
|
||||
|
||||
func (ch *Change) ProtoChange() proto.Marshaler {
|
||||
return ch.Content
|
||||
}
|
||||
|
||||
func (ch *Change) DecryptContents(key *symmetric.Key) error {
|
||||
// if the document is already decrypted
|
||||
if ch.Content.CurrentReadKeyHash == 0 {
|
||||
return nil
|
||||
}
|
||||
decrypted, err := key.Decrypt(ch.Content.ChangesData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decrypt changes data: %w", err)
|
||||
}
|
||||
|
||||
ch.DecryptedChange = decrypted
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewChange(id string, ch *aclpb.TreeChange, signature []byte) *Change {
|
||||
func NewChange(id string, ch *treechangeproto.TreeChange, signature []byte) *Change {
|
||||
return &Change{
|
||||
Next: nil,
|
||||
PreviousIds: ch.TreeHeadIds,
|
||||
AclHeadId: ch.AclHeadId,
|
||||
Timestamp: ch.Timestamp,
|
||||
ReadKeyHash: ch.CurrentReadKeyHash,
|
||||
Id: id,
|
||||
Content: ch,
|
||||
Data: ch.ChangesData,
|
||||
SnapshotId: ch.SnapshotBaseId,
|
||||
IsSnapshot: ch.IsSnapshot,
|
||||
Identity: string(ch.Identity),
|
||||
Sign: signature,
|
||||
Signature: signature,
|
||||
}
|
||||
}
|
||||
|
||||
func (ch *Change) DecryptedChangeContent() []byte {
|
||||
return ch.DecryptedChange
|
||||
}
|
||||
|
||||
func (ch *Change) Signature() []byte {
|
||||
return ch.Sign
|
||||
func NewChangeFromRoot(id string, ch *treechangeproto.RootChange, signature []byte) *Change {
|
||||
return &Change{
|
||||
Next: nil,
|
||||
AclHeadId: ch.AclHeadId,
|
||||
Id: id,
|
||||
IsSnapshot: true,
|
||||
Identity: string(ch.Identity),
|
||||
Signature: signature,
|
||||
}
|
||||
}
|
||||
|
||||
func (ch *Change) CID() string {
|
||||
|
||||
@ -2,8 +2,8 @@ package tree
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
|
||||
@ -14,32 +14,44 @@ import (
|
||||
var ErrEmptyChange = errors.New("change payload should not be empty")
|
||||
|
||||
type BuilderContent struct {
|
||||
treeHeadIds []string
|
||||
aclHeadId string
|
||||
snapshotBaseId string
|
||||
currentReadKeyHash uint64
|
||||
identity []byte
|
||||
isSnapshot bool
|
||||
signingKey signingkey.PrivKey
|
||||
readKey *symmetric.Key
|
||||
content []byte
|
||||
TreeHeadIds []string
|
||||
AclHeadId string
|
||||
SnapshotBaseId string
|
||||
CurrentReadKeyHash uint64
|
||||
Identity []byte
|
||||
IsSnapshot bool
|
||||
SigningKey signingkey.PrivKey
|
||||
ReadKey *symmetric.Key
|
||||
Content []byte
|
||||
}
|
||||
|
||||
type InitialContent struct {
|
||||
AclHeadId string
|
||||
Identity []byte
|
||||
SigningKey signingkey.PrivKey
|
||||
SpaceId string
|
||||
Seed []byte
|
||||
ChangeType string
|
||||
}
|
||||
|
||||
type ChangeBuilder interface {
|
||||
ConvertFromRaw(rawIdChange *aclpb.RawTreeChangeWithId, verify bool) (ch *Change, err error)
|
||||
BuildContent(payload BuilderContent) (ch *Change, raw *aclpb.RawTreeChangeWithId, err error)
|
||||
BuildRaw(ch *Change) (*aclpb.RawTreeChangeWithId, error)
|
||||
ConvertFromRaw(rawIdChange *treechangeproto.RawTreeChangeWithId, verify bool) (ch *Change, err error)
|
||||
BuildContent(payload BuilderContent) (ch *Change, raw *treechangeproto.RawTreeChangeWithId, err error)
|
||||
BuildInitialContent(payload InitialContent) (ch *Change, raw *treechangeproto.RawTreeChangeWithId, err error)
|
||||
BuildRaw(ch *Change) (*treechangeproto.RawTreeChangeWithId, error)
|
||||
SetRootRawChange(rawIdChange *treechangeproto.RawTreeChangeWithId)
|
||||
}
|
||||
|
||||
type changeBuilder struct {
|
||||
rootChange *treechangeproto.RawTreeChangeWithId
|
||||
keys *common.Keychain
|
||||
}
|
||||
|
||||
func newChangeBuilder(keys *common.Keychain) ChangeBuilder {
|
||||
return &changeBuilder{keys: keys}
|
||||
func newChangeBuilder(keys *common.Keychain, rootChange *treechangeproto.RawTreeChangeWithId) ChangeBuilder {
|
||||
return &changeBuilder{keys: keys, rootChange: rootChange}
|
||||
}
|
||||
|
||||
func (c *changeBuilder) ConvertFromRaw(rawIdChange *aclpb.RawTreeChangeWithId, verify bool) (ch *Change, err error) {
|
||||
func (c *changeBuilder) ConvertFromRaw(rawIdChange *treechangeproto.RawTreeChangeWithId, verify bool) (ch *Change, err error) {
|
||||
if rawIdChange.GetRawChange() == nil {
|
||||
err = ErrEmptyChange
|
||||
return
|
||||
@ -53,7 +65,7 @@ func (c *changeBuilder) ConvertFromRaw(rawIdChange *aclpb.RawTreeChangeWithId, v
|
||||
}
|
||||
}
|
||||
|
||||
raw := &aclpb.RawTreeChange{} // TODO: sync pool
|
||||
raw := &treechangeproto.RawTreeChange{} // TODO: sync pool
|
||||
err = proto.Unmarshal(rawIdChange.GetRawChange(), raw)
|
||||
if err != nil {
|
||||
return
|
||||
@ -78,28 +90,69 @@ func (c *changeBuilder) ConvertFromRaw(rawIdChange *aclpb.RawTreeChangeWithId, v
|
||||
}
|
||||
}
|
||||
|
||||
unmarshalled := &aclpb.TreeChange{}
|
||||
err = proto.Unmarshal(raw.Payload, unmarshalled)
|
||||
return c.unmarshallRawChange(raw, rawIdChange.Id)
|
||||
}
|
||||
|
||||
func (c *changeBuilder) SetRootRawChange(rawIdChange *treechangeproto.RawTreeChangeWithId) {
|
||||
c.rootChange = rawIdChange
|
||||
}
|
||||
|
||||
func (c *changeBuilder) BuildInitialContent(payload InitialContent) (ch *Change, rawIdChange *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
change := &treechangeproto.RootChange{
|
||||
AclHeadId: payload.AclHeadId,
|
||||
Timestamp: int64(time.Now().Nanosecond()),
|
||||
Identity: payload.Identity,
|
||||
ChangeType: payload.ChangeType,
|
||||
SpaceId: payload.SpaceId,
|
||||
Seed: payload.Seed,
|
||||
}
|
||||
|
||||
marshalledChange, err := proto.Marshal(change)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ch = NewChange(rawIdChange.Id, unmarshalled, raw.Signature)
|
||||
signature, err := payload.SigningKey.Sign(marshalledChange)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
raw := &treechangeproto.RawTreeChange{
|
||||
Payload: marshalledChange,
|
||||
Signature: signature,
|
||||
}
|
||||
|
||||
marshalledRawChange, err := proto.Marshal(raw)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
id, err := cid.NewCIDFromBytes(marshalledRawChange)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ch = NewChangeFromRoot(id, change, signature)
|
||||
|
||||
rawIdChange = &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: marshalledRawChange,
|
||||
Id: id,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdChange *aclpb.RawTreeChangeWithId, err error) {
|
||||
change := &aclpb.TreeChange{
|
||||
TreeHeadIds: payload.treeHeadIds,
|
||||
AclHeadId: payload.aclHeadId,
|
||||
SnapshotBaseId: payload.snapshotBaseId,
|
||||
CurrentReadKeyHash: payload.currentReadKeyHash,
|
||||
func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdChange *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
change := &treechangeproto.TreeChange{
|
||||
TreeHeadIds: payload.TreeHeadIds,
|
||||
AclHeadId: payload.AclHeadId,
|
||||
SnapshotBaseId: payload.SnapshotBaseId,
|
||||
CurrentReadKeyHash: payload.CurrentReadKeyHash,
|
||||
Timestamp: int64(time.Now().Nanosecond()),
|
||||
Identity: payload.identity,
|
||||
IsSnapshot: payload.isSnapshot,
|
||||
Identity: payload.Identity,
|
||||
IsSnapshot: payload.IsSnapshot,
|
||||
}
|
||||
|
||||
encrypted, err := payload.readKey.Encrypt(payload.content)
|
||||
encrypted, err := payload.ReadKey.Encrypt(payload.Content)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -110,12 +163,12 @@ func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdC
|
||||
return
|
||||
}
|
||||
|
||||
signature, err := payload.signingKey.Sign(marshalledChange)
|
||||
signature, err := payload.SigningKey.Sign(marshalledChange)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
raw := &aclpb.RawTreeChange{
|
||||
raw := &treechangeproto.RawTreeChange{
|
||||
Payload: marshalledChange,
|
||||
Signature: signature,
|
||||
}
|
||||
@ -131,33 +184,67 @@ func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdC
|
||||
}
|
||||
|
||||
ch = NewChange(id, change, signature)
|
||||
ch.ParsedModel = payload.content
|
||||
ch.Model = payload.Content
|
||||
|
||||
rawIdChange = &aclpb.RawTreeChangeWithId{
|
||||
rawIdChange = &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: marshalledRawChange,
|
||||
Id: id,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *changeBuilder) BuildRaw(ch *Change) (raw *aclpb.RawTreeChangeWithId, err error) {
|
||||
func (c *changeBuilder) BuildRaw(ch *Change) (raw *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
if ch.Id == c.rootChange.Id {
|
||||
return c.rootChange, nil
|
||||
}
|
||||
treeChange := &treechangeproto.TreeChange{
|
||||
TreeHeadIds: ch.PreviousIds,
|
||||
AclHeadId: ch.AclHeadId,
|
||||
SnapshotBaseId: ch.SnapshotId,
|
||||
ChangesData: ch.Data,
|
||||
CurrentReadKeyHash: ch.ReadKeyHash,
|
||||
Timestamp: ch.Timestamp,
|
||||
Identity: []byte(ch.Identity),
|
||||
IsSnapshot: ch.IsSnapshot,
|
||||
}
|
||||
var marshalled []byte
|
||||
marshalled, err = ch.Content.Marshal()
|
||||
marshalled, err = treeChange.Marshal()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
marshalledRawChange, err := proto.Marshal(&aclpb.RawTreeChange{
|
||||
marshalledRawChange, err := proto.Marshal(&treechangeproto.RawTreeChange{
|
||||
Payload: marshalled,
|
||||
Signature: ch.Sign,
|
||||
Signature: ch.Signature,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
raw = &aclpb.RawTreeChangeWithId{
|
||||
raw = &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: marshalledRawChange,
|
||||
Id: ch.Id,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *changeBuilder) unmarshallRawChange(raw *treechangeproto.RawTreeChange, id string) (ch *Change, err error) {
|
||||
if c.rootChange.Id == id {
|
||||
unmarshalled := &treechangeproto.RootChange{}
|
||||
err = proto.Unmarshal(raw.Payload, unmarshalled)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ch = NewChangeFromRoot(id, unmarshalled, raw.Signature)
|
||||
return
|
||||
}
|
||||
|
||||
unmarshalled := &treechangeproto.TreeChange{}
|
||||
err = proto.Unmarshal(raw.Payload, unmarshalled)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ch = NewChange(id, unmarshalled, raw.Signature)
|
||||
return
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ package tree
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
)
|
||||
|
||||
@ -43,12 +43,12 @@ func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.ACLList, c
|
||||
state = aclList.ACLState()
|
||||
)
|
||||
// checking if the user could write
|
||||
perm, err = state.PermissionsAtRecord(c.Content.AclHeadId, c.Identity)
|
||||
perm, err = state.PermissionsAtRecord(c.AclHeadId, c.Identity)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if perm.Permission != aclpb.ACLUserPermissions_Writer && perm.Permission != aclpb.ACLUserPermissions_Admin {
|
||||
if perm.Permission != aclrecordproto.ACLUserPermissions_Writer && perm.Permission != aclrecordproto.ACLUserPermissions_Admin {
|
||||
err = list.ErrInsufficientPermissions
|
||||
return
|
||||
}
|
||||
@ -56,16 +56,16 @@ func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.ACLList, c
|
||||
// checking if the change refers to later acl heads than its previous ids
|
||||
for _, id := range c.PreviousIds {
|
||||
prevChange := tree.attached[id]
|
||||
if prevChange.Content.AclHeadId == c.Content.AclHeadId {
|
||||
if prevChange.AclHeadId == c.AclHeadId {
|
||||
continue
|
||||
}
|
||||
var after bool
|
||||
after, err = aclList.IsAfter(c.Content.AclHeadId, prevChange.Content.AclHeadId)
|
||||
after, err = aclList.IsAfter(c.AclHeadId, prevChange.AclHeadId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !after {
|
||||
err = fmt.Errorf("current acl head id (%s) should be after each of the previous ones (%s)", c.Content.AclHeadId, prevChange.Content.AclHeadId)
|
||||
err = fmt.Errorf("current acl head id (%s) should be after each of the previous ones (%s)", c.AclHeadId, prevChange.AclHeadId)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,10 @@ package tree
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
|
||||
"sync"
|
||||
)
|
||||
@ -27,7 +27,7 @@ type AddResultSummary int
|
||||
type AddResult struct {
|
||||
OldHeads []string
|
||||
Heads []string
|
||||
Added []*aclpb.RawTreeChangeWithId
|
||||
Added []*treechangeproto.RawTreeChangeWithId
|
||||
|
||||
Mode Mode
|
||||
}
|
||||
@ -39,7 +39,7 @@ type ObjectTree interface {
|
||||
RWLocker
|
||||
|
||||
ID() string
|
||||
Header() *aclpb.TreeHeader
|
||||
Header() *treechangeproto.RootChange
|
||||
Heads() []string
|
||||
Root() *Change
|
||||
HasChange(string) bool
|
||||
@ -49,12 +49,12 @@ type ObjectTree interface {
|
||||
IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) error
|
||||
|
||||
SnapshotPath() []string
|
||||
ChangesAfterCommonSnapshot(snapshotPath, heads []string) ([]*aclpb.RawTreeChangeWithId, error)
|
||||
ChangesAfterCommonSnapshot(snapshotPath, heads []string) ([]*treechangeproto.RawTreeChangeWithId, error)
|
||||
|
||||
Storage() storage.TreeStorage
|
||||
|
||||
AddContent(ctx context.Context, content SignableChangeContent) (AddResult, error)
|
||||
AddRawChanges(ctx context.Context, changes ...*aclpb.RawTreeChangeWithId) (AddResult, error)
|
||||
AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (AddResult, error)
|
||||
|
||||
Close() error
|
||||
}
|
||||
@ -68,13 +68,13 @@ type objectTree struct {
|
||||
aclList list.ACLList
|
||||
|
||||
id string
|
||||
header *aclpb.TreeHeader
|
||||
root *treechangeproto.RootChange
|
||||
tree *Tree
|
||||
|
||||
keys map[uint64]*symmetric.Key
|
||||
|
||||
// buffers
|
||||
difSnapshotBuf []*aclpb.RawTreeChangeWithId
|
||||
difSnapshotBuf []*treechangeproto.RawTreeChangeWithId
|
||||
tmpChangesBuf []*Change
|
||||
newSnapshotsBuf []*Change
|
||||
notSeenIdxBuf []int
|
||||
@ -94,11 +94,12 @@ type objectTreeDeps struct {
|
||||
}
|
||||
|
||||
func defaultObjectTreeDeps(
|
||||
rootChange *treechangeproto.RawTreeChangeWithId,
|
||||
treeStorage storage.TreeStorage,
|
||||
aclList list.ACLList) objectTreeDeps {
|
||||
|
||||
keychain := common.NewKeychain()
|
||||
changeBuilder := newChangeBuilder(keychain)
|
||||
changeBuilder := newChangeBuilder(keychain, rootChange)
|
||||
treeBuilder := newTreeBuilder(treeStorage, changeBuilder)
|
||||
return objectTreeDeps{
|
||||
changeBuilder: changeBuilder,
|
||||
@ -131,8 +132,8 @@ func (ot *objectTree) ID() string {
|
||||
return ot.id
|
||||
}
|
||||
|
||||
func (ot *objectTree) Header() *aclpb.TreeHeader {
|
||||
return ot.header
|
||||
func (ot *objectTree) Header() *treechangeproto.RootChange {
|
||||
return ot.root
|
||||
}
|
||||
|
||||
func (ot *objectTree) Storage() storage.TreeStorage {
|
||||
@ -172,7 +173,7 @@ func (ot *objectTree) AddContent(ctx context.Context, content SignableChangeCont
|
||||
res = AddResult{
|
||||
OldHeads: oldHeads,
|
||||
Heads: []string{objChange.Id},
|
||||
Added: []*aclpb.RawTreeChangeWithId{rawChange},
|
||||
Added: []*treechangeproto.RawTreeChangeWithId{rawChange},
|
||||
Mode: Append,
|
||||
}
|
||||
return
|
||||
@ -188,20 +189,20 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
|
||||
return
|
||||
}
|
||||
cnt = BuilderContent{
|
||||
treeHeadIds: ot.tree.Heads(),
|
||||
aclHeadId: ot.aclList.Head().Id,
|
||||
snapshotBaseId: ot.tree.RootId(),
|
||||
currentReadKeyHash: state.CurrentReadKeyHash(),
|
||||
identity: content.Identity,
|
||||
isSnapshot: content.IsSnapshot,
|
||||
signingKey: content.Key,
|
||||
readKey: readKey,
|
||||
content: content.Data,
|
||||
TreeHeadIds: ot.tree.Heads(),
|
||||
AclHeadId: ot.aclList.Head().Id,
|
||||
SnapshotBaseId: ot.tree.RootId(),
|
||||
CurrentReadKeyHash: state.CurrentReadKeyHash(),
|
||||
Identity: content.Identity,
|
||||
IsSnapshot: content.IsSnapshot,
|
||||
SigningKey: content.Key,
|
||||
ReadKey: readKey,
|
||||
Content: content.Data,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawTreeChangeWithId) (addResult AddResult, err error) {
|
||||
func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) {
|
||||
addResult, err = ot.addRawChanges(ctx, rawChanges...)
|
||||
if err != nil {
|
||||
return
|
||||
@ -223,7 +224,7 @@ func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
|
||||
return
|
||||
}
|
||||
|
||||
func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.RawTreeChangeWithId) (addResult AddResult, err error) {
|
||||
func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) {
|
||||
// resetting buffers
|
||||
ot.tmpChangesBuf = ot.tmpChangesBuf[:0]
|
||||
ot.notSeenIdxBuf = ot.notSeenIdxBuf[:0]
|
||||
@ -275,7 +276,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
|
||||
// returns changes that we added to the tree as attached this round
|
||||
// they can include not only the changes that were added now,
|
||||
// but also the changes that were previously in the tree
|
||||
getAddedChanges := func(toConvert []*Change) (added []*aclpb.RawTreeChangeWithId, err error) {
|
||||
getAddedChanges := func(toConvert []*Change) (added []*treechangeproto.RawTreeChangeWithId, err error) {
|
||||
alreadyConverted := make(map[*Change]struct{})
|
||||
|
||||
// first we see if we have already unmarshalled those changes
|
||||
@ -300,7 +301,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
|
||||
for _, ch := range toConvert {
|
||||
// if we got some changes that we need to convert to raw
|
||||
if _, exists := alreadyConverted[ch]; !exists {
|
||||
var raw *aclpb.RawTreeChangeWithId
|
||||
var raw *treechangeproto.RawTreeChangeWithId
|
||||
raw, err = ot.changeBuilder.BuildRaw(ch)
|
||||
if err != nil {
|
||||
return
|
||||
@ -342,7 +343,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
|
||||
ot.rebuildFromStorage(nil)
|
||||
return
|
||||
}
|
||||
var added []*aclpb.RawTreeChangeWithId
|
||||
var added []*treechangeproto.RawTreeChangeWithId
|
||||
added, err = getAddedChanges(nil)
|
||||
// we shouldn't get any error in this case
|
||||
if err != nil {
|
||||
@ -378,7 +379,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
|
||||
err = ErrHasInvalidChanges
|
||||
return
|
||||
}
|
||||
var added []*aclpb.RawTreeChangeWithId
|
||||
var added []*treechangeproto.RawTreeChangeWithId
|
||||
added, err = getAddedChanges(treeChangesAdded)
|
||||
if err != nil {
|
||||
// that means that some unattached changes were somehow corrupted in memory
|
||||
@ -409,17 +410,21 @@ func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate
|
||||
|
||||
ot.tree.Iterate(ot.tree.RootId(), func(c *Change) (isContinue bool) {
|
||||
var model any
|
||||
if c.ParsedModel != nil {
|
||||
if c.Model != nil {
|
||||
return iterate(c)
|
||||
}
|
||||
readKey, exists := ot.keys[c.Content.CurrentReadKeyHash]
|
||||
// if this is a root change
|
||||
if c.Id == ot.id {
|
||||
return iterate(c)
|
||||
}
|
||||
readKey, exists := ot.keys[c.ReadKeyHash]
|
||||
if !exists {
|
||||
err = list.ErrNoReadKey
|
||||
return false
|
||||
}
|
||||
|
||||
var decrypted []byte
|
||||
decrypted, err = readKey.Decrypt(c.Content.GetChangesData())
|
||||
decrypted, err = readKey.Decrypt(c.Data)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@ -429,7 +434,7 @@ func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate
|
||||
return false
|
||||
}
|
||||
|
||||
c.ParsedModel = model
|
||||
c.Model = model
|
||||
return iterate(c)
|
||||
})
|
||||
return
|
||||
@ -474,7 +479,7 @@ func (ot *objectTree) SnapshotPath() []string {
|
||||
return path
|
||||
}
|
||||
|
||||
func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string) ([]*aclpb.RawTreeChangeWithId, error) {
|
||||
func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string) ([]*treechangeproto.RawTreeChangeWithId, error) {
|
||||
var (
|
||||
needFullDocument = len(theirPath) == 0
|
||||
ourPath = ot.SnapshotPath()
|
||||
@ -498,11 +503,11 @@ func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string)
|
||||
}
|
||||
}
|
||||
|
||||
func (ot *objectTree) getChangesFromTree(theirHeads []string) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
|
||||
func (ot *objectTree) getChangesFromTree(theirHeads []string) (rawChanges []*treechangeproto.RawTreeChangeWithId, err error) {
|
||||
return ot.rawChangeLoader.LoadFromTree(ot.tree, theirHeads)
|
||||
}
|
||||
|
||||
func (ot *objectTree) getChangesFromDB(commonSnapshot string, theirHeads []string) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
|
||||
func (ot *objectTree) getChangesFromDB(commonSnapshot string, theirHeads []string) (rawChanges []*treechangeproto.RawTreeChangeWithId, err error) {
|
||||
return ot.rawChangeLoader.LoadFromStorage(commonSnapshot, ot.tree.headIds, theirHeads)
|
||||
}
|
||||
|
||||
|
||||
@ -2,10 +2,12 @@ package tree
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/acllistbuilder"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -14,8 +16,26 @@ import (
|
||||
|
||||
type mockChangeCreator struct{}
|
||||
|
||||
func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot bool, prevIds ...string) *aclpb.RawTreeChangeWithId {
|
||||
aclChange := &aclpb.TreeChange{
|
||||
func (c *mockChangeCreator) createRoot(id, aclId string) *treechangeproto.RawTreeChangeWithId {
|
||||
aclChange := &treechangeproto.RootChange{
|
||||
AclHeadId: aclId,
|
||||
}
|
||||
res, _ := aclChange.Marshal()
|
||||
|
||||
raw := &treechangeproto.RawTreeChange{
|
||||
Payload: res,
|
||||
Signature: nil,
|
||||
}
|
||||
rawMarshalled, _ := raw.Marshal()
|
||||
|
||||
return &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: rawMarshalled,
|
||||
Id: id,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot bool, prevIds ...string) *treechangeproto.RawTreeChangeWithId {
|
||||
aclChange := &treechangeproto.TreeChange{
|
||||
TreeHeadIds: prevIds,
|
||||
AclHeadId: aclId,
|
||||
SnapshotBaseId: snapshotId,
|
||||
@ -24,26 +44,21 @@ func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot b
|
||||
}
|
||||
res, _ := aclChange.Marshal()
|
||||
|
||||
raw := &aclpb.RawTreeChange{
|
||||
raw := &treechangeproto.RawTreeChange{
|
||||
Payload: res,
|
||||
Signature: nil,
|
||||
}
|
||||
rawMarshalled, _ := raw.Marshal()
|
||||
|
||||
return &aclpb.RawTreeChangeWithId{
|
||||
return &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: rawMarshalled,
|
||||
Id: id,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *mockChangeCreator) createNewTreeStorage(treeId, aclListId, aclHeadId, firstChangeId string) storage.TreeStorage {
|
||||
firstChange := c.createRaw(firstChangeId, aclHeadId, "", true)
|
||||
header := &aclpb.TreeHeader{
|
||||
FirstId: firstChangeId,
|
||||
AclId: aclListId,
|
||||
TreeHeaderType: aclpb.TreeHeaderType_Object,
|
||||
}
|
||||
treeStorage, _ := storage.NewInMemoryTreeStorage(treeId, header, []string{firstChangeId}, []*aclpb.RawTreeChangeWithId{firstChange})
|
||||
func (c *mockChangeCreator) createNewTreeStorage(treeId, aclHeadId string) storage.TreeStorage {
|
||||
root := c.createRoot(treeId, aclHeadId)
|
||||
treeStorage, _ := storage.NewInMemoryTreeStorage(treeId, root, []string{root.Id}, []*treechangeproto.RawTreeChangeWithId{root})
|
||||
return treeStorage
|
||||
}
|
||||
|
||||
@ -51,15 +66,23 @@ type mockChangeBuilder struct {
|
||||
originalBuilder ChangeBuilder
|
||||
}
|
||||
|
||||
func (c *mockChangeBuilder) ConvertFromRaw(rawChange *aclpb.RawTreeChangeWithId, verify bool) (ch *Change, err error) {
|
||||
return c.originalBuilder.ConvertFromRaw(rawChange, false)
|
||||
}
|
||||
|
||||
func (c *mockChangeBuilder) BuildContent(payload BuilderContent) (ch *Change, raw *aclpb.RawTreeChangeWithId, err error) {
|
||||
func (c *mockChangeBuilder) BuildInitialContent(payload InitialContent) (ch *Change, raw *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *mockChangeBuilder) BuildRaw(ch *Change) (raw *aclpb.RawTreeChangeWithId, err error) {
|
||||
func (c *mockChangeBuilder) SetRootRawChange(rawIdChange *treechangeproto.RawTreeChangeWithId) {
|
||||
c.originalBuilder.SetRootRawChange(rawIdChange)
|
||||
}
|
||||
|
||||
func (c *mockChangeBuilder) ConvertFromRaw(rawChange *treechangeproto.RawTreeChangeWithId, verify bool) (ch *Change, err error) {
|
||||
return c.originalBuilder.ConvertFromRaw(rawChange, false)
|
||||
}
|
||||
|
||||
func (c *mockChangeBuilder) BuildContent(payload BuilderContent) (ch *Change, raw *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *mockChangeBuilder) BuildRaw(ch *Change) (raw *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
return c.originalBuilder.BuildRaw(ch)
|
||||
}
|
||||
|
||||
@ -93,15 +116,15 @@ func prepareACLList(t *testing.T) list.ACLList {
|
||||
|
||||
func prepareTreeContext(t *testing.T, aclList list.ACLList) testTreeContext {
|
||||
changeCreator := &mockChangeCreator{}
|
||||
treeStorage := changeCreator.createNewTreeStorage("treeId", aclList.ID(), aclList.Head().Id, "0")
|
||||
treeStorage := changeCreator.createNewTreeStorage("0", aclList.Head().Id)
|
||||
root, _ := treeStorage.Root()
|
||||
changeBuilder := &mockChangeBuilder{
|
||||
originalBuilder: newChangeBuilder(nil),
|
||||
originalBuilder: newChangeBuilder(nil, root),
|
||||
}
|
||||
deps := objectTreeDeps{
|
||||
changeBuilder: changeBuilder,
|
||||
treeBuilder: newTreeBuilder(treeStorage, changeBuilder),
|
||||
treeStorage: treeStorage,
|
||||
updateListener: nil,
|
||||
rawChangeLoader: newRawChangeLoader(treeStorage, changeBuilder),
|
||||
validator: &mockChangeValidator{},
|
||||
aclList: aclList,
|
||||
@ -128,6 +151,18 @@ func prepareTreeContext(t *testing.T, aclList list.ACLList) testTreeContext {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSameSignature(t *testing.T) {
|
||||
privKey, _, err := signingkey.GenerateEd25519Key(rand.Reader)
|
||||
require.NoError(t, err)
|
||||
bytes := []byte("asefhiosahjfoiesjgioesajgihs")
|
||||
for i := 0; i < 5; i++ {
|
||||
signed, err := privKey.Sign(bytes)
|
||||
require.NoError(t, err)
|
||||
t.Log(hex.EncodeToString(signed))
|
||||
}
|
||||
// kitten step voyage hand cover funny timber auction differ mushroom update pulp
|
||||
}
|
||||
|
||||
func TestObjectTree(t *testing.T) {
|
||||
aclList := prepareACLList(t)
|
||||
|
||||
@ -137,7 +172,7 @@ func TestObjectTree(t *testing.T) {
|
||||
changeCreator := ctx.changeCreator
|
||||
objTree := ctx.objTree
|
||||
|
||||
rawChanges := []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"),
|
||||
changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"),
|
||||
}
|
||||
@ -178,7 +213,7 @@ func TestObjectTree(t *testing.T) {
|
||||
changeCreator := ctx.changeCreator
|
||||
objTree := ctx.objTree
|
||||
|
||||
rawChanges := []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("0", aclList.Head().Id, "", true, ""),
|
||||
}
|
||||
res, err := objTree.AddRawChanges(context.Background(), rawChanges...)
|
||||
@ -198,7 +233,7 @@ func TestObjectTree(t *testing.T) {
|
||||
changeCreator := ctx.changeCreator
|
||||
objTree := ctx.objTree
|
||||
|
||||
rawChanges := []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"),
|
||||
}
|
||||
res, err := objTree.AddRawChanges(context.Background(), rawChanges...)
|
||||
@ -220,7 +255,7 @@ func TestObjectTree(t *testing.T) {
|
||||
changeCreator := ctx.changeCreator
|
||||
objTree := ctx.objTree
|
||||
|
||||
rawChanges := []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"),
|
||||
changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"),
|
||||
changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"),
|
||||
@ -264,7 +299,7 @@ func TestObjectTree(t *testing.T) {
|
||||
changeCreator := ctx.changeCreator
|
||||
objTree := ctx.objTree
|
||||
|
||||
rawChanges := []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"),
|
||||
changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"),
|
||||
changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"),
|
||||
@ -283,7 +318,7 @@ func TestObjectTree(t *testing.T) {
|
||||
changeCreator := ctx.changeCreator
|
||||
objTree := ctx.objTree
|
||||
|
||||
rawChanges := []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"),
|
||||
changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"),
|
||||
changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"),
|
||||
@ -357,7 +392,7 @@ func TestObjectTree(t *testing.T) {
|
||||
changeCreator := ctx.changeCreator
|
||||
objTree := ctx.objTree
|
||||
|
||||
rawChanges := []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"),
|
||||
changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"),
|
||||
changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"),
|
||||
@ -433,7 +468,7 @@ func TestObjectTree(t *testing.T) {
|
||||
changeCreator := ctx.changeCreator
|
||||
objTree := ctx.objTree
|
||||
|
||||
rawChanges := []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"),
|
||||
changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"),
|
||||
changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"),
|
||||
@ -442,7 +477,7 @@ func TestObjectTree(t *testing.T) {
|
||||
require.NoError(t, err, "adding changes should be without error")
|
||||
require.Equal(t, "3", objTree.Root().Id)
|
||||
|
||||
rawChanges = []*aclpb.RawTreeChangeWithId{
|
||||
rawChanges = []*treechangeproto.RawTreeChangeWithId{
|
||||
changeCreator.createRaw("4", aclList.Head().Id, "0", false, "2"),
|
||||
changeCreator.createRaw("5", aclList.Head().Id, "0", false, "1"),
|
||||
changeCreator.createRaw("6", aclList.Head().Id, "0", false, "3", "4", "5"),
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
package tree
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
@ -13,14 +12,19 @@ import (
|
||||
)
|
||||
|
||||
type ObjectTreeCreatePayload struct {
|
||||
AccountData *account.AccountData
|
||||
HeaderData []byte
|
||||
ChangeData []byte
|
||||
TreeType aclpb.TreeHeaderType
|
||||
SignKey signingkey.PrivKey
|
||||
ChangeType string
|
||||
Seed []byte
|
||||
SpaceId string
|
||||
Identity []byte
|
||||
}
|
||||
|
||||
func BuildObjectTree(treeStorage storage.TreeStorage, aclList list.ACLList) (ObjectTree, error) {
|
||||
deps := defaultObjectTreeDeps(treeStorage, aclList)
|
||||
rootChange, err := treeStorage.Root()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deps := defaultObjectTreeDeps(rootChange, treeStorage, aclList)
|
||||
return buildObjectTree(deps)
|
||||
}
|
||||
|
||||
@ -30,53 +34,34 @@ func CreateObjectTree(
|
||||
createStorage storage.TreeStorageCreatorFunc) (objTree ObjectTree, err error) {
|
||||
aclList.RLock()
|
||||
var (
|
||||
deps = defaultObjectTreeDeps(nil, aclList)
|
||||
state = aclList.ACLState()
|
||||
aclId = aclList.ID()
|
||||
deps = defaultObjectTreeDeps(nil, nil, aclList)
|
||||
aclHeadId = aclList.Head().Id
|
||||
readKeyHash = state.CurrentReadKeyHash()
|
||||
)
|
||||
readKey, err := state.CurrentReadKey()
|
||||
aclList.RUnlock()
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// create first change
|
||||
cnt := BuilderContent{
|
||||
treeHeadIds: nil,
|
||||
aclHeadId: aclHeadId,
|
||||
snapshotBaseId: "",
|
||||
currentReadKeyHash: readKeyHash,
|
||||
isSnapshot: true,
|
||||
readKey: readKey,
|
||||
identity: payload.AccountData.Identity,
|
||||
signingKey: payload.AccountData.SignKey,
|
||||
content: payload.ChangeData,
|
||||
cnt := InitialContent{
|
||||
AclHeadId: aclHeadId,
|
||||
Identity: payload.Identity,
|
||||
SigningKey: payload.SignKey,
|
||||
SpaceId: payload.SpaceId,
|
||||
Seed: payload.Seed,
|
||||
ChangeType: payload.ChangeType,
|
||||
}
|
||||
|
||||
_, raw, err := deps.changeBuilder.BuildContent(cnt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// create header
|
||||
header, id, err := createTreeHeaderAndId(
|
||||
raw,
|
||||
payload.TreeType,
|
||||
aclId,
|
||||
payload.AccountData.Identity,
|
||||
payload.HeaderData)
|
||||
_, raw, err := deps.changeBuilder.BuildInitialContent(cnt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
deps.changeBuilder.SetRootRawChange(raw)
|
||||
|
||||
// create storage
|
||||
st, err := createStorage(storage.TreeStorageCreatePayload{
|
||||
TreeId: id,
|
||||
Header: header,
|
||||
Changes: []*aclpb.RawTreeChangeWithId{raw},
|
||||
TreeId: raw.Id,
|
||||
RootRawChange: raw,
|
||||
Changes: []*treechangeproto.RawTreeChangeWithId{raw},
|
||||
Heads: []string{raw.Id},
|
||||
})
|
||||
if err != nil {
|
||||
@ -98,7 +83,7 @@ func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) {
|
||||
tree: nil,
|
||||
keys: make(map[uint64]*symmetric.Key),
|
||||
tmpChangesBuf: make([]*Change, 0, 10),
|
||||
difSnapshotBuf: make([]*aclpb.RawTreeChangeWithId, 0, 10),
|
||||
difSnapshotBuf: make([]*treechangeproto.RawTreeChangeWithId, 0, 10),
|
||||
notSeenIdxBuf: make([]int, 0, 10),
|
||||
newSnapshotsBuf: make([]*Change, 0, 10),
|
||||
}
|
||||
@ -128,32 +113,23 @@ func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
objTree.header, err = objTree.treeStorage.Header()
|
||||
|
||||
rawRootWithId, err := objTree.treeStorage.Root()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawRoot := &treechangeproto.RawTreeChange{}
|
||||
err = proto.Unmarshal(rawRootWithId.RawChange, rawRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
objTree.root = &treechangeproto.RootChange{}
|
||||
err = proto.Unmarshal(rawRoot.Payload, objTree.root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return objTree, nil
|
||||
}
|
||||
|
||||
func createTreeHeaderAndId(
|
||||
raw *aclpb.RawTreeChangeWithId,
|
||||
treeType aclpb.TreeHeaderType,
|
||||
aclId string,
|
||||
identity []byte,
|
||||
headerData []byte) (header *aclpb.TreeHeader, treeId string, err error) {
|
||||
header = &aclpb.TreeHeader{
|
||||
FirstId: raw.Id,
|
||||
TreeHeaderType: treeType,
|
||||
AclId: aclId,
|
||||
Identity: identity,
|
||||
Data: headerData,
|
||||
}
|
||||
marshalledHeader, err := proto.Marshal(header)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
treeId, err = cid.NewCIDFromBytes(marshalledHeader)
|
||||
return
|
||||
}
|
||||
|
||||
@ -2,8 +2,8 @@ package tree
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -18,7 +18,7 @@ type rawChangeLoader struct {
|
||||
|
||||
type rawCacheEntry struct {
|
||||
change *Change
|
||||
rawChange *aclpb.RawTreeChangeWithId
|
||||
rawChange *treechangeproto.RawTreeChangeWithId
|
||||
position int
|
||||
}
|
||||
|
||||
@ -29,15 +29,15 @@ func newRawChangeLoader(treeStorage storage.TreeStorage, changeBuilder ChangeBui
|
||||
}
|
||||
}
|
||||
|
||||
func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.RawTreeChangeWithId, error) {
|
||||
func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*treechangeproto.RawTreeChangeWithId, error) {
|
||||
var stack []*Change
|
||||
for _, h := range t.headIds {
|
||||
stack = append(stack, t.attached[h])
|
||||
}
|
||||
|
||||
convert := func(chs []*Change) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
|
||||
convert := func(chs []*Change) (rawChanges []*treechangeproto.RawTreeChangeWithId, err error) {
|
||||
for _, ch := range chs {
|
||||
var raw *aclpb.RawTreeChangeWithId
|
||||
var raw *treechangeproto.RawTreeChangeWithId
|
||||
raw, err = r.changeBuilder.BuildRaw(ch)
|
||||
if err != nil {
|
||||
return
|
||||
@ -95,7 +95,7 @@ func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.
|
||||
return convert(results)
|
||||
}
|
||||
|
||||
func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoints []string) ([]*aclpb.RawTreeChangeWithId, error) {
|
||||
func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoints []string) ([]*treechangeproto.RawTreeChangeWithId, error) {
|
||||
// resetting cache
|
||||
r.cache = make(map[string]rawCacheEntry)
|
||||
defer func() {
|
||||
@ -162,7 +162,7 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi
|
||||
|
||||
// preparing first pass
|
||||
r.idStack = append(r.idStack, heads...)
|
||||
var buffer []*aclpb.RawTreeChangeWithId
|
||||
var buffer []*treechangeproto.RawTreeChangeWithId
|
||||
|
||||
rootVisited := dfs(commonSnapshot, heads, 0,
|
||||
func(counter int, mapExists bool) bool {
|
||||
@ -203,7 +203,7 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi
|
||||
})
|
||||
|
||||
// discarding visited
|
||||
buffer = discardFromSlice(buffer, func(change *aclpb.RawTreeChangeWithId) bool {
|
||||
buffer = discardFromSlice(buffer, func(change *treechangeproto.RawTreeChangeWithId) bool {
|
||||
return change == nil
|
||||
})
|
||||
|
||||
|
||||
@ -90,7 +90,7 @@ func (t *Tree) Graph() (data string, err error) {
|
||||
label := fmt.Sprintf("Id: %s\nOrd: %s\nTime: %s\nChanges: %s\n",
|
||||
shortId,
|
||||
ord,
|
||||
time.Unix(c.Content.Timestamp, 0).Format("02.01.06 15:04:05"),
|
||||
time.Unix(c.Timestamp, 0).Format("02.01.06 15:04:05"),
|
||||
strings.Join(chSymbs, ","),
|
||||
)
|
||||
n.SetLabel(label)
|
||||
|
||||
55
pkg/acl/treechangeproto/protos/treechange.proto
Normal file
55
pkg/acl/treechangeproto/protos/treechange.proto
Normal file
@ -0,0 +1,55 @@
|
||||
syntax = "proto3";
|
||||
package treechange;
|
||||
option go_package = "pkg/acl/treechangeproto";
|
||||
|
||||
// RootChange is a root of a tree
|
||||
message RootChange {
|
||||
// AclHeadId is a cid of latest acl record at the time of tree creation
|
||||
string aclHeadId = 1;
|
||||
// SpaceId is an id of space where the document is placed
|
||||
string spaceId = 2;
|
||||
// ChangeType is a type of tree which this RootChange is a root of
|
||||
string changeType = 3;
|
||||
// Timestamp is this change creation timestamp
|
||||
int64 timestamp = 4;
|
||||
// Seed is a random bytes to make root change unique
|
||||
bytes seed = 5;
|
||||
// Identity is a public key of the tree's creator
|
||||
bytes identity = 6;
|
||||
}
|
||||
|
||||
// TreeChange is a change of a tree
|
||||
message TreeChange {
|
||||
// TreeHeadIds are previous ids for this TreeChange
|
||||
repeated string treeHeadIds = 1;
|
||||
// AclHeadId is a cid of latest acl record at the time of this change
|
||||
string aclHeadId = 2;
|
||||
// SnapshotBaseId is a snapshot (root) of the tree where this change is added
|
||||
string snapshotBaseId = 3;
|
||||
// ChangesData is an arbitrary payload to be read by the client
|
||||
bytes changesData = 4;
|
||||
// CurrentReadKeyHash is the hash of the read key which is used to encrypt this change
|
||||
uint64 currentReadKeyHash = 5;
|
||||
// Timestamp is this change creation timestamp
|
||||
int64 timestamp = 6;
|
||||
// Identity is a public key with which the raw payload of this change is signed
|
||||
bytes identity = 7;
|
||||
// IsSnapshot indicates whether this change contains a snapshot of state
|
||||
bool isSnapshot = 8;
|
||||
}
|
||||
|
||||
// RawTreeChange is a marshalled TreeChange (or RootChange) payload and a signature of this payload
|
||||
message RawTreeChange {
|
||||
// Payload is a byte payload containing TreeChange
|
||||
bytes payload = 1;
|
||||
// Signature is a signature made by identity indicated in the TreeChange payload
|
||||
bytes signature = 2;
|
||||
}
|
||||
|
||||
// RawTreeChangeWithId is a marshalled RawTreeChange with CID
|
||||
message RawTreeChangeWithId {
|
||||
// RawChange is a byte payload of RawTreeChange
|
||||
bytes rawChange = 1;
|
||||
// Id is a cid made from rawChange payload
|
||||
string id = 2;
|
||||
}
|
||||
1537
pkg/acl/treechangeproto/treechange.pb.go
Normal file
1537
pkg/acl/treechangeproto/treechange.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,14 +2,16 @@ package document
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
testchanges "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/proto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/tree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/node"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/message"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto"
|
||||
@ -25,13 +27,14 @@ type service struct {
|
||||
messageService message.Service
|
||||
treeCache treecache.Service
|
||||
account account.Service
|
||||
storage storage.Service
|
||||
// to create new documents we need to know all nodes
|
||||
nodes []*node.Node
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
UpdateDocument(ctx context.Context, id, text string) error
|
||||
CreateDocument(ctx context.Context, text string) (string, error)
|
||||
UpdateDocumentTree(ctx context.Context, id, text string) error
|
||||
CreateDocumentTree(ctx context.Context, aclTreeId string, text string) (id string, err error)
|
||||
}
|
||||
|
||||
func New() app.Component {
|
||||
@ -42,6 +45,7 @@ func (s *service) Init(a *app.App) (err error) {
|
||||
s.account = a.MustComponent(account.CName).(account.Service)
|
||||
s.messageService = a.MustComponent(message.CName).(message.Service)
|
||||
s.treeCache = a.MustComponent(treecache.CName).(treecache.Service)
|
||||
s.storage = a.MustComponent(storage.CName).(storage.Service)
|
||||
|
||||
nodesService := a.MustComponent(node.CName).(node.Service)
|
||||
s.nodes = nodesService.Nodes()
|
||||
@ -54,41 +58,65 @@ func (s *service) Name() (name string) {
|
||||
}
|
||||
|
||||
func (s *service) Run(ctx context.Context) (err error) {
|
||||
return nil
|
||||
syncData := s.storage.ImportedACLSyncData()
|
||||
|
||||
// we could have added a timeout or some additional logic,
|
||||
// but let's just use the ACL id of the latest started node :-)
|
||||
return s.messageService.SendToSpaceAsync("", syncproto.WrapACLList(
|
||||
&syncproto.SyncACLList{Records: syncData.Records},
|
||||
syncData.Header,
|
||||
syncData.Id,
|
||||
))
|
||||
}
|
||||
|
||||
func (s *service) Close(ctx context.Context) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) UpdateDocument(ctx context.Context, id, text string) (err error) {
|
||||
func (s *service) UpdateDocumentTree(ctx context.Context, id, text string) (err error) {
|
||||
var (
|
||||
ch *aclpb.RawChange
|
||||
header *treepb.TreeHeader
|
||||
header *aclpb.Header
|
||||
snapshotPath []string
|
||||
heads []string
|
||||
)
|
||||
log.With(zap.String("id", id), zap.String("text", text)).
|
||||
Debug("updating document")
|
||||
|
||||
err = s.treeCache.Do(ctx, id, func(tree acltree.ACLTree) error {
|
||||
ch, err = tree.AddContent(ctx, func(builder acltree.ChangeBuilder) error {
|
||||
builder.AddChangeContent(
|
||||
&testchangepb.PlainTextChange_Data{
|
||||
Content: []*testchangepb.PlainTextChange_Content{
|
||||
createAppendTextChangeContent(text),
|
||||
},
|
||||
})
|
||||
err = s.treeCache.Do(ctx, id, func(obj interface{}) error {
|
||||
docTree, ok := obj.(tree.ObjectTree)
|
||||
if !ok {
|
||||
return fmt.Errorf("can't update acl trees with text")
|
||||
}
|
||||
|
||||
docTree.Lock()
|
||||
defer docTree.Unlock()
|
||||
err = s.treeCache.Do(ctx, docTree.Header().AclListId, func(obj interface{}) error {
|
||||
aclTree := obj.(list.ACLList)
|
||||
aclTree.RLock()
|
||||
defer aclTree.RUnlock()
|
||||
|
||||
content := createAppendTextChange(text)
|
||||
signable := tree.SignableChangeContent{
|
||||
Proto: content,
|
||||
Key: s.account.Account().SignKey,
|
||||
Identity: s.account.Account().Identity,
|
||||
IsSnapshot: false,
|
||||
}
|
||||
ch, err = docTree.AddContent(ctx, signable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id = tree.ID()
|
||||
heads = tree.Heads()
|
||||
header = tree.Header()
|
||||
snapshotPath = tree.SnapshotPath()
|
||||
id = docTree.ID()
|
||||
heads = docTree.Heads()
|
||||
header = docTree.Header()
|
||||
snapshotPath = docTree.SnapshotPath()
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@ -100,87 +128,90 @@ func (s *service) UpdateDocument(ctx context.Context, id, text string) (err erro
|
||||
zap.String("header", header.String())).
|
||||
Debug("document updated in the database")
|
||||
|
||||
return s.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(&syncproto.Sync_HeadUpdate{
|
||||
return s.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(&syncproto.SyncHeadUpdate{
|
||||
Heads: heads,
|
||||
Changes: []*aclpb.RawChange{ch},
|
||||
TreeId: id,
|
||||
SnapshotPath: snapshotPath,
|
||||
TreeHeader: header,
|
||||
}))
|
||||
}, header, id))
|
||||
}
|
||||
|
||||
func (s *service) CreateDocument(ctx context.Context, text string) (id string, err error) {
|
||||
func (s *service) CreateDocumentTree(ctx context.Context, aclListId string, text string) (id string, err error) {
|
||||
acc := s.account.Account()
|
||||
var (
|
||||
ch *aclpb.RawChange
|
||||
header *treepb.TreeHeader
|
||||
header *aclpb.Header
|
||||
snapshotPath []string
|
||||
heads []string
|
||||
)
|
||||
err = s.treeCache.Do(ctx, aclListId, func(obj interface{}) error {
|
||||
t := obj.(list.ACLList)
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
err = s.treeCache.Create(ctx, func(builder acltree.ChangeBuilder) error {
|
||||
err := builder.UserAdd(acc.Identity, acc.EncKey.GetPublic(), aclpb.ACLChange_Admin)
|
||||
content := createInitialTextChange(text)
|
||||
doc, err := tree.CreateNewTreeStorage(acc, t, content, s.storage.CreateTreeStorage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// adding all predefined nodes to the document as admins
|
||||
for _, n := range s.nodes {
|
||||
err = builder.UserAdd(n.SigningKeyString, n.EncryptionKey, aclpb.ACLChange_Admin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
builder.AddChangeContent(createInitialChangeContent(text))
|
||||
return nil
|
||||
}, func(tree acltree.ACLTree) error {
|
||||
id = tree.ID()
|
||||
heads = tree.Heads()
|
||||
header = tree.Header()
|
||||
snapshotPath = tree.SnapshotPath()
|
||||
ch, err = tree.Storage().GetChange(ctx, heads[0])
|
||||
id, err = doc.ID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.With(
|
||||
zap.String("id", id),
|
||||
zap.Strings("heads", heads),
|
||||
zap.String("header", header.String())).
|
||||
Debug("document created in the database")
|
||||
|
||||
header, err = doc.Header()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
heads = []string{header.FirstId}
|
||||
snapshotPath = []string{header.FirstId}
|
||||
ch, err = doc.GetRawChange(ctx, header.FirstId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.With(zap.String("id", id), zap.String("text", text)).
|
||||
Debug("creating document")
|
||||
|
||||
err = s.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(&syncproto.Sync_HeadUpdate{
|
||||
err = s.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(&syncproto.SyncHeadUpdate{
|
||||
Heads: heads,
|
||||
Changes: []*aclpb.RawChange{ch},
|
||||
TreeId: id,
|
||||
SnapshotPath: snapshotPath,
|
||||
TreeHeader: header,
|
||||
}))
|
||||
}, header, id))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
|
||||
func createInitialChangeContent(text string) proto.Marshaler {
|
||||
return &testchangepb.PlainTextChange_Data{
|
||||
Content: []*testchangepb.PlainTextChange_Content{
|
||||
func createInitialTextChange(text string) proto.Marshaler {
|
||||
return &testchanges.PlainTextChangeData{
|
||||
Content: []*testchanges.PlainTextChangeContent{
|
||||
createAppendTextChangeContent(text),
|
||||
},
|
||||
Snapshot: &testchangepb.PlainTextChange_Snapshot{Text: text},
|
||||
Snapshot: &testchanges.PlainTextChangeSnapshot{Text: text},
|
||||
}
|
||||
}
|
||||
|
||||
func createAppendTextChangeContent(text string) *testchangepb.PlainTextChange_Content {
|
||||
return &testchangepb.PlainTextChange_Content{
|
||||
Value: &testchangepb.PlainTextChange_Content_TextAppend{
|
||||
TextAppend: &testchangepb.PlainTextChange_TextAppend{
|
||||
func createAppendTextChange(text string) proto.Marshaler {
|
||||
return &testchanges.PlainTextChangeData{
|
||||
Content: []*testchanges.PlainTextChangeContent{
|
||||
createAppendTextChangeContent(text),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createAppendTextChangeContent(text string) *testchanges.PlainTextChangeContent {
|
||||
return &testchanges.PlainTextChangeContent{
|
||||
Value: &testchanges.PlainTextChangeContentValueOfTextAppend{
|
||||
TextAppend: &testchanges.PlainTextChangeTextAppend{
|
||||
Text: text,
|
||||
},
|
||||
},
|
||||
|
||||
@ -2,16 +2,10 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/etc"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/acllistbuilder"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/node"
|
||||
)
|
||||
|
||||
var CName = "storage"
|
||||
@ -38,10 +32,10 @@ type service struct {
|
||||
importedACLSyncData ImportedACLSyncData
|
||||
}
|
||||
|
||||
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||
func (s *service) Init(a *app.App) (err error) {
|
||||
s.storageProvider = storage.NewInMemoryTreeStorageProvider()
|
||||
// importing hardcoded acl list, check that the keys there are correct
|
||||
return s.importACLList(a)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) Storage(treeId string) (storage.Storage, error) {
|
||||
@ -52,12 +46,12 @@ func (s *service) AddStorage(id string, st storage.Storage) error {
|
||||
return s.storageProvider.AddStorage(id, st)
|
||||
}
|
||||
|
||||
func (s *service) CreateTreeStorage(treeId string, header *aclpb.Header, changes []*aclpb.RawChange) (storage.TreeStorage, error) {
|
||||
return s.storageProvider.CreateTreeStorage(treeId, header, changes)
|
||||
func (s *service) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (storage.TreeStorage, error) {
|
||||
return s.storageProvider.CreateTreeStorage(payload)
|
||||
}
|
||||
|
||||
func (s *service) CreateACLListStorage(id string, header *aclpb.Header, records []*aclpb.RawRecord) (storage.ListStorage, error) {
|
||||
return s.storageProvider.CreateACLListStorage(id, header, records)
|
||||
func (s *service) CreateACLListStorage(payload storage.ACLListStorageCreatePayload) (storage.ListStorage, error) {
|
||||
return s.storageProvider.CreateACLListStorage(payload)
|
||||
}
|
||||
|
||||
func (s *service) Name() (name string) {
|
||||
@ -75,62 +69,3 @@ func (s *service) Run(ctx context.Context) (err error) {
|
||||
func (s service) Close(ctx context.Context) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) importACLList(a *app.App) (err error) {
|
||||
path := fmt.Sprintf("%s/%s", etc.Path(), "acl.yml")
|
||||
st, err := acllistbuilder.NewACLListStorageBuilderFromFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id, err := st.ID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
header, err := st.Header()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// checking that acl list contains all the needed permissions for all our nodes
|
||||
err = s.checkActualNodesPermissions(st, a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.importedACLSyncData = ImportedACLSyncData{
|
||||
Id: id,
|
||||
Header: header,
|
||||
Records: st.GetRawRecords(),
|
||||
}
|
||||
|
||||
log.Infof("imported ACLList with id %s", id)
|
||||
return s.storageProvider.AddStorage(id, st)
|
||||
}
|
||||
|
||||
func (s *service) checkActualNodesPermissions(st *acllistbuilder.ACLListStorageBuilder, a *app.App) error {
|
||||
nodes := a.MustComponent(node.CName).(node.Service)
|
||||
acc := a.MustComponent(account.CName).(account.Service)
|
||||
|
||||
aclList, err := list.BuildACLListWithIdentity(acc.Account(), st)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
state := aclList.ACLState()
|
||||
|
||||
// checking own state
|
||||
if state.GetUserStates()[acc.Account().Identity].Permissions != aclpb.ACLChange_Admin {
|
||||
return fmt.Errorf("own node with signing key %s should be admin", acc.Account().Identity)
|
||||
}
|
||||
|
||||
// checking other nodes' states
|
||||
for _, n := range nodes.Nodes() {
|
||||
if state.GetUserStates()[n.SigningKeyString].Permissions != aclpb.ACLChange_Admin {
|
||||
return fmt.Errorf("other node with signing key %s should be admin", n.SigningKeyString)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -2,33 +2,32 @@ package treecache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
aclstorage "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/tree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ocache"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/storage"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const CName = "treecache"
|
||||
|
||||
// TODO: add context
|
||||
type ACLTreeFunc = func(tree acltree.ACLTree) error
|
||||
type ChangeBuildFunc = func(builder acltree.ChangeBuilder) error
|
||||
type ObjFunc = func(obj interface{}) error
|
||||
|
||||
var log = logger.NewNamed("treecache")
|
||||
|
||||
type Service interface {
|
||||
Do(ctx context.Context, treeId string, f ACLTreeFunc) error
|
||||
Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f ACLTreeFunc) error
|
||||
Create(ctx context.Context, build ChangeBuildFunc, f ACLTreeFunc) error
|
||||
Do(ctx context.Context, id string, f ObjFunc) error
|
||||
Add(ctx context.Context, id string, payload any) error
|
||||
}
|
||||
|
||||
type service struct {
|
||||
treeProvider treestorage.Provider
|
||||
storage storage.Service
|
||||
account account.Service
|
||||
cache ocache.OCache
|
||||
}
|
||||
@ -37,53 +36,48 @@ func New() app.ComponentRunnable {
|
||||
return &service{}
|
||||
}
|
||||
|
||||
func (s *service) Create(ctx context.Context, build ChangeBuildFunc, f ACLTreeFunc) error {
|
||||
acc := s.account.Account()
|
||||
st, err := acltree.CreateNewTreeStorageWithACL(acc, build, s.treeProvider.CreateTreeStorage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id, err := st.TreeID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.Do(ctx, id, f)
|
||||
}
|
||||
|
||||
func (s *service) Do(ctx context.Context, treeId string, f ACLTreeFunc) error {
|
||||
func (s *service) Do(ctx context.Context, treeId string, f ObjFunc) error {
|
||||
log.
|
||||
With(zap.String("treeId", treeId)).
|
||||
Debug("requesting tree from cache to perform operation")
|
||||
|
||||
tree, err := s.cache.Get(ctx, treeId)
|
||||
t, err := s.cache.Get(ctx, treeId)
|
||||
defer s.cache.Release(treeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aclTree := tree.(acltree.ACLTree)
|
||||
aclTree.Lock()
|
||||
defer aclTree.Unlock()
|
||||
return f(tree.(acltree.ACLTree))
|
||||
return f(t)
|
||||
}
|
||||
|
||||
func (s *service) Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f ACLTreeFunc) error {
|
||||
func (s *service) Add(ctx context.Context, treeId string, payload any) error {
|
||||
switch pl := payload.(type) {
|
||||
case aclstorage.TreeStorageCreatePayload:
|
||||
log.
|
||||
With(zap.String("treeId", treeId), zap.Int("len(changes)", len(changes))).
|
||||
Debug("adding tree with changes")
|
||||
With(zap.String("treeId", treeId), zap.Int("len(changes)", len(pl.Changes))).
|
||||
Debug("adding Tree with changes")
|
||||
|
||||
_, err := s.treeProvider.CreateTreeStorage(treeId, header, changes)
|
||||
_, err := s.storage.CreateTreeStorage(payload.(aclstorage.TreeStorageCreatePayload))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.Do(ctx, treeId, f)
|
||||
case aclstorage.ACLListStorageCreatePayload:
|
||||
log.
|
||||
With(zap.String("treeId", treeId), zap.Int("len(changes)", len(pl.Records))).
|
||||
Debug("adding ACLList with records")
|
||||
|
||||
_, err := s.storage.CreateACLListStorage(payload.(aclstorage.ACLListStorageCreatePayload))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) Init(a *app.App) (err error) {
|
||||
s.cache = ocache.New(s.loadTree)
|
||||
s.account = a.MustComponent(account.CName).(account.Service)
|
||||
s.treeProvider = treestorage.NewInMemoryTreeStorageProvider()
|
||||
s.storage = a.MustComponent(storage.CName).(storage.Service)
|
||||
// TODO: for test we should load some predefined keys
|
||||
return nil
|
||||
}
|
||||
@ -101,11 +95,33 @@ func (s *service) Close(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
func (s *service) loadTree(ctx context.Context, id string) (ocache.Object, error) {
|
||||
tree, err := s.treeProvider.TreeStorage(id)
|
||||
t, err := s.storage.Storage(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: should probably accept nil listeners
|
||||
aclTree, err := acltree.BuildACLTree(tree, s.account.Account(), acltree.NoOpListener{})
|
||||
return aclTree, err
|
||||
header, err := t.Header()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch header.DocType { // handler
|
||||
case aclpb.Header_ACL:
|
||||
return list.BuildACLListWithIdentity(s.account.Account(), t.(aclstorage.ListStorage))
|
||||
case aclpb.Header_DocTree:
|
||||
break
|
||||
default:
|
||||
return nil, fmt.Errorf("incorrect type")
|
||||
}
|
||||
log.Info("got header", zap.String("header", header.String()))
|
||||
var objTree tree.ObjectTree
|
||||
err = s.Do(ctx, header.AclListId, func(obj interface{}) error {
|
||||
aclList := obj.(list.ACLList)
|
||||
objTree, err = tree.BuildObjectTree(t.(aclstorage.TreeStorage), nil, aclList)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return objTree, err
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ syntax = "proto3";
|
||||
package anytype;
|
||||
option go_package = "/syncproto";
|
||||
|
||||
import "pkg/acl/aclchanges/aclpb/protos/aclchanges.proto";
|
||||
import "pkg/acl/aclrecordproto/aclpb/protos/aclrecordproto.proto";
|
||||
|
||||
message Message {
|
||||
Header header = 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user