WIP proto refactoring

This commit is contained in:
mcrakhman 2022-09-12 21:06:20 +02:00
parent 018406d25c
commit 9976a84d42
No known key found for this signature in database
GPG Key ID: DED12CFEF5B8396B
33 changed files with 4328 additions and 4937 deletions

View File

@ -30,7 +30,7 @@ proto:
$(GOGO_START) protoc --gogofaster_out=:. $(P_TEST_CHANGES_PATH_PB)/proto/*.proto $(GOGO_START) protoc --gogofaster_out=:. $(P_TEST_CHANGES_PATH_PB)/proto/*.proto
$(eval PKGMAP := $$(P_ACL_CHANGES)) $(eval PKGMAP := $$(P_ACL_CHANGES))
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. $(P_SYNC_CHANGES_PATH_PB)/proto/*.proto $(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. $(P_SYNC_CHANGES_PATH_PB)/proto/*.proto
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. service/space/spacesync/protos/*.proto $(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. common/commonspace/spacesyncproto/protos/*.proto
build: build:
@$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/app)) @$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/app))

View File

@ -1,16 +1,17 @@
syntax = "proto3"; syntax = "proto3";
package anySpace; package anySpace;
option go_package = "common/commonspace/spacesyncproto"; option go_package = "common/commonspace/spacesyncproto";
import "pkg/acl/aclchanges/aclpb/protos/aclchanges.proto";
enum ErrCodes { enum ErrCodes {
Unexpected = 0; Unexpected = 0;
} }
service Space { service Space {
// HeadSync compares all objects and their hashes in a space // HeadSync compares all objects and their hashes in a space
rpc HeadSync(HeadSyncRequest) returns (HeadSyncResponse); rpc HeadSync(HeadSyncRequest) returns (HeadSyncResponse);
rpc Stream( stream Msg) returns (stream Msg); rpc Stream(stream ObjectSyncMessage) returns (stream ObjectSyncMessage);
} }
// TODO: temporary mock message // TODO: temporary mock message
@ -18,8 +19,6 @@ message Msg {
string spaceId = 1; string spaceId = 1;
} }
// HeadSyncRange presenting a request for one range // HeadSyncRange presenting a request for one range
message HeadSyncRange { message HeadSyncRange {
uint64 from = 1; uint64 from = 1;
@ -50,3 +49,40 @@ message HeadSyncRequest {
message HeadSyncResponse { message HeadSyncResponse {
repeated HeadSyncResult results = 1; repeated HeadSyncResult results = 1;
} }
// ObjectSyncMessage is a message sent on object sync
message ObjectSyncMessage {
string spaceId = 1;
ObjectSyncContentValue content = 2;
acl.TreeHeader treeHeader = 3;
string treeId = 4;
}
// ObjectSyncContentValue provides different types for object sync
message ObjectSyncContentValue {
oneof value {
ObjectHeadUpdate headUpdate = 1;
ObjectFullSyncRequest fullSyncRequest = 2;
ObjectFullSyncResponse fullSyncResponse = 3;
}
}
// ObjectHeadUpdate is a message sent on document head update
message ObjectHeadUpdate {
repeated string heads = 1;
repeated acl.RawTreeChangeWithId changes = 2;
repeated string snapshotPath = 3;
}
// ObjectHeadUpdate is a message sent when document needs full sync
message ObjectFullSyncRequest {
repeated string heads = 1;
repeated string snapshotPath = 2;
}
// 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 string snapshotPath = 3;
}

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ import (
) )
type AccountData struct { // TODO: create a convenient constructor for this type AccountData struct { // TODO: create a convenient constructor for this
Identity string // TODO: this is essentially the same as sign key Identity []byte // TODO: this is essentially the same as sign key
SignKey signingkey.PrivKey SignKey signingkey.PrivKey
EncKey encryptionkey.PrivKey EncKey encryptionkey.PrivKey
Decoder keys.Decoder Decoder keys.Decoder

File diff suppressed because it is too large Load Diff

View File

@ -2,147 +2,142 @@ syntax = "proto3";
package acl; package acl;
option go_package = "aclpb"; option go_package = "aclpb";
message RawChange { // ACL protos
message RawACLRecord {
bytes payload = 1; bytes payload = 1;
bytes signature = 2; bytes signature = 2;
string id = 3; string id = 3; // this field is only used on user side for convenience, it should be empty when saving to db
} }
message RawRecord { message ACLContentValue {
bytes payload = 1;
bytes signature = 2;
string id = 3;
}
// the element of change tree used to store and internal apply smartBlock history
message ACLChange {
repeated string treeHeadIds = 1;
repeated string aclHeadIds = 2;
string snapshotBaseId = 3; // we will only have one base snapshot for both
ACLData aclData = 4;
// the data is encoded with read key and should be read in ChangesData format
bytes changesData = 5;
uint64 currentReadKeyHash = 6;
int64 timestamp = 7;
string identity = 8;
message ACLContentValue {
oneof value { oneof value {
UserAdd userAdd = 1; ACLUserAdd userAdd = 1;
UserRemove userRemove = 2; ACLUserRemove userRemove = 2;
UserPermissionChange userPermissionChange = 3; ACLUserPermissionChange userPermissionChange = 3;
UserInvite userInvite = 4; ACLUserInvite userInvite = 4;
UserJoin userJoin = 5; ACLUserJoin userJoin = 5;
UserConfirm userConfirm = 6; ACLUserConfirm userConfirm = 6;
}
} }
}
message ACLData { message ACLData {
ACLSnapshot aclSnapshot = 1; repeated ACLContentValue aclContent = 1;
repeated ACLContentValue aclContent = 2; }
}
message ACLSnapshot { message ACLState {
// We don't need ACLState as a separate message now, because we simplified the snapshot model
ACLState aclState = 1;
}
message ACLState {
repeated uint64 readKeyHashes = 1; repeated uint64 readKeyHashes = 1;
repeated UserState userStates = 2; repeated ACLUserState userStates = 2;
map<string, UserInvite> invites = 3; // TODO: later map<string, ACLUserInvite> invites = 3; // TODO: later
// repeated string unconfirmedUsers = 4; // TODO: later // repeated string unconfirmedUsers = 4; // TODO: later
} }
message UserState { message ACLUserState {
string identity = 1; bytes identity = 1;
bytes encryptionKey = 2; bytes encryptionKey = 2;
repeated bytes encryptedReadKeys = 3; // all read keys that we know repeated bytes encryptedReadKeys = 3; // all read keys that we know
UserPermissions permissions = 4; ACLUserPermissions permissions = 4;
bool IsConfirmed = 5; bool isConfirmed = 5;
} }
// we already know identity and encryptionKey // we already know identity and encryptionKey
message UserAdd { message ACLUserAdd {
string identity = 1; // public signing key bytes identity = 1; // public signing key
bytes encryptionKey = 2; // public encryption key bytes encryptionKey = 2; // public encryption key
repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user
UserPermissions permissions = 4; ACLUserPermissions permissions = 4;
} }
// TODO: this is not used as of now // TODO: this is not used as of now
message UserConfirm { // not needed for read permissions message ACLUserConfirm { // not needed for read permissions
string identity = 1; // not needed bytes identity = 1; // not needed
string userAddId = 2; string userAddId = 2;
} }
message UserInvite { message ACLUserInvite {
bytes acceptPublicKey = 1; bytes acceptPublicKey = 1;
bytes encryptPublicKey = 2; bytes encryptPublicKey = 2;
repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user
UserPermissions permissions = 4; ACLUserPermissions permissions = 4;
string InviteId = 5; string inviteId = 5;
} }
message UserJoin { message ACLUserJoin {
string identity = 1; bytes identity = 1;
bytes encryptionKey = 2; bytes encryptionKey = 2;
bytes acceptSignature = 3; // sign acceptPublicKey bytes acceptSignature = 3; // sign acceptPublicKey
string userInviteId = 4; string userInviteId = 4;
repeated bytes encryptedReadKeys = 5; // the idea is that user should itself reencrypt the keys with the pub key repeated bytes encryptedReadKeys = 5; // the idea is that user should itself reencrypt the keys with the pub key
} }
message UserRemove { message ACLUserRemove {
string identity = 1; bytes identity = 1;
repeated ReadKeyReplace readKeyReplaces = 3; // new read key encrypted for all users repeated ACLReadKeyReplace readKeyReplaces = 3; // new read key encrypted for all users
} }
message ReadKeyReplace { message ACLReadKeyReplace {
string identity = 1; bytes identity = 1;
bytes encryptionKey = 2; bytes encryptionKey = 2;
bytes encryptedReadKey = 3; bytes encryptedReadKey = 3;
} }
message UserPermissionChange { message ACLUserPermissionChange {
string identity = 1; bytes identity = 1;
UserPermissions permissions = 2; ACLUserPermissions permissions = 2;
} }
enum UserPermissions { enum ACLUserPermissions {
Admin = 0; Admin = 0;
Writer = 1; Writer = 1;
Reader = 2; Reader = 2;
Removed = 3; Removed = 3;
}
} }
message Change { message ACLRecord {
repeated string treeHeadIds = 1;
string aclHeadId = 2;
string snapshotBaseId = 3; // we will only have one base snapshot for both
bytes changesData = 4;
uint64 currentReadKeyHash = 5;
int64 timestamp = 6;
string identity = 7;
bool isSnapshot = 8;
}
message Record {
string prevId = 1; string prevId = 1;
string identity = 2; bytes identity = 2;
bytes data = 3; bytes data = 3;
uint64 currentReadKeyHash = 4; uint64 currentReadKeyHash = 4;
int64 timestamp = 5; int64 timestamp = 5;
} }
message Header { message ACLHeader {
string firstId = 1; string firstId = 1;
string aclListId = 2; bytes identity = 2; // the identity of the creator
string workspaceId = 3; }
DocType docType = 4;
// Tree protos
enum DocType {
ACL = 0; message RawTreeChange {
DocTree = 1; 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
} }

View File

@ -1,6 +1,7 @@
package list package list
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
@ -29,14 +30,14 @@ var ErrInvalidSignature = errors.New("signature is invalid")
type UserPermissionPair struct { type UserPermissionPair struct {
Identity string Identity string
Permission aclpb.ACLChangeUserPermissions Permission aclpb.ACLUserPermissions
} }
type ACLState struct { type ACLState struct {
currentReadKeyHash uint64 currentReadKeyHash uint64
userReadKeys map[uint64]*symmetric.Key userReadKeys map[uint64]*symmetric.Key
userStates map[string]*aclpb.ACLChangeUserState userStates map[string]*aclpb.ACLUserState
userInvites map[string]*aclpb.ACLChangeUserInvite userInvites map[string]*aclpb.ACLUserInvite
signingPubKeyDecoder keys.Decoder signingPubKeyDecoder keys.Decoder
encryptionKey encryptionkey.PrivKey encryptionKey encryptionkey.PrivKey
@ -55,8 +56,8 @@ func newACLStateWithIdentity(
identity: identity, identity: identity,
encryptionKey: encryptionKey, encryptionKey: encryptionKey,
userReadKeys: make(map[uint64]*symmetric.Key), userReadKeys: make(map[uint64]*symmetric.Key),
userStates: make(map[string]*aclpb.ACLChangeUserState), userStates: make(map[string]*aclpb.ACLUserState),
userInvites: make(map[string]*aclpb.ACLChangeUserInvite), userInvites: make(map[string]*aclpb.ACLUserInvite),
signingPubKeyDecoder: decoder, signingPubKeyDecoder: decoder,
permissionsAtRecord: make(map[string][]UserPermissionPair), permissionsAtRecord: make(map[string][]UserPermissionPair),
keychain: common.NewKeychain(), keychain: common.NewKeychain(),
@ -67,8 +68,8 @@ func newACLState(decoder keys.Decoder) *ACLState {
return &ACLState{ return &ACLState{
signingPubKeyDecoder: decoder, signingPubKeyDecoder: decoder,
userReadKeys: make(map[uint64]*symmetric.Key), userReadKeys: make(map[uint64]*symmetric.Key),
userStates: make(map[string]*aclpb.ACLChangeUserState), userStates: make(map[string]*aclpb.ACLUserState),
userInvites: make(map[string]*aclpb.ACLChangeUserInvite), userInvites: make(map[string]*aclpb.ACLUserInvite),
permissionsAtRecord: make(map[string][]UserPermissionPair), permissionsAtRecord: make(map[string][]UserPermissionPair),
keychain: common.NewKeychain(), keychain: common.NewKeychain(),
} }
@ -105,8 +106,8 @@ func (st *ACLState) PermissionsAtRecord(id string, identity string) (UserPermiss
return UserPermissionPair{}, ErrNoSuchUser return UserPermissionPair{}, ErrNoSuchUser
} }
func (st *ACLState) applyRecord(record *aclpb.Record) (err error) { func (st *ACLState) applyRecord(record *aclpb.ACLRecord) (err error) {
aclData := &aclpb.ACLChangeACLData{} aclData := &aclpb.ACLData{}
err = proto.Unmarshal(record.Data, aclData) err = proto.Unmarshal(record.Data, aclData)
if err != nil { if err != nil {
@ -122,14 +123,14 @@ func (st *ACLState) applyRecord(record *aclpb.Record) (err error) {
return return
} }
func (st *ACLState) applyChangeAndUpdate(recordWrapper *Record) (err error) { func (st *ACLState) applyChangeAndUpdate(recordWrapper *ACLRecord) (err error) {
var ( var (
change = recordWrapper.Content change = recordWrapper.Content
aclData = &aclpb.ACLChangeACLData{} aclData = &aclpb.ACLData{}
) )
if recordWrapper.Model != nil { if recordWrapper.Model != nil {
aclData = recordWrapper.Model.(*aclpb.ACLChangeACLData) aclData = recordWrapper.Model.(*aclpb.ACLData)
} else { } else {
err = proto.Unmarshal(change.Data, aclData) err = proto.Unmarshal(change.Data, aclData)
if err != nil { if err != nil {
@ -147,7 +148,7 @@ func (st *ACLState) applyChangeAndUpdate(recordWrapper *Record) (err error) {
var permissions []UserPermissionPair var permissions []UserPermissionPair
for _, state := range st.userStates { for _, state := range st.userStates {
permission := UserPermissionPair{ permission := UserPermissionPair{
Identity: state.Identity, Identity: string(state.Identity),
Permission: state.Permissions, Permission: state.Permissions,
} }
permissions = append(permissions, permission) permissions = append(permissions, permission)
@ -157,7 +158,7 @@ func (st *ACLState) applyChangeAndUpdate(recordWrapper *Record) (err error) {
return nil return nil
} }
func (st *ACLState) applyChangeData(changeData *aclpb.ACLChangeACLData, hash uint64, identity string) (err error) { func (st *ACLState) applyChangeData(changeData *aclpb.ACLData, hash uint64, identity []byte) (err error) {
defer func() { defer func() {
if err != nil { if err != nil {
return return
@ -170,12 +171,12 @@ func (st *ACLState) applyChangeData(changeData *aclpb.ACLChangeACLData, hash uin
skipIdentityCheck := st.isUserJoin(changeData) || (st.currentReadKeyHash == 0 && st.isUserAdd(changeData, identity)) skipIdentityCheck := st.isUserJoin(changeData) || (st.currentReadKeyHash == 0 && st.isUserAdd(changeData, identity))
if !skipIdentityCheck { if !skipIdentityCheck {
// we check signature when we add this to the Tree, so no need to do it here // we check signature when we add this to the Tree, so no need to do it here
if _, exists := st.userStates[identity]; !exists { if _, exists := st.userStates[string(identity)]; !exists {
err = ErrNoSuchUser err = ErrNoSuchUser
return return
} }
if !st.hasPermission(identity, aclpb.ACLChange_Admin) { if !st.hasPermission(identity, aclpb.ACLUserPermissions_Admin) {
err = fmt.Errorf("user %s must have admin permissions", identity) err = fmt.Errorf("user %s must have admin permissions", identity)
return return
} }
@ -191,7 +192,7 @@ func (st *ACLState) applyChangeData(changeData *aclpb.ACLChangeACLData, hash uin
return nil return nil
} }
func (st *ACLState) applyChangeContent(ch *aclpb.ACLChangeACLContentValue) error { func (st *ACLState) applyChangeContent(ch *aclpb.ACLContentValue) error {
switch { switch {
case ch.GetUserPermissionChange() != nil: case ch.GetUserPermissionChange() != nil:
return st.applyUserPermissionChange(ch.GetUserPermissionChange()) return st.applyUserPermissionChange(ch.GetUserPermissionChange())
@ -210,27 +211,29 @@ func (st *ACLState) applyChangeContent(ch *aclpb.ACLChangeACLContentValue) error
} }
} }
func (st *ACLState) applyUserPermissionChange(ch *aclpb.ACLChangeUserPermissionChange) error { func (st *ACLState) applyUserPermissionChange(ch *aclpb.ACLUserPermissionChange) error {
if _, exists := st.userStates[ch.Identity]; !exists { chIdentity := string(ch.Identity)
if _, exists := st.userStates[chIdentity]; !exists {
return ErrNoSuchUser return ErrNoSuchUser
} }
st.userStates[ch.Identity].Permissions = ch.Permissions st.userStates[chIdentity].Permissions = ch.Permissions
return nil return nil
} }
func (st *ACLState) applyUserInvite(ch *aclpb.ACLChangeUserInvite) error { func (st *ACLState) applyUserInvite(ch *aclpb.ACLUserInvite) error {
st.userInvites[ch.InviteId] = ch st.userInvites[ch.InviteId] = ch
return nil return nil
} }
func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error { func (st *ACLState) applyUserJoin(ch *aclpb.ACLUserJoin) error {
invite, exists := st.userInvites[ch.UserInviteId] invite, exists := st.userInvites[ch.UserInviteId]
if !exists { if !exists {
return fmt.Errorf("no such invite with id %s", ch.UserInviteId) return fmt.Errorf("no such invite with id %s", ch.UserInviteId)
} }
chIdentity := string(ch.Identity)
if _, exists = st.userStates[ch.Identity]; exists { if _, exists = st.userStates[chIdentity]; exists {
return ErrUserAlreadyExists return ErrUserAlreadyExists
} }
@ -241,12 +244,7 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error {
return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err) return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err)
} }
rawSignedId, err := st.signingPubKeyDecoder.DecodeFromStringIntoBytes(ch.Identity) res, err := verificationKey.(signingkey.PubKey).Verify(ch.Identity, signature)
if err != nil {
return fmt.Errorf("failed to decode signing identity as bytes")
}
res, err := verificationKey.(signingkey.PubKey).Verify(rawSignedId, signature)
if err != nil { if err != nil {
return fmt.Errorf("verification returned error: %w", err) return fmt.Errorf("verification returned error: %w", err)
} }
@ -255,7 +253,7 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error {
} }
// if ourselves -> we need to decrypt the read keys // if ourselves -> we need to decrypt the read keys
if st.identity == ch.Identity { if st.identity == chIdentity {
for _, key := range ch.EncryptedReadKeys { for _, key := range ch.EncryptedReadKeys {
key, hash, err := st.decryptReadKeyAndHash(key) key, hash, err := st.decryptReadKeyAndHash(key)
if err != nil { if err != nil {
@ -267,30 +265,31 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error {
} }
// adding user to the list // adding user to the list
userState := &aclpb.ACLChangeUserState{ userState := &aclpb.ACLUserState{
Identity: ch.Identity, Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey, EncryptionKey: ch.EncryptionKey,
EncryptedReadKeys: ch.EncryptedReadKeys, EncryptedReadKeys: ch.EncryptedReadKeys,
Permissions: invite.Permissions, Permissions: invite.Permissions,
IsConfirmed: true, IsConfirmed: true,
} }
st.userStates[ch.Identity] = userState st.userStates[chIdentity] = userState
return nil return nil
} }
func (st *ACLState) applyUserAdd(ch *aclpb.ACLChangeUserAdd) error { func (st *ACLState) applyUserAdd(ch *aclpb.ACLUserAdd) error {
if _, exists := st.userStates[ch.Identity]; exists { chIdentity := string(ch.Identity)
if _, exists := st.userStates[chIdentity]; exists {
return ErrUserAlreadyExists return ErrUserAlreadyExists
} }
st.userStates[ch.Identity] = &aclpb.ACLChangeUserState{ st.userStates[chIdentity] = &aclpb.ACLUserState{
Identity: ch.Identity, Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey, EncryptionKey: ch.EncryptionKey,
Permissions: ch.Permissions, Permissions: ch.Permissions,
EncryptedReadKeys: ch.EncryptedReadKeys, EncryptedReadKeys: ch.EncryptedReadKeys,
} }
if ch.Identity == st.identity { if chIdentity == st.identity {
for _, key := range ch.EncryptedReadKeys { for _, key := range ch.EncryptedReadKeys {
key, hash, err := st.decryptReadKeyAndHash(key) key, hash, err := st.decryptReadKeyAndHash(key)
if err != nil { if err != nil {
@ -304,26 +303,28 @@ func (st *ACLState) applyUserAdd(ch *aclpb.ACLChangeUserAdd) error {
return nil return nil
} }
func (st *ACLState) applyUserRemove(ch *aclpb.ACLChangeUserRemove) error { func (st *ACLState) applyUserRemove(ch *aclpb.ACLUserRemove) error {
if ch.Identity == st.identity { chIdentity := string(ch.Identity)
if chIdentity == st.identity {
return ErrDocumentForbidden return ErrDocumentForbidden
} }
if _, exists := st.userStates[ch.Identity]; !exists { if _, exists := st.userStates[chIdentity]; !exists {
return ErrNoSuchUser return ErrNoSuchUser
} }
delete(st.userStates, ch.Identity) delete(st.userStates, chIdentity)
for _, replace := range ch.ReadKeyReplaces { for _, replace := range ch.ReadKeyReplaces {
userState, exists := st.userStates[replace.Identity] repIdentity := string(replace.Identity)
userState, exists := st.userStates[repIdentity]
if !exists { if !exists {
continue continue
} }
userState.EncryptedReadKeys = append(userState.EncryptedReadKeys, replace.EncryptedReadKey) userState.EncryptedReadKeys = append(userState.EncryptedReadKeys, replace.EncryptedReadKey)
// if this is our identity then we have to decrypt the key // if this is our identity then we have to decrypt the key
if replace.Identity == st.identity { if repIdentity == st.identity {
key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey) key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey)
if err != nil { if err != nil {
return ErrFailedToDecrypt return ErrFailedToDecrypt
@ -336,12 +337,13 @@ func (st *ACLState) applyUserRemove(ch *aclpb.ACLChangeUserRemove) error {
return nil return nil
} }
func (st *ACLState) applyUserConfirm(ch *aclpb.ACLChangeUserConfirm) error { func (st *ACLState) applyUserConfirm(ch *aclpb.ACLUserConfirm) error {
if _, exists := st.userStates[ch.Identity]; !exists { chIdentity := string(ch.Identity)
if _, exists := st.userStates[chIdentity]; !exists {
return ErrNoSuchUser return ErrNoSuchUser
} }
userState := st.userStates[ch.Identity] userState := st.userStates[chIdentity]
userState.IsConfirmed = true userState.IsConfirmed = true
return nil return nil
} }
@ -362,8 +364,8 @@ func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, e
return key, hasher.Sum64(), nil return key, hasher.Sum64(), nil
} }
func (st *ACLState) hasPermission(identity string, permission aclpb.ACLChangeUserPermissions) bool { func (st *ACLState) hasPermission(identity []byte, permission aclpb.ACLUserPermissions) bool {
state, exists := st.userStates[identity] state, exists := st.userStates[string(identity)]
if !exists { if !exists {
return false return false
} }
@ -371,17 +373,17 @@ func (st *ACLState) hasPermission(identity string, permission aclpb.ACLChangeUse
return state.Permissions == permission return state.Permissions == permission
} }
func (st *ACLState) isUserJoin(data *aclpb.ACLChangeACLData) bool { func (st *ACLState) isUserJoin(data *aclpb.ACLData) bool {
// if we have a UserJoin, then it should always be the first one applied // if we have a UserJoin, then it should always be the first one applied
return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil
} }
func (st *ACLState) isUserAdd(data *aclpb.ACLChangeACLData, identity string) bool { func (st *ACLState) isUserAdd(data *aclpb.ACLData, identity []byte) bool {
// if we have a UserAdd, then it should always be the first one applied // if we have a UserAdd, then it should always be the first one applied
userAdd := data.GetAclContent()[0].GetUserAdd() userAdd := data.GetAclContent()[0].GetUserAdd()
return data.GetAclContent() != nil && userAdd != nil && userAdd.GetIdentity() == identity return data.GetAclContent() != nil && userAdd != nil && bytes.Compare(userAdd.GetIdentity(), identity) == 0
} }
func (st *ACLState) GetUserStates() map[string]*aclpb.ACLChangeUserState { func (st *ACLState) GetUserStates() map[string]*aclpb.ACLUserState {
return st.userStates return st.userStates
} }

View File

@ -15,7 +15,7 @@ type aclStateBuilder struct {
func newACLStateBuilderWithIdentity(decoder keys.Decoder, accountData *account.AccountData) *aclStateBuilder { func newACLStateBuilderWithIdentity(decoder keys.Decoder, accountData *account.AccountData) *aclStateBuilder {
return &aclStateBuilder{ return &aclStateBuilder{
decoder: decoder, decoder: decoder,
identity: accountData.Identity, identity: string(accountData.Identity),
key: accountData.EncKey, key: accountData.EncKey,
} }
} }
@ -26,7 +26,7 @@ func newACLStateBuilder(decoder keys.Decoder) *aclStateBuilder {
} }
} }
func (sb *aclStateBuilder) Build(records []*Record) (*ACLState, error) { func (sb *aclStateBuilder) Build(records []*ACLRecord) (*ACLState, error) {
var ( var (
err error err error
state *ACLState state *ACLState

View File

@ -14,7 +14,7 @@ import (
type MarshalledChange = []byte type MarshalledChange = []byte
type ACLChangeBuilder interface { type ACLChangeBuilder interface {
UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLChangeUserPermissions) error UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLUserPermissions) error
AddId(id string) // TODO: this is only for testing AddId(id string) // TODO: this is only for testing
} }
@ -23,7 +23,7 @@ type aclChangeBuilder struct {
list ACLList list ACLList
acc *account.AccountData acc *account.AccountData
aclData *aclpb.ACLChangeACLData aclData *aclpb.ACLData
id string id string
readKey *symmetric.Key readKey *symmetric.Key
readKeyHash uint64 readKeyHash uint64
@ -38,7 +38,7 @@ func (c *aclChangeBuilder) Init(state *ACLState, list ACLList, acc *account.Acco
c.list = list c.list = list
c.acc = acc c.acc = acc
c.aclData = &aclpb.ACLChangeACLData{} c.aclData = &aclpb.ACLData{}
// setting read key for further encryption etc // setting read key for further encryption etc
if state.currentReadKeyHash == 0 { if state.currentReadKeyHash == 0 {
c.readKey, _ = symmetric.NewRandom() c.readKey, _ = symmetric.NewRandom()
@ -56,7 +56,7 @@ func (c *aclChangeBuilder) AddId(id string) {
c.id = id c.id = id
} }
func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLChangeUserPermissions) error { func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLUserPermissions) error {
var allKeys []*symmetric.Key var allKeys []*symmetric.Key
if c.aclState.currentReadKeyHash != 0 { if c.aclState.currentReadKeyHash != 0 {
for _, key := range c.aclState.userReadKeys { for _, key := range c.aclState.userReadKeys {
@ -79,10 +79,10 @@ func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.
if err != nil { if err != nil {
return err return err
} }
ch := &aclpb.ACLChangeACLContentValue{ ch := &aclpb.ACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{ Value: &aclpb.ACLContentValue_UserAdd{
UserAdd: &aclpb.ACLChangeUserAdd{ UserAdd: &aclpb.ACLUserAdd{
Identity: identity, Identity: []byte(identity),
EncryptionKey: rawKey, EncryptionKey: rawKey,
EncryptedReadKeys: encryptedKeys, EncryptedReadKeys: encryptedKeys,
Permissions: permissions, Permissions: permissions,
@ -93,8 +93,8 @@ func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.
return nil return nil
} }
func (c *aclChangeBuilder) BuildAndApply() (*Record, []byte, error) { func (c *aclChangeBuilder) BuildAndApply() (*ACLRecord, []byte, error) {
aclRecord := &aclpb.Record{ aclRecord := &aclpb.ACLRecord{
PrevId: c.list.Head().Id, PrevId: c.list.Head().Id,
CurrentReadKeyHash: c.readKeyHash, CurrentReadKeyHash: c.readKeyHash,
Timestamp: int64(time.Now().Nanosecond()), Timestamp: int64(time.Now().Nanosecond()),

View File

@ -13,7 +13,7 @@ import (
"sync" "sync"
) )
type IterFunc = func(record *Record) (IsContinue bool) type IterFunc = func(record *ACLRecord) (IsContinue bool)
var ErrIncorrectCID = errors.New("incorrect CID") var ErrIncorrectCID = errors.New("incorrect CID")
@ -26,20 +26,20 @@ type RWLocker interface {
type ACLList interface { type ACLList interface {
RWLocker RWLocker
ID() string ID() string
Header() *aclpb.Header Header() *aclpb.ACLHeader
Records() []*Record Records() []*ACLRecord
ACLState() *ACLState ACLState() *ACLState
IsAfter(first string, second string) (bool, error) IsAfter(first string, second string) (bool, error)
Head() *Record Head() *ACLRecord
Get(id string) (*Record, error) Get(id string) (*ACLRecord, error)
Iterate(iterFunc IterFunc) Iterate(iterFunc IterFunc)
IterateFrom(startId string, iterFunc IterFunc) IterateFrom(startId string, iterFunc IterFunc)
Close() (err error) Close() (err error)
} }
type aclList struct { type aclList struct {
header *aclpb.Header header *aclpb.ACLHeader
records []*Record records []*ACLRecord
indexes map[string]int indexes map[string]int
id string id string
@ -84,7 +84,7 @@ func buildWithACLStateBuilder(builder *aclStateBuilder, storage storage.ListStor
if err != nil { if err != nil {
return return
} }
records := []*Record{record} records := []*ACLRecord{record}
for record.Content.PrevId != "" { for record.Content.PrevId != "" {
rawRecord, err = storage.GetRawRecord(context.Background(), record.Content.PrevId) rawRecord, err = storage.GetRawRecord(context.Background(), record.Content.PrevId)
@ -131,7 +131,7 @@ func buildWithACLStateBuilder(builder *aclStateBuilder, storage storage.ListStor
return return
} }
func (a *aclList) Records() []*Record { func (a *aclList) Records() []*ACLRecord {
return a.records return a.records
} }
@ -139,7 +139,7 @@ func (a *aclList) ID() string {
return a.id return a.id
} }
func (a *aclList) Header() *aclpb.Header { func (a *aclList) Header() *aclpb.ACLHeader {
return a.header return a.header
} }
@ -156,11 +156,11 @@ func (a *aclList) IsAfter(first string, second string) (bool, error) {
return firstRec >= secondRec, nil return firstRec >= secondRec, nil
} }
func (a *aclList) Head() *Record { func (a *aclList) Head() *ACLRecord {
return a.records[len(a.records)-1] return a.records[len(a.records)-1]
} }
func (a *aclList) Get(id string) (*Record, error) { func (a *aclList) Get(id string) (*ACLRecord, error) {
recIdx, ok := a.indexes[id] recIdx, ok := a.indexes[id]
if !ok { if !ok {
return nil, fmt.Errorf("no such record") return nil, fmt.Errorf("no such record")
@ -192,8 +192,8 @@ func (a *aclList) Close() (err error) {
return nil return nil
} }
func verifyRecord(keychain *common.Keychain, rawRecord *aclpb.RawRecord, record *Record) (err error) { func verifyRecord(keychain *common.Keychain, rawRecord *aclpb.RawACLRecord, record *ACLRecord) (err error) {
identityKey, err := keychain.GetOrAdd(record.Content.Identity) identityKey, err := keychain.GetOrAdd(record.Identity)
if err != nil { if err != nil {
return return
} }

View File

@ -28,8 +28,8 @@ func TestAclList_ACLState_UserInviteAndJoin(t *testing.T) {
assert.Equal(t, aclpb.ACLChange_Reader, aclList.ACLState().GetUserStates()[idC].Permissions) assert.Equal(t, aclpb.ACLChange_Reader, aclList.ACLState().GetUserStates()[idC].Permissions)
assert.Equal(t, aclList.Head().Content.CurrentReadKeyHash, aclList.ACLState().CurrentReadKeyHash()) assert.Equal(t, aclList.Head().Content.CurrentReadKeyHash, aclList.ACLState().CurrentReadKeyHash())
var records []*Record var records []*ACLRecord
aclList.Iterate(func(record *Record) (IsContinue bool) { aclList.Iterate(func(record *ACLRecord) (IsContinue bool) {
records = append(records, record) records = append(records, record)
return true return true
}) })
@ -69,8 +69,8 @@ func TestAclList_ACLState_UserJoinAndRemove(t *testing.T) {
_, exists := aclList.ACLState().GetUserStates()[idB] _, exists := aclList.ACLState().GetUserStates()[idB]
assert.Equal(t, false, exists) assert.Equal(t, false, exists)
var records []*Record var records []*ACLRecord
aclList.Iterate(func(record *Record) (IsContinue bool) { aclList.Iterate(func(record *ACLRecord) (IsContinue bool) {
records = append(records, record) records = append(records, record)
return true return true
}) })

View File

@ -5,30 +5,33 @@ import (
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
) )
type Record struct { type ACLRecord struct {
Id string Id string
Content *aclpb.Record Content *aclpb.ACLRecord
Identity string
Model interface{} Model interface{}
Sign []byte Sign []byte
} }
func NewRecord(id string, aclRecord *aclpb.Record) *Record { func NewRecord(id string, aclRecord *aclpb.ACLRecord) *ACLRecord {
return &Record{ return &ACLRecord{
Id: id, Id: id,
Content: aclRecord, Content: aclRecord,
Identity: string(aclRecord.Identity),
} }
} }
func NewFromRawRecord(rawRec *aclpb.RawRecord) (*Record, error) { func NewFromRawRecord(rawRec *aclpb.RawACLRecord) (*ACLRecord, error) {
aclRec := &aclpb.Record{} aclRec := &aclpb.ACLRecord{}
err := proto.Unmarshal(rawRec.Payload, aclRec) err := proto.Unmarshal(rawRec.Payload, aclRec)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Record{ return &ACLRecord{
Id: rawRec.Id, Id: rawRec.Id,
Content: aclRec, Content: aclRec,
Sign: rawRec.Signature, Sign: rawRec.Signature,
Identity: string(aclRec.Identity),
}, nil }, nil
} }

View File

@ -8,8 +8,8 @@ import (
) )
type inMemoryACLListStorage struct { type inMemoryACLListStorage struct {
header *aclpb.Header header *aclpb.ACLHeader
records []*aclpb.RawRecord records []*aclpb.RawACLRecord
id string id string
@ -18,8 +18,8 @@ type inMemoryACLListStorage struct {
func NewInMemoryACLListStorage( func NewInMemoryACLListStorage(
id string, id string,
header *aclpb.Header, header *aclpb.ACLHeader,
records []*aclpb.RawRecord) (ListStorage, error) { records []*aclpb.RawACLRecord) (ListStorage, error) {
return &inMemoryACLListStorage{ return &inMemoryACLListStorage{
id: id, id: id,
header: header, header: header,
@ -28,19 +28,19 @@ func NewInMemoryACLListStorage(
}, nil }, nil
} }
func (i *inMemoryACLListStorage) Header() (*aclpb.Header, error) { func (i *inMemoryACLListStorage) Header() (*aclpb.ACLHeader, error) {
i.RLock() i.RLock()
defer i.RUnlock() defer i.RUnlock()
return i.header, nil return i.header, nil
} }
func (i *inMemoryACLListStorage) Head() (*aclpb.RawRecord, error) { func (i *inMemoryACLListStorage) Head() (*aclpb.RawACLRecord, error) {
i.RLock() i.RLock()
defer i.RUnlock() defer i.RUnlock()
return i.records[len(i.records)-1], nil return i.records[len(i.records)-1], nil
} }
func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*aclpb.RawRecord, error) { func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*aclpb.RawACLRecord, error) {
i.RLock() i.RLock()
defer i.RUnlock() defer i.RUnlock()
for _, rec := range i.records { for _, rec := range i.records {
@ -51,7 +51,7 @@ func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*
return nil, fmt.Errorf("no such record") return nil, fmt.Errorf("no such record")
} }
func (i *inMemoryACLListStorage) AddRawRecord(ctx context.Context, rec *aclpb.RawRecord) error { func (i *inMemoryACLListStorage) AddRawRecord(ctx context.Context, rec *aclpb.RawACLRecord) error {
panic("implement me") panic("implement me")
} }
@ -63,19 +63,19 @@ func (i *inMemoryACLListStorage) ID() (string, error) {
type inMemoryTreeStorage struct { type inMemoryTreeStorage struct {
id string id string
header *aclpb.Header header *aclpb.TreeHeader
heads []string heads []string
changes map[string]*aclpb.RawChange changes map[string]*aclpb.RawTreeChangeWithId
sync.RWMutex sync.RWMutex
} }
func NewInMemoryTreeStorage( func NewInMemoryTreeStorage(
treeId string, treeId string,
header *aclpb.Header, header *aclpb.TreeHeader,
heads []string, heads []string,
changes []*aclpb.RawChange) (TreeStorage, error) { changes []*aclpb.RawTreeChangeWithId) (TreeStorage, error) {
allChanges := make(map[string]*aclpb.RawChange) allChanges := make(map[string]*aclpb.RawTreeChangeWithId)
for _, ch := range changes { for _, ch := range changes {
allChanges[ch.Id] = ch allChanges[ch.Id] = ch
} }
@ -95,7 +95,7 @@ func (t *inMemoryTreeStorage) ID() (string, error) {
return t.id, nil return t.id, nil
} }
func (t *inMemoryTreeStorage) Header() (*aclpb.Header, error) { func (t *inMemoryTreeStorage) Header() (*aclpb.TreeHeader, error) {
t.RLock() t.RLock()
defer t.RUnlock() defer t.RUnlock()
return t.header, nil return t.header, nil
@ -118,7 +118,7 @@ func (t *inMemoryTreeStorage) SetHeads(heads []string) error {
return nil return nil
} }
func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawChange) error { func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawTreeChangeWithId) error {
t.Lock() t.Lock()
defer t.Unlock() defer t.Unlock()
// TODO: better to do deep copy // TODO: better to do deep copy
@ -126,7 +126,7 @@ func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawChange) error {
return nil return nil
} }
func (t *inMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string) (*aclpb.RawChange, error) { func (t *inMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string) (*aclpb.RawTreeChangeWithId, error) {
t.RLock() t.RLock()
defer t.RUnlock() defer t.RUnlock()
if res, exists := t.changes[changeId]; exists { if res, exists := t.changes[changeId]; exists {

View File

@ -7,8 +7,8 @@ import (
type ListStorage interface { type ListStorage interface {
Storage Storage
Head() (*aclpb.RawRecord, error) Head() (*aclpb.RawACLRecord, error)
GetRawRecord(ctx context.Context, id string) (*aclpb.RawRecord, error) GetRawRecord(ctx context.Context, id string) (*aclpb.RawACLRecord, error)
AddRawRecord(ctx context.Context, rec *aclpb.RawRecord) error AddRawRecord(ctx context.Context, rec *aclpb.RawACLRecord) error
} }

View File

@ -9,15 +9,15 @@ var ErrUnknownTreeId = errors.New("tree does not exist")
type TreeStorageCreatePayload struct { type TreeStorageCreatePayload struct {
TreeId string TreeId string
Header *aclpb.Header Header *aclpb.TreeHeader
Changes []*aclpb.RawChange Changes []*aclpb.RawTreeChangeWithId
Heads []string Heads []string
} }
type ACLListStorageCreatePayload struct { type ACLListStorageCreatePayload struct {
ListId string ListId string
Header *aclpb.Header Header *aclpb.ACLHeader
Records []*aclpb.RawRecord Records []*aclpb.RawACLRecord
} }
type Provider interface { type Provider interface {

View File

@ -10,8 +10,8 @@ type TreeStorage interface {
Heads() ([]string, error) Heads() ([]string, error)
SetHeads(heads []string) error SetHeads(heads []string) error
AddRawChange(change *aclpb.RawChange) error AddRawChange(change *aclpb.RawTreeChangeWithId) error
GetRawChange(ctx context.Context, recordID string) (*aclpb.RawChange, error) GetRawChange(ctx context.Context, recordID string) (*aclpb.RawTreeChangeWithId, error)
} }
type TreeStorageCreatorFunc = func(payload TreeStorageCreatePayload) (TreeStorage, error) type TreeStorageCreatorFunc = func(payload TreeStorageCreatePayload) (TreeStorage, error)

View File

@ -19,8 +19,8 @@ import (
type ACLListStorageBuilder struct { type ACLListStorageBuilder struct {
aclList string aclList string
records []*aclpb.Record records []*aclpb.ACLRecord
rawRecords []*aclpb.RawRecord rawRecords []*aclpb.RawACLRecord
indexes map[string]int indexes map[string]int
keychain *Keychain keychain *Keychain
header *aclpb.Header header *aclpb.Header
@ -29,7 +29,7 @@ type ACLListStorageBuilder struct {
func NewACLListStorageBuilder(keychain *Keychain) *ACLListStorageBuilder { func NewACLListStorageBuilder(keychain *Keychain) *ACLListStorageBuilder {
return &ACLListStorageBuilder{ return &ACLListStorageBuilder{
records: make([]*aclpb.Record, 0), records: make([]*aclpb.ACLRecord, 0),
indexes: make(map[string]int), indexes: make(map[string]int),
keychain: keychain, keychain: keychain,
} }
@ -58,7 +58,7 @@ func NewACLListStorageBuilderFromFile(file string) (*ACLListStorageBuilder, erro
return tb, nil return tb, nil
} }
func (t *ACLListStorageBuilder) createRaw(rec *aclpb.Record) *aclpb.RawRecord { func (t *ACLListStorageBuilder) createRaw(rec *aclpb.ACLRecord) *aclpb.RawACLRecord {
aclMarshaled, err := proto.Marshal(rec) aclMarshaled, err := proto.Marshal(rec)
if err != nil { if err != nil {
panic("should be able to marshal final acl message!") panic("should be able to marshal final acl message!")
@ -71,18 +71,18 @@ func (t *ACLListStorageBuilder) createRaw(rec *aclpb.Record) *aclpb.RawRecord {
id, _ := cid.NewCIDFromBytes(aclMarshaled) id, _ := cid.NewCIDFromBytes(aclMarshaled)
return &aclpb.RawRecord{ return &aclpb.RawACLRecord{
Payload: aclMarshaled, Payload: aclMarshaled,
Signature: signature, Signature: signature,
Id: id, Id: id,
} }
} }
func (t *ACLListStorageBuilder) getRecord(idx int) *aclpb.RawRecord { func (t *ACLListStorageBuilder) getRecord(idx int) *aclpb.RawACLRecord {
return t.rawRecords[idx] return t.rawRecords[idx]
} }
func (t *ACLListStorageBuilder) Head() (*aclpb.RawRecord, error) { func (t *ACLListStorageBuilder) Head() (*aclpb.RawACLRecord, error) {
return t.getRecord(len(t.records) - 1), nil return t.getRecord(len(t.records) - 1), nil
} }
@ -90,7 +90,7 @@ func (t *ACLListStorageBuilder) Header() (*aclpb.Header, error) {
return t.header, nil return t.header, nil
} }
func (t *ACLListStorageBuilder) GetRawRecord(ctx context.Context, id string) (*aclpb.RawRecord, error) { func (t *ACLListStorageBuilder) GetRawRecord(ctx context.Context, id string) (*aclpb.RawACLRecord, error) {
recIdx, ok := t.indexes[id] recIdx, ok := t.indexes[id]
if !ok { if !ok {
return nil, fmt.Errorf("no such record") return nil, fmt.Errorf("no such record")
@ -98,7 +98,7 @@ func (t *ACLListStorageBuilder) GetRawRecord(ctx context.Context, id string) (*a
return t.getRecord(recIdx), nil return t.getRecord(recIdx), nil
} }
func (t *ACLListStorageBuilder) AddRawRecord(ctx context.Context, rec *aclpb.RawRecord) error { func (t *ACLListStorageBuilder) AddRawRecord(ctx context.Context, rec *aclpb.RawACLRecord) error {
panic("implement me") panic("implement me")
} }
@ -106,7 +106,7 @@ func (t *ACLListStorageBuilder) ID() (string, error) {
return t.id, nil return t.id, nil
} }
func (t *ACLListStorageBuilder) GetRawRecords() []*aclpb.RawRecord { func (t *ACLListStorageBuilder) GetRawRecords() []*aclpb.RawACLRecord {
return t.rawRecords return t.rawRecords
} }
@ -132,7 +132,7 @@ func (t *ACLListStorageBuilder) Parse(tree *YMLList) {
t.createHeaderAndId() t.createHeaderAndId()
} }
func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclpb.Record { func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclpb.ACLRecord {
k := t.keychain.GetKey(rec.ReadKey).(*SymKey) k := t.keychain.GetKey(rec.ReadKey).(*SymKey)
var aclChangeContents []*aclpb.ACLChangeACLContentValue var aclChangeContents []*aclpb.ACLChangeACLContentValue
for _, ch := range rec.AclChanges { for _, ch := range rec.AclChanges {
@ -144,7 +144,7 @@ func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclpb.R
} }
bytes, _ := data.Marshal() bytes, _ := data.Marshal()
return &aclpb.Record{ return &aclpb.ACLRecord{
PrevId: prevId, PrevId: prevId,
Identity: t.keychain.GetIdentity(rec.Identity), Identity: t.keychain.GetIdentity(rec.Identity),
Data: bytes, Data: bytes,
@ -163,7 +163,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{ convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{ Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{
UserAdd: &aclpb.ACLChangeUserAdd{ UserAdd: &aclpb.ACLUserPermissionsAdd{
Identity: t.keychain.GetIdentity(add.Identity), Identity: t.keychain.GetIdentity(add.Identity),
EncryptionKey: rawKey, EncryptionKey: rawKey,
EncryptedReadKeys: t.encryptReadKeys(add.EncryptedReadKeys, encKey), EncryptedReadKeys: t.encryptReadKeys(add.EncryptedReadKeys, encKey),
@ -187,7 +187,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{ convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserJoin{ Value: &aclpb.ACLChangeACLContentValueValueOfUserJoin{
UserJoin: &aclpb.ACLChangeUserJoin{ UserJoin: &aclpb.ACLUserPermissionsJoin{
Identity: t.keychain.GetIdentity(join.Identity), Identity: t.keychain.GetIdentity(join.Identity),
EncryptionKey: rawKey, EncryptionKey: rawKey,
AcceptSignature: signature, AcceptSignature: signature,
@ -205,7 +205,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{ convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserInvite{ Value: &aclpb.ACLChangeACLContentValueValueOfUserInvite{
UserInvite: &aclpb.ACLChangeUserInvite{ UserInvite: &aclpb.ACLUserPermissionsInvite{
AcceptPublicKey: rawAcceptKey, AcceptPublicKey: rawAcceptKey,
EncryptPublicKey: rawEncKey, EncryptPublicKey: rawEncKey,
EncryptedReadKeys: t.encryptReadKeys(invite.EncryptedReadKeys, encKey), EncryptedReadKeys: t.encryptReadKeys(invite.EncryptedReadKeys, encKey),
@ -219,7 +219,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{ convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserConfirm{ Value: &aclpb.ACLChangeACLContentValueValueOfUserConfirm{
UserConfirm: &aclpb.ACLChangeUserConfirm{ UserConfirm: &aclpb.ACLUserPermissionsConfirm{
Identity: t.keychain.GetIdentity(confirm.Identity), Identity: t.keychain.GetIdentity(confirm.Identity),
UserAddId: confirm.UserAddId, UserAddId: confirm.UserAddId,
}, },
@ -230,7 +230,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{ convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserPermissionChange{ Value: &aclpb.ACLChangeACLContentValueValueOfUserPermissionChange{
UserPermissionChange: &aclpb.ACLChangeUserPermissionChange{ UserPermissionChange: &aclpb.ACLUserPermissionsPermissionChange{
Identity: t.keychain.GetIdentity(permissionChange.Identity), Identity: t.keychain.GetIdentity(permissionChange.Identity),
Permissions: t.convertPermission(permissionChange.Permission), Permissions: t.convertPermission(permissionChange.Permission),
}, },
@ -259,7 +259,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{ convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserRemove{ Value: &aclpb.ACLChangeACLContentValueValueOfUserRemove{
UserRemove: &aclpb.ACLChangeUserRemove{ UserRemove: &aclpb.ACLUserPermissionsRemove{
Identity: t.keychain.GetIdentity(remove.RemovedIdentity), Identity: t.keychain.GetIdentity(remove.RemovedIdentity),
ReadKeyReplaces: replaces, ReadKeyReplaces: replaces,
}, },
@ -286,7 +286,7 @@ func (t *ACLListStorageBuilder) encryptReadKeys(keys []string, encKey encryption
return return
} }
func (t *ACLListStorageBuilder) convertPermission(perm string) aclpb.ACLChangeUserPermissions { func (t *ACLListStorageBuilder) convertPermission(perm string) aclpb.ACLUserPermissions {
switch perm { switch perm {
case "admin": case "admin":
return aclpb.ACLChange_Admin return aclpb.ACLChange_Admin
@ -299,7 +299,7 @@ func (t *ACLListStorageBuilder) convertPermission(perm string) aclpb.ACLChangeUs
} }
} }
func (t *ACLListStorageBuilder) traverseFromHead(f func(rec *aclpb.Record, id string) error) (err error) { func (t *ACLListStorageBuilder) traverseFromHead(f func(rec *aclpb.ACLRecord, id string) error) (err error) {
for i := len(t.records) - 1; i >= 0; i-- { for i := len(t.records) - 1; i >= 0; i-- {
err = f(t.records[i], t.rawRecords[i].Id) err = f(t.records[i], t.rawRecords[i].Id)
if err != nil { if err != nil {

View File

@ -33,7 +33,7 @@ func (t *ACLListStorageBuilder) Graph() (string, error) {
graph.SetDir(true) graph.SetDir(true)
var nodes = make(map[string]struct{}) var nodes = make(map[string]struct{})
var addNodes = func(r *aclpb.Record, id string) error { var addNodes = func(r *aclpb.ACLRecord, id string) error {
style := "solid" style := "solid"
var chSymbs []string var chSymbs []string
@ -92,7 +92,7 @@ func (t *ACLListStorageBuilder) Graph() (string, error) {
return nil return nil
} }
var addLinks = func(r *aclpb.Record, id string) error { var addLinks = func(r *aclpb.ACLRecord, id string) error {
if r.PrevId == "" { if r.PrevId == "" {
return nil return nil
} }

View File

@ -58,24 +58,24 @@ func (m *PlainTextChange) XXX_DiscardUnknown() {
var xxx_messageInfo_PlainTextChange proto.InternalMessageInfo var xxx_messageInfo_PlainTextChange proto.InternalMessageInfo
type PlainTextChangeContent struct { type PlainTextChange_Content struct {
// Types that are valid to be assigned to Value: // Types that are valid to be assigned to Value:
// *PlainTextChangeContentValueOfTextAppend // *PlainTextChange_Content_TextAppend
Value IsPlainTextChangeContentValue `protobuf_oneof:"value"` Value isPlainTextChange_Content_Value `protobuf_oneof:"value"`
} }
func (m *PlainTextChangeContent) Reset() { *m = PlainTextChangeContent{} } func (m *PlainTextChange_Content) Reset() { *m = PlainTextChange_Content{} }
func (m *PlainTextChangeContent) String() string { return proto.CompactTextString(m) } func (m *PlainTextChange_Content) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeContent) ProtoMessage() {} func (*PlainTextChange_Content) ProtoMessage() {}
func (*PlainTextChangeContent) Descriptor() ([]byte, []int) { func (*PlainTextChange_Content) Descriptor() ([]byte, []int) {
return fileDescriptor_37f33c266ada4318, []int{0, 0} return fileDescriptor_37f33c266ada4318, []int{0, 0}
} }
func (m *PlainTextChangeContent) XXX_Unmarshal(b []byte) error { func (m *PlainTextChange_Content) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
} }
func (m *PlainTextChangeContent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *PlainTextChange_Content) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic { if deterministic {
return xxx_messageInfo_PlainTextChangeContent.Marshal(b, m, deterministic) return xxx_messageInfo_PlainTextChange_Content.Marshal(b, m, deterministic)
} else { } else {
b = b[:cap(b)] b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b) n, err := m.MarshalToSizedBuffer(b)
@ -85,67 +85,67 @@ func (m *PlainTextChangeContent) XXX_Marshal(b []byte, deterministic bool) ([]by
return b[:n], nil return b[:n], nil
} }
} }
func (m *PlainTextChangeContent) XXX_Merge(src proto.Message) { func (m *PlainTextChange_Content) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChangeContent.Merge(m, src) xxx_messageInfo_PlainTextChange_Content.Merge(m, src)
} }
func (m *PlainTextChangeContent) XXX_Size() int { func (m *PlainTextChange_Content) XXX_Size() int {
return m.Size() return m.Size()
} }
func (m *PlainTextChangeContent) XXX_DiscardUnknown() { func (m *PlainTextChange_Content) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChangeContent.DiscardUnknown(m) xxx_messageInfo_PlainTextChange_Content.DiscardUnknown(m)
} }
var xxx_messageInfo_PlainTextChangeContent proto.InternalMessageInfo var xxx_messageInfo_PlainTextChange_Content proto.InternalMessageInfo
type IsPlainTextChangeContentValue interface { type isPlainTextChange_Content_Value interface {
IsPlainTextChangeContentValue() isPlainTextChange_Content_Value()
MarshalTo([]byte) (int, error) MarshalTo([]byte) (int, error)
Size() int Size() int
} }
type PlainTextChangeContentValueOfTextAppend struct { type PlainTextChange_Content_TextAppend struct {
TextAppend *PlainTextChangeTextAppend `protobuf:"bytes,1,opt,name=textAppend,proto3,oneof" json:"textAppend,omitempty"` TextAppend *PlainTextChange_TextAppend `protobuf:"bytes,1,opt,name=textAppend,proto3,oneof" json:"textAppend,omitempty"`
} }
func (*PlainTextChangeContentValueOfTextAppend) IsPlainTextChangeContentValue() {} func (*PlainTextChange_Content_TextAppend) isPlainTextChange_Content_Value() {}
func (m *PlainTextChangeContent) GetValue() IsPlainTextChangeContentValue { func (m *PlainTextChange_Content) GetValue() isPlainTextChange_Content_Value {
if m != nil { if m != nil {
return m.Value return m.Value
} }
return nil return nil
} }
func (m *PlainTextChangeContent) GetTextAppend() *PlainTextChangeTextAppend { func (m *PlainTextChange_Content) GetTextAppend() *PlainTextChange_TextAppend {
if x, ok := m.GetValue().(*PlainTextChangeContentValueOfTextAppend); ok { if x, ok := m.GetValue().(*PlainTextChange_Content_TextAppend); ok {
return x.TextAppend return x.TextAppend
} }
return nil return nil
} }
// XXX_OneofWrappers is for the internal use of the proto package. // XXX_OneofWrappers is for the internal use of the proto package.
func (*PlainTextChangeContent) XXX_OneofWrappers() []interface{} { func (*PlainTextChange_Content) XXX_OneofWrappers() []interface{} {
return []interface{}{ return []interface{}{
(*PlainTextChangeContentValueOfTextAppend)(nil), (*PlainTextChange_Content_TextAppend)(nil),
} }
} }
type PlainTextChangeTextAppend struct { type PlainTextChange_TextAppend struct {
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
} }
func (m *PlainTextChangeTextAppend) Reset() { *m = PlainTextChangeTextAppend{} } func (m *PlainTextChange_TextAppend) Reset() { *m = PlainTextChange_TextAppend{} }
func (m *PlainTextChangeTextAppend) String() string { return proto.CompactTextString(m) } func (m *PlainTextChange_TextAppend) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeTextAppend) ProtoMessage() {} func (*PlainTextChange_TextAppend) ProtoMessage() {}
func (*PlainTextChangeTextAppend) Descriptor() ([]byte, []int) { func (*PlainTextChange_TextAppend) Descriptor() ([]byte, []int) {
return fileDescriptor_37f33c266ada4318, []int{0, 1} return fileDescriptor_37f33c266ada4318, []int{0, 1}
} }
func (m *PlainTextChangeTextAppend) XXX_Unmarshal(b []byte) error { func (m *PlainTextChange_TextAppend) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
} }
func (m *PlainTextChangeTextAppend) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *PlainTextChange_TextAppend) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic { if deterministic {
return xxx_messageInfo_PlainTextChangeTextAppend.Marshal(b, m, deterministic) return xxx_messageInfo_PlainTextChange_TextAppend.Marshal(b, m, deterministic)
} else { } else {
b = b[:cap(b)] b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b) n, err := m.MarshalToSizedBuffer(b)
@ -155,41 +155,41 @@ func (m *PlainTextChangeTextAppend) XXX_Marshal(b []byte, deterministic bool) ([
return b[:n], nil return b[:n], nil
} }
} }
func (m *PlainTextChangeTextAppend) XXX_Merge(src proto.Message) { func (m *PlainTextChange_TextAppend) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChangeTextAppend.Merge(m, src) xxx_messageInfo_PlainTextChange_TextAppend.Merge(m, src)
} }
func (m *PlainTextChangeTextAppend) XXX_Size() int { func (m *PlainTextChange_TextAppend) XXX_Size() int {
return m.Size() return m.Size()
} }
func (m *PlainTextChangeTextAppend) XXX_DiscardUnknown() { func (m *PlainTextChange_TextAppend) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChangeTextAppend.DiscardUnknown(m) xxx_messageInfo_PlainTextChange_TextAppend.DiscardUnknown(m)
} }
var xxx_messageInfo_PlainTextChangeTextAppend proto.InternalMessageInfo var xxx_messageInfo_PlainTextChange_TextAppend proto.InternalMessageInfo
func (m *PlainTextChangeTextAppend) GetText() string { func (m *PlainTextChange_TextAppend) GetText() string {
if m != nil { if m != nil {
return m.Text return m.Text
} }
return "" return ""
} }
type PlainTextChangeSnapshot struct { type PlainTextChange_Snapshot struct {
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
} }
func (m *PlainTextChangeSnapshot) Reset() { *m = PlainTextChangeSnapshot{} } func (m *PlainTextChange_Snapshot) Reset() { *m = PlainTextChange_Snapshot{} }
func (m *PlainTextChangeSnapshot) String() string { return proto.CompactTextString(m) } func (m *PlainTextChange_Snapshot) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeSnapshot) ProtoMessage() {} func (*PlainTextChange_Snapshot) ProtoMessage() {}
func (*PlainTextChangeSnapshot) Descriptor() ([]byte, []int) { func (*PlainTextChange_Snapshot) Descriptor() ([]byte, []int) {
return fileDescriptor_37f33c266ada4318, []int{0, 2} return fileDescriptor_37f33c266ada4318, []int{0, 2}
} }
func (m *PlainTextChangeSnapshot) XXX_Unmarshal(b []byte) error { func (m *PlainTextChange_Snapshot) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
} }
func (m *PlainTextChangeSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *PlainTextChange_Snapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic { if deterministic {
return xxx_messageInfo_PlainTextChangeSnapshot.Marshal(b, m, deterministic) return xxx_messageInfo_PlainTextChange_Snapshot.Marshal(b, m, deterministic)
} else { } else {
b = b[:cap(b)] b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b) n, err := m.MarshalToSizedBuffer(b)
@ -199,42 +199,42 @@ func (m *PlainTextChangeSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]b
return b[:n], nil return b[:n], nil
} }
} }
func (m *PlainTextChangeSnapshot) XXX_Merge(src proto.Message) { func (m *PlainTextChange_Snapshot) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChangeSnapshot.Merge(m, src) xxx_messageInfo_PlainTextChange_Snapshot.Merge(m, src)
} }
func (m *PlainTextChangeSnapshot) XXX_Size() int { func (m *PlainTextChange_Snapshot) XXX_Size() int {
return m.Size() return m.Size()
} }
func (m *PlainTextChangeSnapshot) XXX_DiscardUnknown() { func (m *PlainTextChange_Snapshot) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChangeSnapshot.DiscardUnknown(m) xxx_messageInfo_PlainTextChange_Snapshot.DiscardUnknown(m)
} }
var xxx_messageInfo_PlainTextChangeSnapshot proto.InternalMessageInfo var xxx_messageInfo_PlainTextChange_Snapshot proto.InternalMessageInfo
func (m *PlainTextChangeSnapshot) GetText() string { func (m *PlainTextChange_Snapshot) GetText() string {
if m != nil { if m != nil {
return m.Text return m.Text
} }
return "" return ""
} }
type PlainTextChangeData struct { type PlainTextChange_Data struct {
Content []*PlainTextChangeContent `protobuf:"bytes,1,rep,name=content,proto3" json:"content,omitempty"` Content []*PlainTextChange_Content `protobuf:"bytes,1,rep,name=content,proto3" json:"content,omitempty"`
Snapshot *PlainTextChangeSnapshot `protobuf:"bytes,2,opt,name=snapshot,proto3" json:"snapshot,omitempty"` Snapshot *PlainTextChange_Snapshot `protobuf:"bytes,2,opt,name=snapshot,proto3" json:"snapshot,omitempty"`
} }
func (m *PlainTextChangeData) Reset() { *m = PlainTextChangeData{} } func (m *PlainTextChange_Data) Reset() { *m = PlainTextChange_Data{} }
func (m *PlainTextChangeData) String() string { return proto.CompactTextString(m) } func (m *PlainTextChange_Data) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeData) ProtoMessage() {} func (*PlainTextChange_Data) ProtoMessage() {}
func (*PlainTextChangeData) Descriptor() ([]byte, []int) { func (*PlainTextChange_Data) Descriptor() ([]byte, []int) {
return fileDescriptor_37f33c266ada4318, []int{0, 3} return fileDescriptor_37f33c266ada4318, []int{0, 3}
} }
func (m *PlainTextChangeData) XXX_Unmarshal(b []byte) error { func (m *PlainTextChange_Data) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
} }
func (m *PlainTextChangeData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *PlainTextChange_Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic { if deterministic {
return xxx_messageInfo_PlainTextChangeData.Marshal(b, m, deterministic) return xxx_messageInfo_PlainTextChange_Data.Marshal(b, m, deterministic)
} else { } else {
b = b[:cap(b)] b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b) n, err := m.MarshalToSizedBuffer(b)
@ -244,26 +244,26 @@ func (m *PlainTextChangeData) XXX_Marshal(b []byte, deterministic bool) ([]byte,
return b[:n], nil return b[:n], nil
} }
} }
func (m *PlainTextChangeData) XXX_Merge(src proto.Message) { func (m *PlainTextChange_Data) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChangeData.Merge(m, src) xxx_messageInfo_PlainTextChange_Data.Merge(m, src)
} }
func (m *PlainTextChangeData) XXX_Size() int { func (m *PlainTextChange_Data) XXX_Size() int {
return m.Size() return m.Size()
} }
func (m *PlainTextChangeData) XXX_DiscardUnknown() { func (m *PlainTextChange_Data) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChangeData.DiscardUnknown(m) xxx_messageInfo_PlainTextChange_Data.DiscardUnknown(m)
} }
var xxx_messageInfo_PlainTextChangeData proto.InternalMessageInfo var xxx_messageInfo_PlainTextChange_Data proto.InternalMessageInfo
func (m *PlainTextChangeData) GetContent() []*PlainTextChangeContent { func (m *PlainTextChange_Data) GetContent() []*PlainTextChange_Content {
if m != nil { if m != nil {
return m.Content return m.Content
} }
return nil return nil
} }
func (m *PlainTextChangeData) GetSnapshot() *PlainTextChangeSnapshot { func (m *PlainTextChange_Data) GetSnapshot() *PlainTextChange_Snapshot {
if m != nil { if m != nil {
return m.Snapshot return m.Snapshot
} }
@ -272,10 +272,10 @@ func (m *PlainTextChangeData) GetSnapshot() *PlainTextChangeSnapshot {
func init() { func init() {
proto.RegisterType((*PlainTextChange)(nil), "anytype.PlainTextChange") proto.RegisterType((*PlainTextChange)(nil), "anytype.PlainTextChange")
proto.RegisterType((*PlainTextChangeContent)(nil), "anytype.PlainTextChange.Content") proto.RegisterType((*PlainTextChange_Content)(nil), "anytype.PlainTextChange.Content")
proto.RegisterType((*PlainTextChangeTextAppend)(nil), "anytype.PlainTextChange.TextAppend") proto.RegisterType((*PlainTextChange_TextAppend)(nil), "anytype.PlainTextChange.TextAppend")
proto.RegisterType((*PlainTextChangeSnapshot)(nil), "anytype.PlainTextChange.Snapshot") proto.RegisterType((*PlainTextChange_Snapshot)(nil), "anytype.PlainTextChange.Snapshot")
proto.RegisterType((*PlainTextChangeData)(nil), "anytype.PlainTextChange.Data") proto.RegisterType((*PlainTextChange_Data)(nil), "anytype.PlainTextChange.Data")
} }
func init() { func init() {
@ -326,7 +326,7 @@ func (m *PlainTextChange) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *PlainTextChangeContent) Marshal() (dAtA []byte, err error) { func (m *PlainTextChange_Content) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size]) n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -336,12 +336,12 @@ func (m *PlainTextChangeContent) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil return dAtA[:n], nil
} }
func (m *PlainTextChangeContent) MarshalTo(dAtA []byte) (int, error) { func (m *PlainTextChange_Content) MarshalTo(dAtA []byte) (int, error) {
size := m.Size() size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size]) return m.MarshalToSizedBuffer(dAtA[:size])
} }
func (m *PlainTextChangeContent) MarshalToSizedBuffer(dAtA []byte) (int, error) { func (m *PlainTextChange_Content) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA) i := len(dAtA)
_ = i _ = i
var l int var l int
@ -358,12 +358,12 @@ func (m *PlainTextChangeContent) MarshalToSizedBuffer(dAtA []byte) (int, error)
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *PlainTextChangeContentValueOfTextAppend) MarshalTo(dAtA []byte) (int, error) { func (m *PlainTextChange_Content_TextAppend) MarshalTo(dAtA []byte) (int, error) {
size := m.Size() size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size]) return m.MarshalToSizedBuffer(dAtA[:size])
} }
func (m *PlainTextChangeContentValueOfTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) { func (m *PlainTextChange_Content_TextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA) i := len(dAtA)
if m.TextAppend != nil { if m.TextAppend != nil {
{ {
@ -379,7 +379,7 @@ func (m *PlainTextChangeContentValueOfTextAppend) MarshalToSizedBuffer(dAtA []by
} }
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *PlainTextChangeTextAppend) Marshal() (dAtA []byte, err error) { func (m *PlainTextChange_TextAppend) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size]) n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -389,12 +389,12 @@ func (m *PlainTextChangeTextAppend) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil return dAtA[:n], nil
} }
func (m *PlainTextChangeTextAppend) MarshalTo(dAtA []byte) (int, error) { func (m *PlainTextChange_TextAppend) MarshalTo(dAtA []byte) (int, error) {
size := m.Size() size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size]) return m.MarshalToSizedBuffer(dAtA[:size])
} }
func (m *PlainTextChangeTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) { func (m *PlainTextChange_TextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA) i := len(dAtA)
_ = i _ = i
var l int var l int
@ -409,7 +409,7 @@ func (m *PlainTextChangeTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, erro
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *PlainTextChangeSnapshot) Marshal() (dAtA []byte, err error) { func (m *PlainTextChange_Snapshot) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size]) n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -419,12 +419,12 @@ func (m *PlainTextChangeSnapshot) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil return dAtA[:n], nil
} }
func (m *PlainTextChangeSnapshot) MarshalTo(dAtA []byte) (int, error) { func (m *PlainTextChange_Snapshot) MarshalTo(dAtA []byte) (int, error) {
size := m.Size() size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size]) return m.MarshalToSizedBuffer(dAtA[:size])
} }
func (m *PlainTextChangeSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) { func (m *PlainTextChange_Snapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA) i := len(dAtA)
_ = i _ = i
var l int var l int
@ -439,7 +439,7 @@ func (m *PlainTextChangeSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error)
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *PlainTextChangeData) Marshal() (dAtA []byte, err error) { func (m *PlainTextChange_Data) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size]) n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -449,12 +449,12 @@ func (m *PlainTextChangeData) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil return dAtA[:n], nil
} }
func (m *PlainTextChangeData) MarshalTo(dAtA []byte) (int, error) { func (m *PlainTextChange_Data) MarshalTo(dAtA []byte) (int, error) {
size := m.Size() size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size]) return m.MarshalToSizedBuffer(dAtA[:size])
} }
func (m *PlainTextChangeData) MarshalToSizedBuffer(dAtA []byte) (int, error) { func (m *PlainTextChange_Data) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA) i := len(dAtA)
_ = i _ = i
var l int var l int
@ -508,7 +508,7 @@ func (m *PlainTextChange) Size() (n int) {
return n return n
} }
func (m *PlainTextChangeContent) Size() (n int) { func (m *PlainTextChange_Content) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
} }
@ -520,7 +520,7 @@ func (m *PlainTextChangeContent) Size() (n int) {
return n return n
} }
func (m *PlainTextChangeContentValueOfTextAppend) Size() (n int) { func (m *PlainTextChange_Content_TextAppend) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
} }
@ -532,7 +532,7 @@ func (m *PlainTextChangeContentValueOfTextAppend) Size() (n int) {
} }
return n return n
} }
func (m *PlainTextChangeTextAppend) Size() (n int) { func (m *PlainTextChange_TextAppend) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
} }
@ -545,7 +545,7 @@ func (m *PlainTextChangeTextAppend) Size() (n int) {
return n return n
} }
func (m *PlainTextChangeSnapshot) Size() (n int) { func (m *PlainTextChange_Snapshot) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
} }
@ -558,7 +558,7 @@ func (m *PlainTextChangeSnapshot) Size() (n int) {
return n return n
} }
func (m *PlainTextChangeData) Size() (n int) { func (m *PlainTextChange_Data) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
} }
@ -633,7 +633,7 @@ func (m *PlainTextChange) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error { func (m *PlainTextChange_Content) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
@ -691,11 +691,11 @@ func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
v := &PlainTextChangeTextAppend{} v := &PlainTextChange_TextAppend{}
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
m.Value = &PlainTextChangeContentValueOfTextAppend{v} m.Value = &PlainTextChange_Content_TextAppend{v}
iNdEx = postIndex iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
@ -718,7 +718,7 @@ func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error { func (m *PlainTextChange_TextAppend) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
@ -800,7 +800,7 @@ func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error { func (m *PlainTextChange_Snapshot) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
@ -882,7 +882,7 @@ func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error { func (m *PlainTextChange_Data) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
@ -940,7 +940,7 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Content = append(m.Content, &PlainTextChangeContent{}) m.Content = append(m.Content, &PlainTextChange_Content{})
if err := m.Content[len(m.Content)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Content[len(m.Content)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
@ -975,7 +975,7 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if m.Snapshot == nil { if m.Snapshot == nil {
m.Snapshot = &PlainTextChangeSnapshot{} m.Snapshot = &PlainTextChange_Snapshot{}
} }
if err := m.Snapshot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Snapshot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err

View File

@ -16,7 +16,7 @@ var (
type ChangeContent struct { type ChangeContent struct {
ChangesData proto.Marshaler ChangesData proto.Marshaler
ACLData *aclpb.ACLChangeACLData ACLData *aclpb.ACLData
Id string // TODO: this is just for testing, because id should be created automatically from content Id string // TODO: this is just for testing, because id should be created automatically from content
} }
@ -34,7 +34,8 @@ type Change struct {
visited bool visited bool
branchesFinished bool branchesFinished bool
Content *aclpb.Change Content *aclpb.TreeChange
Identity string
Sign []byte Sign []byte
} }
@ -56,7 +57,7 @@ func (ch *Change) DecryptContents(key *symmetric.Key) error {
return nil return nil
} }
func NewChange(id string, ch *aclpb.Change, signature []byte) *Change { func NewChange(id string, ch *aclpb.TreeChange, signature []byte) *Change {
return &Change{ return &Change{
Next: nil, Next: nil,
PreviousIds: ch.TreeHeadIds, PreviousIds: ch.TreeHeadIds,
@ -64,6 +65,7 @@ func NewChange(id string, ch *aclpb.Change, signature []byte) *Change {
Content: ch, Content: ch,
SnapshotId: ch.SnapshotBaseId, SnapshotId: ch.SnapshotBaseId,
IsSnapshot: ch.IsSnapshot, IsSnapshot: ch.IsSnapshot,
Identity: string(ch.Identity),
Sign: signature, Sign: signature,
} }
} }

View File

@ -1,6 +1,7 @@
package tree package tree
import ( import (
"errors"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" "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/common"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
@ -10,25 +11,24 @@ import (
"time" "time"
) )
const componentBuilder = "tree.changebuilder" var ErrEmptyChange = errors.New("change payload should not be empty")
type BuilderContent struct { type BuilderContent struct {
treeHeadIds []string treeHeadIds []string
aclHeadId string aclHeadId string
snapshotBaseId string snapshotBaseId string
currentReadKeyHash uint64 currentReadKeyHash uint64
identity string identity []byte
isSnapshot bool isSnapshot bool
signingKey signingkey.PrivKey signingKey signingkey.PrivKey
readKey *symmetric.Key readKey *symmetric.Key
content proto.Marshaler content []byte
} }
type ChangeBuilder interface { type ChangeBuilder interface {
ConvertFromRaw(rawChange *aclpb.RawChange) (ch *Change, err error) ConvertFromRaw(rawIdChange *aclpb.RawTreeChangeWithId, verify bool) (ch *Change, err error)
ConvertFromRawAndVerify(rawChange *aclpb.RawChange) (ch *Change, err error) BuildContent(payload BuilderContent) (ch *Change, raw *aclpb.RawTreeChangeWithId, err error)
BuildContent(payload BuilderContent) (ch *Change, raw *aclpb.RawChange, err error) BuildRaw(ch *Change) (*aclpb.RawTreeChangeWithId, error)
BuildRaw(ch *Change) (*aclpb.RawChange, error)
} }
type changeBuilder struct { type changeBuilder struct {
@ -39,31 +39,34 @@ func newChangeBuilder(keys *common.Keychain) ChangeBuilder {
return &changeBuilder{keys: keys} return &changeBuilder{keys: keys}
} }
func (c *changeBuilder) ConvertFromRaw(rawChange *aclpb.RawChange) (ch *Change, err error) { func (c *changeBuilder) ConvertFromRaw(rawIdChange *aclpb.RawTreeChangeWithId, verify bool) (ch *Change, err error) {
unmarshalled := &aclpb.Change{} if rawIdChange.GetRawChange() == nil {
err = proto.Unmarshal(rawChange.Payload, unmarshalled) err = ErrEmptyChange
if err != nil {
return nil, err
}
ch = NewChange(rawChange.Id, unmarshalled, rawChange.Signature)
return return
}
func (c *changeBuilder) ConvertFromRawAndVerify(rawChange *aclpb.RawChange) (ch *Change, err error) {
unmarshalled := &aclpb.Change{}
ch, err = c.ConvertFromRaw(rawChange)
if err != nil {
return nil, err
} }
identityKey, err := c.keys.GetOrAdd(unmarshalled.Identity) if verify {
// verifying ID
if !cid.VerifyCID(rawIdChange.RawChange, rawIdChange.Id) {
err = ErrIncorrectCID
return
}
}
raw := &aclpb.RawTreeChange{}
err = proto.Unmarshal(rawIdChange.GetRawChange(), raw)
if err != nil {
return
}
if verify {
identityKey, err := c.keys.GetOrAdd(ch.Identity)
if err != nil { if err != nil {
return return
} }
// verifying signature // verifying signature
res, err := identityKey.Verify(rawChange.Payload, rawChange.Signature) res, err := identityKey.Verify(raw.Payload, raw.Signature)
if err != nil { if err != nil {
return return
} }
@ -71,17 +74,20 @@ func (c *changeBuilder) ConvertFromRawAndVerify(rawChange *aclpb.RawChange) (ch
err = ErrIncorrectSignature err = ErrIncorrectSignature
return return
} }
// verifying ID
if !cid.VerifyCID(rawChange.Payload, rawChange.Id) {
err = ErrIncorrectCID
} }
unmarshalled := &aclpb.TreeChange{}
err = proto.Unmarshal(raw.Payload, unmarshalled)
if err != nil {
return
}
ch = NewChange(rawIdChange.Id, unmarshalled, raw.Signature)
return return
} }
func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, raw *aclpb.RawChange, err error) { func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdChange *aclpb.RawTreeChangeWithId, err error) {
aclChange := &aclpb.Change{ change := &aclpb.TreeChange{
TreeHeadIds: payload.treeHeadIds, TreeHeadIds: payload.treeHeadIds,
AclHeadId: payload.aclHeadId, AclHeadId: payload.aclHeadId,
SnapshotBaseId: payload.snapshotBaseId, SnapshotBaseId: payload.snapshotBaseId,
@ -90,53 +96,65 @@ func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, raw *a
Identity: payload.identity, Identity: payload.identity,
IsSnapshot: payload.isSnapshot, IsSnapshot: payload.isSnapshot,
} }
marshalledData, err := payload.content.Marshal()
encrypted, err := payload.readKey.Encrypt(payload.content)
if err != nil {
return
}
change.ChangesData = encrypted
marshalledChange, err := proto.Marshal(change)
if err != nil { if err != nil {
return return
} }
encrypted, err := payload.readKey.Encrypt(marshalledData) signature, err := payload.signingKey.Sign(marshalledChange)
if err != nil {
return
}
aclChange.ChangesData = encrypted
fullMarshalledChange, err := proto.Marshal(aclChange)
if err != nil { if err != nil {
return return
} }
signature, err := payload.signingKey.Sign(fullMarshalledChange) raw := &aclpb.RawTreeChange{
Payload: marshalledChange,
Signature: signature,
}
marshalledRawChange, err := proto.Marshal(raw)
if err != nil { if err != nil {
return return
} }
id, err := cid.NewCIDFromBytes(fullMarshalledChange) id, err := cid.NewCIDFromBytes(marshalledRawChange)
if err != nil { if err != nil {
return return
} }
ch = NewChange(id, aclChange, signature) ch = NewChange(id, change, signature)
ch.ParsedModel = payload.content ch.ParsedModel = payload.content
raw = &aclpb.RawChange{ rawIdChange = &aclpb.RawTreeChangeWithId{
Payload: fullMarshalledChange, RawChange: marshalledRawChange,
Signature: signature,
Id: id, Id: id,
} }
return return
} }
func (c *changeBuilder) BuildRaw(ch *Change) (raw *aclpb.RawChange, err error) { func (c *changeBuilder) BuildRaw(ch *Change) (raw *aclpb.RawTreeChangeWithId, err error) {
var marshalled []byte var marshalled []byte
marshalled, err = ch.Content.Marshal() marshalled, err = ch.Content.Marshal()
if err != nil { if err != nil {
return return
} }
raw = &aclpb.RawChange{ marshalledRawChange, err := proto.Marshal(&aclpb.RawTreeChange{
Payload: marshalled, Payload: marshalled,
Signature: ch.Signature(), Signature: ch.Sign,
})
if err != nil {
return
}
raw = &aclpb.RawTreeChangeWithId{
RawChange: marshalledRawChange,
Id: ch.Id, Id: ch.Id,
} }
return return

View File

@ -48,7 +48,7 @@ func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.ACLList, c
return return
} }
if perm.Permission != aclpb.ACLChange_Writer && perm.Permission != aclpb.ACLChange_Admin { if perm.Permission != aclpb.ACLUserPermissions_Writer && perm.Permission != aclpb.ACLUserPermissions_Admin {
err = list.ErrInsufficientPermissions err = list.ErrInsufficientPermissions
return return
} }

View File

@ -8,8 +8,6 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list" "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/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
"go.uber.org/zap"
"sync" "sync"
) )
@ -34,7 +32,7 @@ type AddResultSummary int
type AddResult struct { type AddResult struct {
OldHeads []string OldHeads []string
Heads []string Heads []string
Added []*aclpb.RawChange Added []*aclpb.RawTreeChangeWithId
Mode Mode Mode Mode
} }
@ -46,7 +44,7 @@ type ObjectTree interface {
RWLocker RWLocker
ID() string ID() string
Header() *aclpb.Header Header() *aclpb.TreeHeader
Heads() []string Heads() []string
Root() *Change Root() *Change
HasChange(string) bool HasChange(string) bool
@ -55,13 +53,13 @@ type ObjectTree interface {
IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) error IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) error
SnapshotPath() []string SnapshotPath() []string
ChangesAfterCommonSnapshot(snapshotPath, heads []string) ([]*aclpb.RawChange, error) ChangesAfterCommonSnapshot(snapshotPath, heads []string) ([]*aclpb.RawTreeChangeWithId, error)
Storage() storage.TreeStorage Storage() storage.TreeStorage
DebugDump() (string, error) DebugDump() (string, error)
AddContent(ctx context.Context, content SignableChangeContent) (*aclpb.RawChange, error) AddContent(ctx context.Context, content SignableChangeContent) (*aclpb.RawTreeChangeWithId, error)
AddRawChanges(ctx context.Context, changes ...*aclpb.RawChange) (AddResult, error) AddRawChanges(ctx context.Context, changes ...*aclpb.RawTreeChangeWithId) (AddResult, error)
Close() error Close() error
} }
@ -76,13 +74,13 @@ type objectTree struct {
aclList list.ACLList aclList list.ACLList
id string id string
header *aclpb.Header header *aclpb.TreeHeader
tree *Tree tree *Tree
keys map[uint64]*symmetric.Key keys map[uint64]*symmetric.Key
// buffers // buffers
difSnapshotBuf []*aclpb.RawChange difSnapshotBuf []*aclpb.RawTreeChangeWithId
tmpChangesBuf []*Change tmpChangesBuf []*Change
newSnapshotsBuf []*Change newSnapshotsBuf []*Change
notSeenIdxBuf []int notSeenIdxBuf []int
@ -121,65 +119,6 @@ func defaultObjectTreeDeps(
} }
} }
func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) {
objTree := &objectTree{
treeStorage: deps.treeStorage,
updateListener: deps.updateListener,
treeBuilder: deps.treeBuilder,
validator: deps.validator,
aclList: deps.aclList,
changeBuilder: deps.changeBuilder,
rawChangeLoader: deps.rawChangeLoader,
tree: nil,
keys: make(map[uint64]*symmetric.Key),
tmpChangesBuf: make([]*Change, 0, 10),
difSnapshotBuf: make([]*aclpb.RawChange, 0, 10),
notSeenIdxBuf: make([]int, 0, 10),
newSnapshotsBuf: make([]*Change, 0, 10),
}
err := objTree.rebuildFromStorage(nil)
if err != nil {
return nil, err
}
storageHeads, err := objTree.treeStorage.Heads()
if err != nil {
return nil, err
}
// comparing rebuilt heads with heads in storage
// in theory it can happen that we didn't set heads because the process has crashed
// therefore we want to set them later
if !slice.UnsortedEquals(storageHeads, objTree.tree.Heads()) {
log.With(zap.Strings("storage", storageHeads), zap.Strings("rebuilt", objTree.tree.Heads())).
Errorf("the heads in storage and objTree are different")
err = objTree.treeStorage.SetHeads(objTree.tree.Heads())
if err != nil {
return nil, err
}
}
objTree.id, err = objTree.treeStorage.ID()
if err != nil {
return nil, err
}
objTree.header, err = objTree.treeStorage.Header()
if err != nil {
return nil, err
}
if objTree.updateListener != nil {
objTree.updateListener.Rebuild(objTree)
}
return objTree, nil
}
func BuildObjectTree(treeStorage storage.TreeStorage, listener ObjectTreeUpdateListener, aclList list.ACLList) (ObjectTree, error) {
deps := defaultObjectTreeDeps(treeStorage, listener, aclList)
return buildObjectTree(deps)
}
func (ot *objectTree) rebuildFromStorage(newChanges []*Change) (err error) { func (ot *objectTree) rebuildFromStorage(newChanges []*Change) (err error) {
ot.treeBuilder.Reset() ot.treeBuilder.Reset()
@ -201,7 +140,7 @@ func (ot *objectTree) ID() string {
return ot.id return ot.id
} }
func (ot *objectTree) Header() *aclpb.Header { func (ot *objectTree) Header() *aclpb.TreeHeader {
return ot.header return ot.header
} }
@ -209,7 +148,7 @@ func (ot *objectTree) Storage() storage.TreeStorage {
return ot.treeStorage return ot.treeStorage
} }
func (ot *objectTree) AddContent(ctx context.Context, content SignableChangeContent) (rawChange *aclpb.RawChange, err error) { func (ot *objectTree) AddContent(ctx context.Context, content SignableChangeContent) (rawChange *aclpb.RawTreeChangeWithId, err error) {
defer func() { defer func() {
if err == nil && ot.updateListener != nil { if err == nil && ot.updateListener != nil {
ot.updateListener.Update(ot) ot.updateListener.Update(ot)
@ -258,12 +197,12 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
isSnapshot: content.IsSnapshot, isSnapshot: content.IsSnapshot,
signingKey: content.Key, signingKey: content.Key,
readKey: readKey, readKey: readKey,
content: content.Proto, content: content.Data,
} }
return return
} }
func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawChange) (addResult AddResult, err error) { func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawTreeChangeWithId) (addResult AddResult, err error) {
var mode Mode var mode Mode
mode, addResult, err = ot.addRawChanges(ctx, rawChanges...) mode, addResult, err = ot.addRawChanges(ctx, rawChanges...)
if err != nil { if err != nil {
@ -302,7 +241,7 @@ func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
return return
} }
func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.RawChange) (mode Mode, addResult AddResult, err error) { func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.RawTreeChangeWithId) (mode Mode, addResult AddResult, err error) {
// resetting buffers // resetting buffers
ot.tmpChangesBuf = ot.tmpChangesBuf[:0] ot.tmpChangesBuf = ot.tmpChangesBuf[:0]
ot.notSeenIdxBuf = ot.notSeenIdxBuf[:0] ot.notSeenIdxBuf = ot.notSeenIdxBuf[:0]
@ -329,7 +268,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
} }
var change *Change var change *Change
change, err = ot.changeBuilder.ConvertFromRawAndVerify(ch) change, err = ot.changeBuilder.ConvertFromRaw(ch, true)
if err != nil { if err != nil {
return return
} }
@ -354,7 +293,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
// returns changes that we added to the tree as attached this round // returns changes that we added to the tree as attached this round
// they can include not only the changes that were added now, // they can include not only the changes that were added now,
// but also the changes that were previously in the tree // but also the changes that were previously in the tree
getAddedChanges := func(toConvert []*Change) (added []*aclpb.RawChange, err error) { getAddedChanges := func(toConvert []*Change) (added []*aclpb.RawTreeChangeWithId, err error) {
alreadyConverted := make(map[*Change]struct{}) alreadyConverted := make(map[*Change]struct{})
// first we see if we have already unmarshalled those changes // first we see if we have already unmarshalled those changes
@ -379,7 +318,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
for _, ch := range toConvert { for _, ch := range toConvert {
// if we got some changes that we need to convert to raw // if we got some changes that we need to convert to raw
if _, exists := alreadyConverted[ch]; !exists { if _, exists := alreadyConverted[ch]; !exists {
var raw *aclpb.RawChange var raw *aclpb.RawTreeChangeWithId
raw, err = ot.changeBuilder.BuildRaw(ch) raw, err = ot.changeBuilder.BuildRaw(ch)
if err != nil { if err != nil {
return return
@ -421,7 +360,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
ot.rebuildFromStorage(nil) ot.rebuildFromStorage(nil)
return return
} }
var added []*aclpb.RawChange var added []*aclpb.RawTreeChangeWithId
added, err = getAddedChanges(nil) added, err = getAddedChanges(nil)
// we shouldn't get any error in this case // we shouldn't get any error in this case
if err != nil { if err != nil {
@ -457,7 +396,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
err = ErrHasInvalidChanges err = ErrHasInvalidChanges
return return
} }
var added []*aclpb.RawChange var added []*aclpb.RawTreeChangeWithId
added, err = getAddedChanges(treeChangesAdded) added, err = getAddedChanges(treeChangesAdded)
if err != nil { if err != nil {
// that means that some unattached changes were somehow corrupted in memory // that means that some unattached changes were somehow corrupted in memory
@ -553,7 +492,7 @@ func (ot *objectTree) SnapshotPath() []string {
return path return path
} }
func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string) ([]*aclpb.RawChange, error) { func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string) ([]*aclpb.RawTreeChangeWithId, error) {
var ( var (
needFullDocument = len(theirPath) == 0 needFullDocument = len(theirPath) == 0
ourPath = ot.SnapshotPath() ourPath = ot.SnapshotPath()
@ -577,11 +516,11 @@ func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string)
} }
} }
func (ot *objectTree) getChangesFromTree(theirHeads []string) (rawChanges []*aclpb.RawChange, err error) { func (ot *objectTree) getChangesFromTree(theirHeads []string) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
return ot.rawChangeLoader.LoadFromTree(ot.tree, theirHeads) return ot.rawChangeLoader.LoadFromTree(ot.tree, theirHeads)
} }
func (ot *objectTree) getChangesFromDB(commonSnapshot string, theirHeads []string) (rawChanges []*aclpb.RawChange, err error) { func (ot *objectTree) getChangesFromDB(commonSnapshot string, theirHeads []string) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
return ot.rawChangeLoader.LoadFromStorage(commonSnapshot, ot.tree.headIds, theirHeads) return ot.rawChangeLoader.LoadFromStorage(commonSnapshot, ot.tree.headIds, theirHeads)
} }

View File

@ -15,7 +15,7 @@ import (
type mockChangeCreator struct{} type mockChangeCreator struct{}
func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot bool, prevIds ...string) *aclpb.RawChange { func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot bool, prevIds ...string) *aclpb.RawChange {
aclChange := &aclpb.Change{ aclChange := &aclpb.TreeChange{
TreeHeadIds: prevIds, TreeHeadIds: prevIds,
AclHeadId: aclId, AclHeadId: aclId,
SnapshotBaseId: snapshotId, SnapshotBaseId: snapshotId,
@ -23,22 +23,27 @@ func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot b
IsSnapshot: isSnapshot, IsSnapshot: isSnapshot,
} }
res, _ := aclChange.Marshal() res, _ := aclChange.Marshal()
return &aclpb.RawChange{
raw := &aclpb.RawTreeChange{
Payload: res, Payload: res,
Signature: nil, Signature: nil,
}
rawMarshalled, _ := raw.Marshal()
return &aclpb.RawTreeChangeWithId{
RawChange: rawMarshalled,
Id: id, Id: id,
} }
} }
func (c *mockChangeCreator) createNewTreeStorage(treeId, aclListId, aclHeadId, firstChangeId string) storage.TreeStorage { func (c *mockChangeCreator) createNewTreeStorage(treeId, aclListId, aclHeadId, firstChangeId string) storage.TreeStorage {
firstChange := c.createRaw(firstChangeId, aclHeadId, "", true) firstChange := c.createRaw(firstChangeId, aclHeadId, "", true)
header := &aclpb.Header{ header := &aclpb.TreeHeader{
FirstId: firstChangeId, FirstId: firstChangeId,
AclListId: aclListId, AclId: aclListId,
WorkspaceId: "", TreeHeaderType: aclpb.TreeHeaderType_Object,
DocType: aclpb.Header_DocTree,
} }
treeStorage, _ := storage.NewInMemoryTreeStorage(treeId, header, []string{firstChangeId}, []*aclpb.RawChange{firstChange}) treeStorage, _ := storage.NewInMemoryTreeStorage(treeId, header, []string{firstChangeId}, []*aclpb.RawTreeChangeWithId{firstChange})
return treeStorage return treeStorage
} }

View File

@ -0,0 +1,161 @@
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/util/keys/symmetric"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
"github.com/gogo/protobuf/proto"
"go.uber.org/zap"
)
type ObjectTreeCreatePayload struct {
AccountData *account.AccountData
HeaderData []byte
ChangeData []byte
TreeType aclpb.TreeHeaderType
}
func BuildObjectTree(treeStorage storage.TreeStorage, listener ObjectTreeUpdateListener, aclList list.ACLList) (ObjectTree, error) {
deps := defaultObjectTreeDeps(treeStorage, listener, aclList)
return buildObjectTree(deps)
}
func CreateObjectTree(
payload ObjectTreeCreatePayload,
listener ObjectTreeUpdateListener,
aclList list.ACLList,
createStorage storage.TreeStorageCreatorFunc) (objTree ObjectTree, err error) {
aclList.RLock()
var (
deps = defaultObjectTreeDeps(nil, listener, aclList)
state = aclList.ACLState()
aclId = aclList.ID()
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,
}
_, 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)
if err != nil {
return
}
// create storage
st, err := createStorage(storage.TreeStorageCreatePayload{
TreeId: id,
Header: header,
Changes: []*aclpb.RawTreeChangeWithId{raw},
Heads: []string{raw.Id},
})
if err != nil {
return
}
deps.treeStorage = st
return buildObjectTree(deps)
}
func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) {
objTree := &objectTree{
treeStorage: deps.treeStorage,
updateListener: deps.updateListener,
treeBuilder: deps.treeBuilder,
validator: deps.validator,
aclList: deps.aclList,
changeBuilder: deps.changeBuilder,
rawChangeLoader: deps.rawChangeLoader,
tree: nil,
keys: make(map[uint64]*symmetric.Key),
tmpChangesBuf: make([]*Change, 0, 10),
difSnapshotBuf: make([]*aclpb.RawTreeChangeWithId, 0, 10),
notSeenIdxBuf: make([]int, 0, 10),
newSnapshotsBuf: make([]*Change, 0, 10),
}
err := objTree.rebuildFromStorage(nil)
if err != nil {
return nil, err
}
storageHeads, err := objTree.treeStorage.Heads()
if err != nil {
return nil, err
}
// comparing rebuilt heads with heads in storage
// in theory it can happen that we didn't set heads because the process has crashed
// therefore we want to set them later
if !slice.UnsortedEquals(storageHeads, objTree.tree.Heads()) {
log.With(zap.Strings("storage", storageHeads), zap.Strings("rebuilt", objTree.tree.Heads())).
Errorf("the heads in storage and objTree are different")
err = objTree.treeStorage.SetHeads(objTree.tree.Heads())
if err != nil {
return nil, err
}
}
objTree.id, err = objTree.treeStorage.ID()
if err != nil {
return nil, err
}
objTree.header, err = objTree.treeStorage.Header()
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
}

View File

@ -18,7 +18,7 @@ type rawChangeLoader struct {
type rawCacheEntry struct { type rawCacheEntry struct {
change *Change change *Change
rawChange *aclpb.RawChange rawChange *aclpb.RawTreeChangeWithId
position int position int
} }
@ -29,15 +29,15 @@ func newRawChangeLoader(treeStorage storage.TreeStorage, changeBuilder ChangeBui
} }
} }
func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.RawChange, error) { func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.RawTreeChangeWithId, error) {
var stack []*Change var stack []*Change
for _, h := range t.headIds { for _, h := range t.headIds {
stack = append(stack, t.attached[h]) stack = append(stack, t.attached[h])
} }
convert := func(chs []*Change) (rawChanges []*aclpb.RawChange, err error) { convert := func(chs []*Change) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
for _, ch := range chs { for _, ch := range chs {
var raw *aclpb.RawChange var raw *aclpb.RawTreeChangeWithId
raw, err = r.changeBuilder.BuildRaw(ch) raw, err = r.changeBuilder.BuildRaw(ch)
if err != nil { if err != nil {
return return
@ -95,7 +95,7 @@ func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.
return convert(results) return convert(results)
} }
func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoints []string) ([]*aclpb.RawChange, error) { func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoints []string) ([]*aclpb.RawTreeChangeWithId, error) {
// resetting cache // resetting cache
r.cache = make(map[string]rawCacheEntry) r.cache = make(map[string]rawCacheEntry)
defer func() { defer func() {
@ -162,7 +162,7 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi
// preparing first pass // preparing first pass
r.idStack = append(r.idStack, heads...) r.idStack = append(r.idStack, heads...)
var buffer []*aclpb.RawChange var buffer []*aclpb.RawTreeChangeWithId
rootVisited := dfs(commonSnapshot, heads, 0, rootVisited := dfs(commonSnapshot, heads, 0,
func(counter int, mapExists bool) bool { func(counter int, mapExists bool) bool {
@ -203,7 +203,7 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi
}) })
// discarding visited // discarding visited
buffer = discardFromSlice(buffer, func(change *aclpb.RawChange) bool { buffer = discardFromSlice(buffer, func(change *aclpb.RawTreeChangeWithId) bool {
return change == nil return change == nil
}) })
@ -219,7 +219,7 @@ func (r *rawChangeLoader) loadEntry(id string) (entry rawCacheEntry, err error)
return return
} }
change, err := r.changeBuilder.ConvertFromRaw(rawChange) change, err := r.changeBuilder.ConvertFromRaw(rawChange, false)
if err != nil { if err != nil {
return return
} }

View File

@ -2,12 +2,11 @@ package tree
import ( import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"github.com/gogo/protobuf/proto"
) )
type SignableChangeContent struct { type SignableChangeContent struct {
Proto proto.Marshaler Data []byte
Key signingkey.PrivKey Key signingkey.PrivKey
Identity string Identity []byte
IsSnapshot bool IsSnapshot bool
} }

View File

@ -0,0 +1,91 @@
package tests
import (
"bytes"
"math/rand"
"testing"
"time"
)
func BenchmarkHashes(b *testing.B) {
genRandomBytes := func() [][]byte {
var res [][]byte
s := rand.NewSource(time.Now().Unix())
r := rand.New(s)
for i := 0; i < 10000; i++ {
var newBytes []byte
for j := 0; j < 64; j++ {
newBytes = append(newBytes, byte(r.Intn(256)))
}
res = append(res, newBytes)
}
return res
}
makeStrings := func(input [][]byte) []string {
var res []string
for _, bytes := range input {
res = append(res, string(bytes))
}
return res
}
res := genRandomBytes()
stringRes := makeStrings(res)
stringMap := map[string]struct{}{}
b.Run("string bytes hash map write", func(b *testing.B) {
stringMap = map[string]struct{}{}
for i := 0; i < b.N; i++ {
for _, bytes := range res {
stringMap[string(bytes)] = struct{}{}
}
}
b.Run("hash map read", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, bytes := range res {
_, _ = stringMap[string(bytes)]
}
}
})
})
b.Run("compare byte slices as strings", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, bytes := range res {
if string(bytes) == string(bytes) {
}
}
}
})
b.Run("compare byte slices", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, bt := range res {
if bytes.Compare(bt, bt) == 0 {
}
}
}
})
b.Run("compare strings", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, st := range stringRes {
if st == st {
}
}
}
})
b.Run("string hash map write", func(b *testing.B) {
stringMap = map[string]struct{}{}
for i := 0; i < b.N; i++ {
for _, str := range stringRes {
stringMap[str] = struct{}{}
}
}
b.Run("hash map read", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, str := range stringRes {
_, _ = stringMap[str]
}
}
})
})
}

View File

@ -129,7 +129,7 @@ func (tb *treeBuilder) loadChange(id string) (ch *Change, err error) {
return nil, err return nil, err
} }
ch, err = tb.builder.ConvertFromRawAndVerify(change) ch, err = tb.builder.ConvertFromRaw(change, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,91 +0,0 @@
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/gogo/protobuf/proto"
"time"
)
func CreateNewTreeStorage(
acc *account.AccountData,
aclList list.ACLList,
content proto.Marshaler,
create storage.TreeStorageCreatorFunc) (thr storage.TreeStorage, err error) {
state := aclList.ACLState()
change := &aclpb.Change{
AclHeadId: aclList.Head().Id,
CurrentReadKeyHash: state.CurrentReadKeyHash(),
Timestamp: int64(time.Now().Nanosecond()),
Identity: acc.Identity,
IsSnapshot: true,
}
marshalledData, err := content.Marshal()
if err != nil {
return
}
readKey, err := state.CurrentReadKey()
if err != nil {
return
}
encrypted, err := readKey.Encrypt(marshalledData)
if err != nil {
return
}
change.ChangesData = encrypted
fullMarshalledChange, err := proto.Marshal(change)
if err != nil {
return
}
signature, err := acc.SignKey.Sign(fullMarshalledChange)
if err != nil {
return
}
changeId, err := cid.NewCIDFromBytes(fullMarshalledChange)
if err != nil {
return
}
rawChange := &aclpb.RawChange{
Payload: fullMarshalledChange,
Signature: signature,
Id: changeId,
}
header, treeId, err := createTreeHeaderAndId(rawChange, aclpb.Header_DocTree, aclList.ID())
if err != nil {
return
}
return create(storage.TreeStorageCreatePayload{
TreeId: treeId,
Header: header,
Changes: []*aclpb.RawChange{rawChange},
Heads: []string{rawChange.Id},
})
}
func createTreeHeaderAndId(change *aclpb.RawChange, treeType aclpb.HeaderDocType, aclListId string) (header *aclpb.Header, treeId string, err error) {
header = &aclpb.Header{
FirstId: change.Id,
DocType: treeType,
AclListId: aclListId,
}
marshalledHeader, err := proto.Marshal(header)
if err != nil {
return
}
treeId, err = cid.NewCIDFromBytes(marshalledHeader)
return
}

View File

@ -15,7 +15,7 @@ var log = logger.NewNamed("storage").Sugar()
type ImportedACLSyncData struct { type ImportedACLSyncData struct {
Id string Id string
Header *aclpb.Header Header *aclpb.Header
Records []*aclpb.RawRecord Records []*aclpb.RawACLRecord
} }
type Service interface { type Service interface {

View File

@ -47,44 +47,3 @@ message System {
} }
} }
} }
message Sync {
string spaceId = 1;
ContentValue message = 2;
acl.Header treeHeader = 3;
string treeId = 4;
message ContentValue {
oneof value {
HeadUpdate headUpdate = 1;
Full.Request fullSyncRequest = 2;
Full.Response fullSyncResponse = 3;
ACLList aclList = 4;
}
}
message ACLList {
repeated acl.RawRecord records = 1;
}
message HeadUpdate {
repeated string heads = 1;
repeated acl.RawChange changes = 2;
repeated string snapshotPath = 3;
}
message Full {
// here with send the request with all changes we have (we already know sender's snapshot path)
message Request {
repeated string heads = 1;
repeated acl.RawChange changes = 2;
repeated string snapshotPath = 3;
}
message Response {
repeated string heads = 1;
repeated acl.RawChange changes = 2;
repeated string snapshotPath = 3;
}
}
}

File diff suppressed because it is too large Load Diff