Merge pull request #3 from anytypeio/improve-acl-naming-and-packages

This commit is contained in:
Mikhail Rakhmanov 2022-07-14 13:17:16 +02:00 committed by GitHub
commit 1331123fb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 1241 additions and 2277 deletions

View File

@ -15,16 +15,19 @@ export PATH=$(GOPATH)/bin:$(shell echo $$PATH)
# TODO: folders were changed, so we should update Makefile and protos generation
protos-go:
@echo 'Generating protobuf packages (Go)...'
$(eval P_TIMESTAMP := Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types)
$(eval P_STRUCT := Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types)
@$(eval P_ACL_CHANGES := Mdata/pb/protos/aclchanges.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges/pb)
@$(eval P_THREAD := Mdata/pb/protos/aclchanges.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/thread/pb)
@$(eval P_PLAINTEXT_CHANGES := Mdata/pb/protos/plaintextchanges.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/testutils/testchanges/pb)
# Uncomment if needed
@$(eval P_TIMESTAMP := Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types)
@$(eval P_STRUCT := Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types)
@$(eval ROOT_PKG := pkg)
@$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1)
@$(eval P_TREE_STORAGE_PATH_PB := $(ROOT_PKG)/acl/treestorage/treepb)
@$(eval P_ACL_CHANGES_PATH_PB := $(ROOT_PKG)/acl/aclchanges/aclpb)
@$(eval P_PLAINTEXT_CHANGES_PATH_PB := $(ROOT_PKG)/acl/testutils/testchanges/testchangepb)
$(eval PKGMAP := $$(P_TIMESTAMP),$$(P_STRUCT),$$(P_ACL_CHANGES))
GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1 protoc --gogofaster_out=$(PKGMAP):./aclchanges/pb aclchanges/pb/protos/*.*; mv aclchanges/pb/aclchanges/pb/protos/*.go aclchanges/pb; rm -rf aclchanges/pb/aclchanges
$(eval PKGMAP := $$(P_TIMESTAMP),$$(P_STRUCT),$$(P_THREAD))
GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1 protoc --gogofaster_out=$(PKGMAP):./thread/pb thread/pb/protos/*.*; mv thread/pb/thread/pb/protos/*.go thread/pb; rm -rf thread/pb/thread
# use if needed $(eval PKGMAP := $$(P_TIMESTAMP),$$(P_STRUCT))
$(GOGO_START) protoc --gogofaster_out=:. $(P_ACL_CHANGES_PATH_PB)/protos/*.proto; mv $(P_ACL_CHANGES_PATH_PB)/protos/*.go $(P_ACL_CHANGES_PATH_PB)
$(GOGO_START) protoc --gogofaster_out=:. $(P_TREE_STORAGE_PATH_PB)/protos/*.proto; mv $(P_TREE_STORAGE_PATH_PB)/protos/*.go $(P_TREE_STORAGE_PATH_PB)
$(GOGO_START) protoc --gogofaster_out=:. $(P_PLAINTEXT_CHANGES_PATH_PB)/protos/*.proto; mv $(P_PLAINTEXT_CHANGES_PATH_PB)/protos/*.go $(P_PLAINTEXT_CHANGES_PATH_PB)
build:
@$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/app))

32
go.mod
View File

@ -6,54 +6,32 @@ require (
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab
github.com/goccy/go-graphviz v0.0.9
github.com/gogo/protobuf v1.3.2
github.com/libp2p/go-libp2p-core v0.8.5
github.com/ipfs/go-cid v0.0.7
github.com/mr-tron/base58 v1.2.0
github.com/multiformats/go-base32 v0.0.3
github.com/multiformats/go-multiaddr v0.3.3
github.com/multiformats/go-multiaddr-dns v0.3.1
github.com/multiformats/go-multibase v0.0.3
github.com/multiformats/go-multihash v0.0.15
github.com/prometheus/common v0.18.0
github.com/stretchr/testify v1.7.0
github.com/textileio/go-threads v1.0.2-0.20210304072541-d0f91da84404
go.uber.org/zap v1.21.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/btcsuite/btcd v0.21.0-beta // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/fogleman/gg v1.3.0 // indirect
github.com/gogo/googleapis v1.3.1 // indirect
github.com/gogo/status v1.1.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.2.1 // indirect
github.com/ipfs/go-cid v0.0.7 // indirect
github.com/klauspost/cpuid/v2 v2.0.4 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
github.com/libp2p/go-openssl v0.0.7 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/multiformats/go-base32 v0.0.3 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.6.0 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
google.golang.org/grpc v1.33.2 // indirect
google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)
replace github.com/textileio/go-threads => github.com/anytypeio/go-threads v1.1.0-rc1.0.20220223104843-a67245cee80e

1246
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,13 @@
package account
import "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
)
type AccountData struct {
Identity string
SignKey keys.SigningPrivKey
EncKey keys.EncryptionPrivKey
type AccountData struct { // TODO: create a convenient constructor for this
Identity string // TODO: this is essentially the same as sign key
SignKey signingkey.PrivKey
EncKey encryptionkey.PrivKey
Decoder signingkey.PubKeyDecoder
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: aclchanges/pb/protos/aclchanges.proto
// source: pkg/acl/aclchanges/aclpb/protos/aclchanges.proto
package pb
package aclpb
import (
fmt "fmt"
@ -50,7 +50,7 @@ func (x ACLChangeUserPermissions) String() string {
}
func (ACLChangeUserPermissions) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 0}
return fileDescriptor_37a022c841a51877, []int{0, 0}
}
// the element of change tree used to store and internal apply smartBlock history
@ -70,7 +70,7 @@ func (m *ACLChange) Reset() { *m = ACLChange{} }
func (m *ACLChange) String() string { return proto.CompactTextString(m) }
func (*ACLChange) ProtoMessage() {}
func (*ACLChange) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0}
return fileDescriptor_37a022c841a51877, []int{0}
}
func (m *ACLChange) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -170,7 +170,7 @@ func (m *ACLChangeACLContentValue) Reset() { *m = ACLChangeACLContentVal
func (m *ACLChangeACLContentValue) String() string { return proto.CompactTextString(m) }
func (*ACLChangeACLContentValue) ProtoMessage() {}
func (*ACLChangeACLContentValue) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 0}
return fileDescriptor_37a022c841a51877, []int{0, 0}
}
func (m *ACLChangeACLContentValue) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -301,7 +301,7 @@ func (m *ACLChangeACLData) Reset() { *m = ACLChangeACLData{} }
func (m *ACLChangeACLData) String() string { return proto.CompactTextString(m) }
func (*ACLChangeACLData) ProtoMessage() {}
func (*ACLChangeACLData) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 1}
return fileDescriptor_37a022c841a51877, []int{0, 1}
}
func (m *ACLChangeACLData) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -353,7 +353,7 @@ func (m *ACLChangeACLSnapshot) Reset() { *m = ACLChangeACLSnapshot{} }
func (m *ACLChangeACLSnapshot) String() string { return proto.CompactTextString(m) }
func (*ACLChangeACLSnapshot) ProtoMessage() {}
func (*ACLChangeACLSnapshot) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 2}
return fileDescriptor_37a022c841a51877, []int{0, 2}
}
func (m *ACLChangeACLSnapshot) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -399,7 +399,7 @@ func (m *ACLChangeACLState) Reset() { *m = ACLChangeACLState{} }
func (m *ACLChangeACLState) String() string { return proto.CompactTextString(m) }
func (*ACLChangeACLState) ProtoMessage() {}
func (*ACLChangeACLState) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 3}
return fileDescriptor_37a022c841a51877, []int{0, 3}
}
func (m *ACLChangeACLState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -461,7 +461,7 @@ func (m *ACLChangeUserState) Reset() { *m = ACLChangeUserState{} }
func (m *ACLChangeUserState) String() string { return proto.CompactTextString(m) }
func (*ACLChangeUserState) ProtoMessage() {}
func (*ACLChangeUserState) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 4}
return fileDescriptor_37a022c841a51877, []int{0, 4}
}
func (m *ACLChangeUserState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -537,7 +537,7 @@ func (m *ACLChangeUserAdd) Reset() { *m = ACLChangeUserAdd{} }
func (m *ACLChangeUserAdd) String() string { return proto.CompactTextString(m) }
func (*ACLChangeUserAdd) ProtoMessage() {}
func (*ACLChangeUserAdd) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 5}
return fileDescriptor_37a022c841a51877, []int{0, 5}
}
func (m *ACLChangeUserAdd) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -604,7 +604,7 @@ func (m *ACLChangeUserConfirm) Reset() { *m = ACLChangeUserConfirm{} }
func (m *ACLChangeUserConfirm) String() string { return proto.CompactTextString(m) }
func (*ACLChangeUserConfirm) ProtoMessage() {}
func (*ACLChangeUserConfirm) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 6}
return fileDescriptor_37a022c841a51877, []int{0, 6}
}
func (m *ACLChangeUserConfirm) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -659,7 +659,7 @@ func (m *ACLChangeUserInvite) Reset() { *m = ACLChangeUserInvite{} }
func (m *ACLChangeUserInvite) String() string { return proto.CompactTextString(m) }
func (*ACLChangeUserInvite) ProtoMessage() {}
func (*ACLChangeUserInvite) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 7}
return fileDescriptor_37a022c841a51877, []int{0, 7}
}
func (m *ACLChangeUserInvite) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -735,7 +735,7 @@ func (m *ACLChangeUserJoin) Reset() { *m = ACLChangeUserJoin{} }
func (m *ACLChangeUserJoin) String() string { return proto.CompactTextString(m) }
func (*ACLChangeUserJoin) ProtoMessage() {}
func (*ACLChangeUserJoin) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 8}
return fileDescriptor_37a022c841a51877, []int{0, 8}
}
func (m *ACLChangeUserJoin) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -808,7 +808,7 @@ func (m *ACLChangeUserRemove) Reset() { *m = ACLChangeUserRemove{} }
func (m *ACLChangeUserRemove) String() string { return proto.CompactTextString(m) }
func (*ACLChangeUserRemove) ProtoMessage() {}
func (*ACLChangeUserRemove) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 9}
return fileDescriptor_37a022c841a51877, []int{0, 9}
}
func (m *ACLChangeUserRemove) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -861,7 +861,7 @@ func (m *ACLChangeReadKeyReplace) Reset() { *m = ACLChangeReadKeyReplace
func (m *ACLChangeReadKeyReplace) String() string { return proto.CompactTextString(m) }
func (*ACLChangeReadKeyReplace) ProtoMessage() {}
func (*ACLChangeReadKeyReplace) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 10}
return fileDescriptor_37a022c841a51877, []int{0, 10}
}
func (m *ACLChangeReadKeyReplace) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -920,7 +920,7 @@ func (m *ACLChangeUserPermissionChange) Reset() { *m = ACLChangeUserPerm
func (m *ACLChangeUserPermissionChange) String() string { return proto.CompactTextString(m) }
func (*ACLChangeUserPermissionChange) ProtoMessage() {}
func (*ACLChangeUserPermissionChange) Descriptor() ([]byte, []int) {
return fileDescriptor_ffc88c8445fc0f24, []int{0, 11}
return fileDescriptor_37a022c841a51877, []int{0, 11}
}
func (m *ACLChangeUserPermissionChange) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -982,68 +982,69 @@ func init() {
}
func init() {
proto.RegisterFile("aclchanges/pb/protos/aclchanges.proto", fileDescriptor_ffc88c8445fc0f24)
proto.RegisterFile("pkg/acl/aclchanges/aclpb/protos/aclchanges.proto", fileDescriptor_37a022c841a51877)
}
var fileDescriptor_ffc88c8445fc0f24 = []byte{
// 907 bytes of a gzipped FileDescriptorProto
var fileDescriptor_37a022c841a51877 = []byte{
// 915 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4d, 0x6f, 0xe3, 0x44,
0x18, 0xf6, 0x24, 0x6d, 0x1d, 0xbf, 0x0e, 0x6d, 0x18, 0xf5, 0x60, 0x79, 0x8b, 0x15, 0x2a, 0x3e,
0x22, 0x84, 0x52, 0x29, 0x8b, 0xf8, 0x12, 0x12, 0x34, 0x5d, 0x20, 0xa1, 0x1c, 0x56, 0xb3, 0x02,
0x04, 0x12, 0x87, 0xa9, 0x3d, 0x6c, 0x2d, 0x92, 0xb1, 0xe5, 0x99, 0x54, 0xe4, 0xc2, 0x3f, 0x40,
0xf0, 0x5b, 0xb8, 0x72, 0xe0, 0xba, 0xc7, 0x3d, 0x72, 0x44, 0xed, 0x3f, 0xe0, 0x17, 0xa0, 0xf9,
0xb0, 0xe3, 0xa4, 0x71, 0x91, 0x50, 0x25, 0xc4, 0x6d, 0xe6, 0x99, 0xe7, 0x99, 0xbc, 0x1f, 0xcf,
0x3b, 0x0e, 0xbc, 0x4a, 0xe3, 0x59, 0x7c, 0x49, 0xf9, 0x53, 0x26, 0x4e, 0xf2, 0x8b, 0x93, 0xbc,
0xc8, 0x64, 0x26, 0x4e, 0x56, 0xe0, 0x50, 0x23, 0xd8, 0xa5, 0x7c, 0x29, 0x97, 0x39, 0x3b, 0xfe,
0xed, 0x10, 0xbc, 0xd3, 0xb3, 0xcf, 0xcf, 0xf4, 0x29, 0xee, 0x83, 0x2f, 0x0b, 0xc6, 0x26, 0x8c,
0x26, 0xd3, 0x44, 0x04, 0xa8, 0xdf, 0x1e, 0x78, 0xa4, 0x0e, 0xe1, 0x08, 0x80, 0xc6, 0xb3, 0x92,
0xd0, 0xd2, 0x84, 0x1a, 0x82, 0x5f, 0x83, 0x7d, 0xc1, 0x69, 0x2e, 0x2e, 0x33, 0x39, 0xa6, 0x82,
0x4d, 0x93, 0xa0, 0xdd, 0x47, 0x03, 0x8f, 0x6c, 0xa0, 0xf8, 0x2d, 0x70, 0x69, 0x3c, 0x7b, 0x44,
0x25, 0x0d, 0x76, 0xfa, 0x68, 0xe0, 0x8f, 0xc2, 0xa1, 0x0d, 0x69, 0x58, 0x85, 0xa3, 0x56, 0x8a,
0x41, 0x4a, 0xaa, 0x8a, 0xcf, 0xe6, 0xa1, 0x95, 0xbb, 0x7d, 0x34, 0xe8, 0x92, 0x3a, 0x84, 0x87,
0x80, 0xe3, 0x45, 0x51, 0x30, 0x2e, 0x09, 0xa3, 0xc9, 0x39, 0x5b, 0x4e, 0xa8, 0xb8, 0x0c, 0xf6,
0xfa, 0x68, 0xb0, 0x43, 0xb6, 0x9c, 0xe0, 0x23, 0xf0, 0x64, 0x3a, 0x67, 0x42, 0xd2, 0x79, 0x1e,
0xb8, 0x7d, 0x34, 0x68, 0x93, 0x15, 0x80, 0x43, 0xe8, 0xa4, 0x09, 0xe3, 0x32, 0x95, 0xcb, 0xa0,
0xa3, 0xf3, 0xa8, 0xf6, 0xe1, 0xaf, 0x6d, 0x38, 0x50, 0xa1, 0x66, 0x5c, 0x32, 0x2e, 0xbf, 0xa4,
0xb3, 0x05, 0xc3, 0x6f, 0x83, 0xbb, 0x10, 0xac, 0x38, 0x4d, 0x92, 0x00, 0x35, 0x66, 0xf5, 0x85,
0x61, 0x4c, 0x1c, 0x52, 0x92, 0xf1, 0x87, 0x00, 0x6a, 0x49, 0xd8, 0x3c, 0xbb, 0x62, 0x41, 0x4b,
0x4b, 0x5f, 0x6a, 0x90, 0x1a, 0xd2, 0xc4, 0x21, 0x35, 0x09, 0xfe, 0x16, 0x0e, 0xd5, 0xee, 0x31,
0x2b, 0xe6, 0xa9, 0x10, 0x69, 0xc6, 0x8d, 0x40, 0x17, 0xdf, 0x1f, 0xbd, 0xde, 0x70, 0xd5, 0x26,
0x7d, 0xe2, 0x90, 0xad, 0xd7, 0x94, 0xf1, 0x4d, 0xf9, 0x55, 0x2a, 0x99, 0x6d, 0x58, 0x53, 0x7c,
0x86, 0x54, 0xc6, 0x67, 0x76, 0xf8, 0x3d, 0xe8, 0xa8, 0xdd, 0x67, 0x59, 0xca, 0x75, 0xd7, 0xfc,
0xd1, 0x83, 0x06, 0xb9, 0xa2, 0x4c, 0x1c, 0x52, 0xd1, 0xf1, 0x18, 0x7c, 0xb5, 0x3e, 0xcb, 0xf8,
0x77, 0x69, 0x31, 0xd7, 0xad, 0xf4, 0x47, 0x51, 0x83, 0xda, 0xb2, 0x26, 0x0e, 0xa9, 0x8b, 0xc6,
0x2e, 0xec, 0x5e, 0xa9, 0x06, 0x85, 0x3f, 0x23, 0x70, 0xad, 0xab, 0xf0, 0x47, 0xe0, 0xd3, 0x78,
0xf6, 0xc4, 0xfa, 0xd2, 0x36, 0x2c, 0xda, 0x6e, 0xc3, 0x92, 0x45, 0xea, 0x12, 0x3c, 0xd6, 0xc3,
0x60, 0x1d, 0xa0, 0x87, 0xc1, 0x1f, 0x1d, 0x6f, 0xbf, 0xa0, 0x6e, 0x13, 0x52, 0x53, 0x85, 0x9f,
0x80, 0x5f, 0xbb, 0x1f, 0xbf, 0x03, 0x1d, 0xf5, 0x0b, 0x92, 0x4a, 0x66, 0x23, 0x7a, 0xd0, 0x10,
0x91, 0xa2, 0x90, 0x8a, 0x1c, 0xfe, 0xd4, 0x82, 0x4e, 0x09, 0xe3, 0x57, 0xe0, 0x85, 0x62, 0x65,
0x72, 0x66, 0x26, 0x79, 0x87, 0xac, 0x83, 0xf8, 0x03, 0xd3, 0x55, 0x2d, 0x11, 0x36, 0xfc, 0xa3,
0x86, 0xc2, 0x9a, 0x9f, 0xab, 0xf1, 0xf1, 0x18, 0xdc, 0x54, 0x37, 0x57, 0x04, 0x6d, 0x2d, 0x1d,
0xdc, 0x11, 0xe8, 0xd0, 0xf8, 0x40, 0x7c, 0xcc, 0x65, 0xb1, 0x24, 0xa5, 0x30, 0xfc, 0x1a, 0xba,
0xf5, 0x03, 0xdc, 0x83, 0xf6, 0xf7, 0x6c, 0xa9, 0x13, 0xf7, 0x88, 0x5a, 0xe2, 0x87, 0xb6, 0x73,
0xff, 0x30, 0x14, 0xe6, 0x16, 0x62, 0xb8, 0xef, 0xb7, 0xde, 0x45, 0xe1, 0x0d, 0x02, 0xaf, 0x0a,
0x7c, 0x6d, 0x90, 0xd1, 0xfa, 0x20, 0xab, 0x62, 0x31, 0x1e, 0x17, 0xcb, 0x5c, 0xa6, 0x19, 0x3f,
0x67, 0x4b, 0xfd, 0x53, 0x5d, 0xb2, 0x0e, 0xe2, 0x37, 0xe1, 0x45, 0x0b, 0xb0, 0xc4, 0x3e, 0x20,
0x26, 0xf1, 0x2e, 0xb9, 0x7d, 0x80, 0x1f, 0x81, 0x9f, 0x57, 0x43, 0x24, 0xf4, 0xc4, 0xec, 0x6f,
0xb5, 0xc6, 0xfa, 0x18, 0x0a, 0x52, 0x97, 0xa9, 0xe7, 0x6e, 0x2a, 0xac, 0x87, 0x59, 0xa2, 0x07,
0xa7, 0x43, 0xea, 0x50, 0xf8, 0x3b, 0x02, 0xd7, 0xbe, 0x27, 0xff, 0xcf, 0x1c, 0xc3, 0x4f, 0xc1,
0xaf, 0x0d, 0xee, 0x9d, 0x49, 0x1c, 0x81, 0x67, 0x1f, 0xcc, 0x69, 0xa2, 0x13, 0xf0, 0xc8, 0x0a,
0x08, 0xff, 0x42, 0x00, 0x2b, 0x2b, 0xe0, 0x01, 0x1c, 0xd0, 0x38, 0x66, 0xb9, 0x7c, 0xbc, 0xb8,
0x98, 0xa5, 0xf1, 0xb9, 0xb5, 0x55, 0x97, 0x6c, 0xc2, 0xf8, 0x0d, 0xe8, 0xd9, 0xe4, 0x56, 0x54,
0x53, 0x9e, 0x5b, 0xf8, 0x7f, 0xe2, 0x82, 0x10, 0x3a, 0x26, 0xa7, 0xa9, 0xb1, 0x80, 0x47, 0xaa,
0x7d, 0xf8, 0x0c, 0x41, 0xa7, 0x7c, 0x35, 0xef, 0xc1, 0x00, 0x55, 0xd1, 0x9e, 0xa4, 0x4f, 0x39,
0x95, 0x8b, 0xc2, 0x7c, 0x41, 0xaa, 0xa2, 0x55, 0x30, 0x3e, 0x86, 0xee, 0xea, 0x79, 0x9f, 0x26,
0x3a, 0x37, 0x8f, 0xac, 0x61, 0xdb, 0x8b, 0xb5, 0xdb, 0x50, 0xac, 0x70, 0x61, 0xda, 0x67, 0x3f,
0x68, 0x77, 0xe5, 0x72, 0x0e, 0x07, 0xf6, 0x21, 0x23, 0x2c, 0x9f, 0xd1, 0xb8, 0x7a, 0x81, 0x5e,
0xde, 0x52, 0x5a, 0xb2, 0xc6, 0x24, 0x9b, 0xca, 0xf0, 0x47, 0xd8, 0x5f, 0xa7, 0xdc, 0x43, 0x19,
0x57, 0x8e, 0xaa, 0xf2, 0xb3, 0x75, 0xbc, 0x85, 0x87, 0x3f, 0xc0, 0xe1, 0xb6, 0x4f, 0xf1, 0x9d,
0x51, 0x6c, 0xf8, 0xaa, 0xf5, 0xaf, 0x7c, 0x75, 0x7c, 0x0a, 0x07, 0x1b, 0xe7, 0xd8, 0x83, 0xdd,
0xd3, 0x64, 0x9e, 0xf2, 0x9e, 0x83, 0x01, 0xf6, 0xbe, 0x2a, 0x52, 0xc9, 0x8a, 0x1e, 0x52, 0x6b,
0x15, 0x2e, 0x2b, 0x7a, 0x2d, 0xec, 0x83, 0x6b, 0x5a, 0x94, 0xf4, 0xda, 0xe3, 0xa3, 0x67, 0xd7,
0x11, 0x7a, 0x7e, 0x1d, 0xa1, 0x3f, 0xaf, 0x23, 0xf4, 0xcb, 0x4d, 0xe4, 0x3c, 0xbf, 0x89, 0x9c,
0x3f, 0x6e, 0x22, 0xe7, 0x9b, 0x56, 0x7e, 0x71, 0xb1, 0xa7, 0xff, 0x6b, 0x3e, 0xfc, 0x3b, 0x00,
0x00, 0xff, 0xff, 0xd3, 0xdf, 0xf9, 0x1b, 0x94, 0x0a, 0x00, 0x00,
0x18, 0xf6, 0x24, 0x4d, 0x1d, 0xbf, 0x0e, 0x6d, 0x18, 0xf5, 0x60, 0x79, 0x8b, 0x09, 0x15, 0x82,
0x08, 0xa1, 0x2c, 0xca, 0x22, 0xbe, 0x84, 0x04, 0x4d, 0x17, 0x48, 0x28, 0x87, 0xd5, 0xac, 0x00,
0x81, 0xc4, 0x61, 0x6a, 0x0f, 0xad, 0xb5, 0x89, 0x6d, 0x79, 0x26, 0x15, 0xb9, 0xf0, 0x0f, 0x10,
0xfc, 0x16, 0xae, 0x1c, 0xb8, 0xee, 0x71, 0x8f, 0x1c, 0x51, 0xfb, 0x0f, 0xf8, 0x05, 0x68, 0x3e,
0xec, 0x38, 0xa9, 0x1d, 0x24, 0xb4, 0x12, 0xe2, 0x10, 0x69, 0xe6, 0x99, 0xe7, 0x1d, 0xbf, 0x1f,
0xcf, 0xfb, 0x4e, 0xe0, 0xad, 0xec, 0xc9, 0xe5, 0x7d, 0x1a, 0xce, 0xe5, 0x2f, 0xbc, 0xa2, 0xc9,
0x25, 0xe3, 0x72, 0x99, 0x5d, 0xdc, 0xcf, 0xf2, 0x54, 0xa4, 0xbc, 0x82, 0x8f, 0x14, 0x82, 0x6d,
0x9a, 0xac, 0xc4, 0x2a, 0x63, 0x27, 0xbf, 0x1d, 0x81, 0x73, 0x7a, 0xf6, 0xc5, 0x99, 0x3a, 0xc5,
0x03, 0x70, 0x45, 0xce, 0xd8, 0x94, 0xd1, 0x68, 0x16, 0x71, 0x0f, 0x0d, 0xda, 0x43, 0x87, 0x54,
0x21, 0x1c, 0x00, 0xd0, 0x70, 0x5e, 0x10, 0x5a, 0x8a, 0x50, 0x41, 0xf0, 0x6b, 0x70, 0xc0, 0x13,
0x9a, 0xf1, 0xab, 0x54, 0x4c, 0x28, 0x67, 0xb3, 0xc8, 0x6b, 0x0f, 0xd0, 0xd0, 0x21, 0x5b, 0x28,
0x7e, 0x1b, 0x6c, 0x1a, 0xce, 0x1f, 0x52, 0x41, 0xbd, 0xbd, 0x01, 0x1a, 0xba, 0x63, 0x7f, 0x64,
0x5c, 0x1a, 0x95, 0xee, 0xc8, 0x95, 0x64, 0x90, 0x82, 0x2a, 0xfd, 0x33, 0x71, 0x28, 0xcb, 0xce,
0x00, 0x0d, 0x7b, 0xa4, 0x0a, 0xe1, 0x11, 0xe0, 0x70, 0x99, 0xe7, 0x2c, 0x11, 0x84, 0xd1, 0xe8,
0x9c, 0xad, 0xa6, 0x94, 0x5f, 0x79, 0xfb, 0x03, 0x34, 0xdc, 0x23, 0x35, 0x27, 0xf8, 0x18, 0x1c,
0x11, 0x2f, 0x18, 0x17, 0x74, 0x91, 0x79, 0xf6, 0x00, 0x0d, 0xdb, 0x64, 0x0d, 0x60, 0x1f, 0xba,
0x71, 0xc4, 0x12, 0x11, 0x8b, 0x95, 0xd7, 0x55, 0x71, 0x94, 0x7b, 0xff, 0xd7, 0x36, 0x1c, 0x4a,
0x57, 0xd3, 0x44, 0xb0, 0x44, 0x7c, 0x45, 0xe7, 0x4b, 0x86, 0xdf, 0x01, 0x7b, 0xc9, 0x59, 0x7e,
0x1a, 0x45, 0x1e, 0x6a, 0x8c, 0xea, 0x4b, 0xcd, 0x98, 0x5a, 0xa4, 0x20, 0xe3, 0x8f, 0x00, 0xe4,
0x92, 0xb0, 0x45, 0x7a, 0xcd, 0xbc, 0x96, 0x32, 0x7d, 0xa9, 0xc1, 0x54, 0x93, 0xa6, 0x16, 0xa9,
0x98, 0xe0, 0xef, 0xe0, 0x48, 0xee, 0x1e, 0xb1, 0x7c, 0x11, 0x73, 0x1e, 0xa7, 0x89, 0x36, 0x50,
0xc9, 0x77, 0xc7, 0xaf, 0x37, 0x5c, 0xb5, 0x4d, 0x9f, 0x5a, 0xa4, 0xf6, 0x9a, 0xc2, 0xbf, 0x59,
0x72, 0x1d, 0x0b, 0x66, 0x0a, 0xd6, 0xe4, 0x9f, 0x26, 0x15, 0xfe, 0xe9, 0x1d, 0x7e, 0x1f, 0xba,
0x72, 0xf7, 0x79, 0x1a, 0x27, 0xaa, 0x6a, 0xee, 0xf8, 0x5e, 0x83, 0xb9, 0xa4, 0x4c, 0x2d, 0x52,
0xd2, 0xf1, 0x04, 0x5c, 0xb9, 0x3e, 0x4b, 0x93, 0xef, 0xe3, 0x7c, 0xa1, 0x4a, 0xe9, 0x8e, 0x83,
0x06, 0x6b, 0xc3, 0x9a, 0x5a, 0xa4, 0x6a, 0x34, 0xb1, 0xa1, 0x73, 0x2d, 0x0b, 0xe4, 0xff, 0x8c,
0xc0, 0x36, 0xaa, 0xc2, 0x1f, 0x83, 0x4b, 0xc3, 0xf9, 0x63, 0xa3, 0x4b, 0x53, 0xb0, 0xa0, 0x5e,
0x86, 0x05, 0x8b, 0x54, 0x4d, 0xf0, 0x44, 0x35, 0x83, 0x51, 0x80, 0x6a, 0x06, 0x77, 0x7c, 0x52,
0x7f, 0x41, 0x55, 0x26, 0xa4, 0x62, 0xe5, 0x7f, 0x0a, 0x6e, 0xe5, 0x7e, 0xfc, 0x2e, 0x74, 0xe5,
0x17, 0x04, 0x15, 0xcc, 0x78, 0x74, 0xaf, 0xc1, 0x23, 0x49, 0x21, 0x25, 0xd9, 0xff, 0xa9, 0x05,
0xdd, 0x02, 0xc6, 0xaf, 0xc2, 0x0b, 0xf9, 0x5a, 0xe4, 0x4c, 0x77, 0xf2, 0x1e, 0xd9, 0x04, 0xf1,
0x87, 0xba, 0xaa, 0xca, 0x84, 0x1b, 0xf7, 0x8f, 0x1b, 0x12, 0xab, 0x3f, 0x57, 0xe1, 0xe3, 0x09,
0xd8, 0xb1, 0x2a, 0x2e, 0xf7, 0xda, 0xca, 0x74, 0xb8, 0xc3, 0xd1, 0x91, 0xd6, 0x01, 0xff, 0x24,
0x11, 0xf9, 0x8a, 0x14, 0x86, 0xfe, 0x37, 0xd0, 0xab, 0x1e, 0xe0, 0x3e, 0xb4, 0x9f, 0xb0, 0x95,
0x0a, 0xdc, 0x21, 0x72, 0x89, 0x1f, 0x98, 0xca, 0xfd, 0x43, 0x53, 0xe8, 0x5b, 0x88, 0xe6, 0x7e,
0xd0, 0x7a, 0x0f, 0xf9, 0xb7, 0x08, 0x9c, 0xd2, 0xf1, 0x8d, 0x46, 0x46, 0x9b, 0x8d, 0x2c, 0x93,
0xc5, 0x92, 0x30, 0x5f, 0x65, 0x22, 0x4e, 0x93, 0x73, 0xb6, 0x52, 0x9f, 0xea, 0x91, 0x4d, 0x10,
0xbf, 0x09, 0x2f, 0x1a, 0x80, 0x45, 0x66, 0x80, 0xe8, 0xc0, 0x7b, 0xe4, 0xee, 0x01, 0x7e, 0x08,
0x6e, 0x56, 0x36, 0x11, 0x57, 0x1d, 0x73, 0x50, 0x2b, 0x8d, 0xcd, 0x36, 0xe4, 0xa4, 0x6a, 0x26,
0xc7, 0xdd, 0x8c, 0x1b, 0x0d, 0xb3, 0x48, 0x35, 0x4e, 0x97, 0x54, 0x21, 0xff, 0x77, 0x04, 0xb6,
0x99, 0x27, 0xff, 0xcf, 0x18, 0xfd, 0xcf, 0xc0, 0xad, 0x34, 0xee, 0xce, 0x20, 0x8e, 0xc1, 0x31,
0x03, 0x73, 0x16, 0xa9, 0x00, 0x1c, 0xb2, 0x06, 0xfc, 0xbf, 0x10, 0xc0, 0x5a, 0x0a, 0x78, 0x08,
0x87, 0x34, 0x0c, 0x59, 0x26, 0x1e, 0x2d, 0x2f, 0xe6, 0x71, 0x78, 0x6e, 0x64, 0xd5, 0x23, 0xdb,
0x30, 0x7e, 0x03, 0xfa, 0x26, 0xb8, 0x35, 0x55, 0xa7, 0xe7, 0x0e, 0xfe, 0x9f, 0xa8, 0xc0, 0x87,
0xae, 0x8e, 0x69, 0xa6, 0x25, 0xe0, 0x90, 0x72, 0xef, 0x3f, 0x45, 0xd0, 0x2d, 0xa6, 0xe6, 0x73,
0x10, 0x40, 0x99, 0xb4, 0xc7, 0xf1, 0x65, 0x42, 0xc5, 0x32, 0xd7, 0x2f, 0x48, 0x99, 0xb4, 0x12,
0xc6, 0x27, 0xd0, 0x5b, 0x8f, 0xf7, 0x59, 0xa4, 0x62, 0x73, 0xc8, 0x06, 0x56, 0x9f, 0xac, 0x4e,
0x43, 0xb2, 0xfc, 0xa5, 0x2e, 0x9f, 0x79, 0xd0, 0x76, 0xc5, 0x72, 0x0e, 0x87, 0x66, 0x90, 0x11,
0x96, 0xcd, 0x69, 0x58, 0x4e, 0xa0, 0x57, 0x6a, 0x52, 0x4b, 0x36, 0x98, 0x64, 0xdb, 0xd2, 0xff,
0x11, 0x0e, 0x36, 0x29, 0xcf, 0x21, 0x8d, 0x6b, 0x45, 0x95, 0xf1, 0x99, 0x3c, 0xde, 0xc1, 0xfd,
0x1f, 0xe0, 0xa8, 0xee, 0x29, 0xde, 0xe9, 0xc5, 0x96, 0xae, 0x5a, 0xff, 0x4a, 0x57, 0x27, 0xa7,
0x70, 0xb8, 0x75, 0x8e, 0x1d, 0xe8, 0x9c, 0x46, 0x8b, 0x38, 0xe9, 0x5b, 0x18, 0x60, 0xff, 0xeb,
0x3c, 0x16, 0x2c, 0xef, 0x23, 0xb9, 0x96, 0xee, 0xb2, 0xbc, 0xdf, 0xc2, 0x2e, 0xd8, 0xba, 0x44,
0x51, 0xbf, 0x3d, 0x79, 0xf9, 0xe9, 0x4d, 0x80, 0x9e, 0xdd, 0x04, 0xe8, 0xcf, 0x9b, 0x00, 0xfd,
0x72, 0x1b, 0x58, 0xcf, 0x6e, 0x03, 0xeb, 0x8f, 0xdb, 0xc0, 0xfa, 0xb6, 0xa3, 0xfe, 0x7f, 0x5e,
0xec, 0xab, 0xbf, 0x9b, 0x0f, 0xfe, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x12, 0x23, 0x4c, 0xb6, 0xa2,
0x0a, 0x00, 0x00,
}
func (m *ACLChange) Marshal() (dAtA []byte, err error) {

View File

@ -1,6 +1,6 @@
syntax = "proto3";
package anytype;
option go_package = "pb";
option go_package = "aclpb";
// the element of change tree used to store and internal apply smartBlock history
message ACLChange {

View File

@ -1,11 +1,11 @@
package aclchanges
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
)
type Change interface {
ProtoChange() *pb.ACLChange
ProtoChange() *aclpb.ACLChange
DecryptedChangeContent() []byte
Signature() []byte
CID() string

View File

@ -4,9 +4,10 @@ import (
"bytes"
"errors"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/textileio/go-threads/crypto/symmetric"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
"hash/fnv"
)
@ -19,38 +20,38 @@ var ErrUserAlreadyExists = errors.New("user already exists")
type ACLState struct {
currentReadKeyHash uint64
userReadKeys map[uint64]*symmetric.Key
userStates map[string]*pb.ACLChangeUserState
userInvites map[string]*pb.ACLChangeUserInvite
signingPubKeyDecoder keys.SigningPubKeyDecoder
encryptionKey keys.EncryptionPrivKey
userStates map[string]*aclpb.ACLChangeUserState
userInvites map[string]*aclpb.ACLChangeUserInvite
signingPubKeyDecoder signingkey.PubKeyDecoder
encryptionKey encryptionkey.PrivKey
identity string
}
func newACLState(
identity string,
encryptionKey keys.EncryptionPrivKey,
signingPubKeyDecoder keys.SigningPubKeyDecoder) *ACLState {
encryptionKey encryptionkey.PrivKey,
signingPubKeyDecoder signingkey.PubKeyDecoder) *ACLState {
return &ACLState{
identity: identity,
encryptionKey: encryptionKey,
userReadKeys: make(map[uint64]*symmetric.Key),
userStates: make(map[string]*pb.ACLChangeUserState),
userInvites: make(map[string]*pb.ACLChangeUserInvite),
userStates: make(map[string]*aclpb.ACLChangeUserState),
userInvites: make(map[string]*aclpb.ACLChangeUserInvite),
signingPubKeyDecoder: signingPubKeyDecoder,
}
}
func newACLStateFromSnapshotChange(
snapshotChange *pb.ACLChange,
snapshotChange *aclpb.ACLChange,
identity string,
encryptionKey keys.EncryptionPrivKey,
signingPubKeyDecoder keys.SigningPubKeyDecoder) (*ACLState, error) {
encryptionKey encryptionkey.PrivKey,
signingPubKeyDecoder signingkey.PubKeyDecoder) (*ACLState, error) {
st := &ACLState{
identity: identity,
encryptionKey: encryptionKey,
userReadKeys: make(map[uint64]*symmetric.Key),
userStates: make(map[string]*pb.ACLChangeUserState),
userInvites: make(map[string]*pb.ACLChangeUserInvite),
userStates: make(map[string]*aclpb.ACLChangeUserState),
userInvites: make(map[string]*aclpb.ACLChangeUserInvite),
signingPubKeyDecoder: signingPubKeyDecoder,
}
err := st.recreateFromSnapshotChange(snapshotChange)
@ -60,7 +61,7 @@ func newACLStateFromSnapshotChange(
return st, nil
}
func (st *ACLState) recreateFromSnapshotChange(snapshotChange *pb.ACLChange) error {
func (st *ACLState) recreateFromSnapshotChange(snapshotChange *aclpb.ACLChange) error {
snapshot := snapshotChange.GetAclData().GetAclSnapshot()
if snapshot == nil {
return fmt.Errorf("could not create state from snapshot, because it is nil")
@ -89,20 +90,20 @@ func (st *ACLState) recreateFromSnapshotChange(snapshotChange *pb.ACLChange) err
return nil
}
func (st *ACLState) makeSnapshot() *pb.ACLChangeACLSnapshot {
var userStates []*pb.ACLChangeUserState
func (st *ACLState) makeSnapshot() *aclpb.ACLChangeACLSnapshot {
var userStates []*aclpb.ACLChangeUserState
for _, st := range st.userStates {
userStates = append(userStates, st)
}
return &pb.ACLChangeACLSnapshot{AclState: &pb.ACLChangeACLState{
return &aclpb.ACLChangeACLSnapshot{AclState: &aclpb.ACLChangeACLState{
ReadKeyHashes: nil,
UserStates: userStates, // TODO: make states and invites in same format
Invites: st.userInvites,
}}
}
func (st *ACLState) applyChange(change *pb.ACLChange) (err error) {
func (st *ACLState) applyChange(change *aclpb.ACLChange) (err error) {
defer func() {
if err != nil {
return
@ -120,7 +121,7 @@ func (st *ACLState) applyChange(change *pb.ACLChange) (err error) {
return
}
if !st.hasPermission(change.Identity, pb.ACLChange_Admin) {
if !st.hasPermission(change.Identity, aclpb.ACLChange_Admin) {
err = fmt.Errorf("user %s must have admin permissions", change.Identity)
return
}
@ -137,7 +138,7 @@ func (st *ACLState) applyChange(change *pb.ACLChange) (err error) {
}
// TODO: remove changeId, because it is not needed
func (st *ACLState) applyChangeContent(ch *pb.ACLChangeACLContentValue) error {
func (st *ACLState) applyChangeContent(ch *aclpb.ACLChangeACLContentValue) error {
switch {
case ch.GetUserPermissionChange() != nil:
return st.applyUserPermissionChange(ch.GetUserPermissionChange())
@ -156,7 +157,7 @@ func (st *ACLState) applyChangeContent(ch *pb.ACLChangeACLContentValue) error {
}
}
func (st *ACLState) applyUserPermissionChange(ch *pb.ACLChangeUserPermissionChange) error {
func (st *ACLState) applyUserPermissionChange(ch *aclpb.ACLChangeUserPermissionChange) error {
if _, exists := st.userStates[ch.Identity]; !exists {
return ErrNoSuchUser
}
@ -165,12 +166,12 @@ func (st *ACLState) applyUserPermissionChange(ch *pb.ACLChangeUserPermissionChan
return nil
}
func (st *ACLState) applyUserInvite(ch *pb.ACLChangeUserInvite) error {
func (st *ACLState) applyUserInvite(ch *aclpb.ACLChangeUserInvite) error {
st.userInvites[ch.InviteId] = ch
return nil
}
func (st *ACLState) applyUserJoin(ch *pb.ACLChangeUserJoin) error {
func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error {
invite, exists := st.userInvites[ch.UserInviteId]
if !exists {
return fmt.Errorf("no such invite with id %s", ch.UserInviteId)
@ -213,7 +214,7 @@ func (st *ACLState) applyUserJoin(ch *pb.ACLChangeUserJoin) error {
}
// adding user to the list
userState := &pb.ACLChangeUserState{
userState := &aclpb.ACLChangeUserState{
Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey,
EncryptedReadKeys: ch.EncryptedReadKeys,
@ -224,12 +225,12 @@ func (st *ACLState) applyUserJoin(ch *pb.ACLChangeUserJoin) error {
return nil
}
func (st *ACLState) applyUserAdd(ch *pb.ACLChangeUserAdd) error {
func (st *ACLState) applyUserAdd(ch *aclpb.ACLChangeUserAdd) error {
if _, exists := st.userStates[ch.Identity]; exists {
return ErrUserAlreadyExists
}
st.userStates[ch.Identity] = &pb.ACLChangeUserState{
st.userStates[ch.Identity] = &aclpb.ACLChangeUserState{
Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey,
Permissions: ch.Permissions,
@ -250,7 +251,7 @@ func (st *ACLState) applyUserAdd(ch *pb.ACLChangeUserAdd) error {
return nil
}
func (st *ACLState) applyUserRemove(ch *pb.ACLChangeUserRemove) error {
func (st *ACLState) applyUserRemove(ch *aclpb.ACLChangeUserRemove) error {
if ch.Identity == st.identity {
return ErrDocumentForbidden
}
@ -282,7 +283,7 @@ func (st *ACLState) applyUserRemove(ch *pb.ACLChangeUserRemove) error {
return nil
}
func (st *ACLState) applyUserConfirm(ch *pb.ACLChangeUserConfirm) error {
func (st *ACLState) applyUserConfirm(ch *aclpb.ACLChangeUserConfirm) error {
if _, exists := st.userStates[ch.Identity]; !exists {
return ErrNoSuchUser
}
@ -308,7 +309,7 @@ func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, e
return key, hasher.Sum64(), nil
}
func (st *ACLState) hasPermission(identity string, permission pb.ACLChangeUserPermissions) bool {
func (st *ACLState) hasPermission(identity string, permission aclpb.ACLChangeUserPermissions) bool {
state, exists := st.userStates[identity]
if !exists {
return false
@ -317,18 +318,18 @@ func (st *ACLState) hasPermission(identity string, permission pb.ACLChangeUserPe
return state.Permissions == permission
}
func (st *ACLState) isUserJoin(ch *pb.ACLChange) bool {
func (st *ACLState) isUserJoin(ch *aclpb.ACLChange) bool {
// if we have a UserJoin, then it should always be the first one applied
return ch.AclData.GetAclContent() != nil && ch.AclData.GetAclContent()[0].GetUserJoin() != nil
}
func (st *ACLState) isUserAdd(ch *pb.ACLChange) bool {
func (st *ACLState) isUserAdd(ch *aclpb.ACLChange) bool {
// if we have a UserAdd, then it should always be the first one applied
userAdd := ch.AclData.GetAclContent()[0].GetUserAdd()
return ch.AclData.GetAclContent() != nil && userAdd != nil && userAdd.GetIdentity() == ch.Identity
}
func (st *ACLState) getPermissionDecreasedUsers(ch *pb.ACLChange) (identities []*pb.ACLChangeUserPermissionChange) {
func (st *ACLState) getPermissionDecreasedUsers(ch *aclpb.ACLChange) (identities []*aclpb.ACLChangeUserPermissionChange) {
// this should be called after general checks are completed
if ch.GetAclData().GetAclContent() == nil {
return nil
@ -342,7 +343,7 @@ func (st *ACLState) getPermissionDecreasedUsers(ch *pb.ACLChange) (identities []
currentState := st.userStates[content.Identity]
// the comparison works in different direction :-)
if content.Permissions > currentState.Permissions {
identities = append(identities, &pb.ACLChangeUserPermissionChange{
identities = append(identities, &aclpb.ACLChangeUserPermissionChange{
Identity: content.Identity,
Permissions: content.Permissions,
})
@ -350,9 +351,9 @@ func (st *ACLState) getPermissionDecreasedUsers(ch *pb.ACLChange) (identities []
}
if c.GetUserRemove() != nil {
content := c.GetUserRemove()
identities = append(identities, &pb.ACLChangeUserPermissionChange{
identities = append(identities, &aclpb.ACLChangeUserPermissionChange{
Identity: content.Identity,
Permissions: pb.ACLChange_Removed,
Permissions: aclpb.ACLChange_Removed,
})
}
}
@ -404,7 +405,7 @@ func (st *ACLState) equal(other *ACLState) bool {
return true
}
func (st *ACLState) GetUserStates() map[string]*pb.ACLChangeUserState {
func (st *ACLState) GetUserStates() map[string]*aclpb.ACLChangeUserState {
// TODO: we should provide better API that would not allow to change this map from the outside
return st.userStates
}

View File

@ -3,24 +3,24 @@ package acltree
import (
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
)
type aclStateBuilder struct {
tree *Tree
identity string
key keys.EncryptionPrivKey
decoder keys.SigningPubKeyDecoder
key encryptionkey.PrivKey
decoder signingkey.PubKeyDecoder
}
type decreasedPermissionsParameters struct {
users []*pb.ACLChangeUserPermissionChange
users []*aclpb.ACLChangeUserPermissionChange
startChange string
}
func newACLStateBuilder(decoder keys.SigningPubKeyDecoder, accountData *account.AccountData) *aclStateBuilder {
func newACLStateBuilder(decoder signingkey.PubKeyDecoder, accountData *account.AccountData) *aclStateBuilder {
return &aclStateBuilder{
decoder: decoder,
identity: accountData.Identity,
@ -115,7 +115,7 @@ func (sb *aclStateBuilder) BuildBefore(beforeId string) (*ACLState, bool, error)
}
// the user can't make changes
if !state.hasPermission(c.Content.Identity, pb.ACLChange_Writer) && !state.hasPermission(c.Content.Identity, pb.ACLChange_Admin) {
if !state.hasPermission(c.Content.Identity, aclpb.ACLChange_Writer) && !state.hasPermission(c.Content.Identity, aclpb.ACLChange_Admin) {
err = fmt.Errorf("user %s cannot make changes", c.Content.Identity)
return false
}
@ -155,7 +155,7 @@ func (sb *aclStateBuilder) BuildBefore(beforeId string) (*ACLState, bool, error)
// if we find some invalid changes
if _, exists := validChanges[seen.Id]; !exists {
// if the user didn't have enough permission to make changes
if seen.IsACLChange() || permChange.Permissions > pb.ACLChange_Writer {
if seen.IsACLChange() || permChange.Permissions > aclpb.ACLChange_Writer {
removed = true
sb.tree.RemoveInvalidChange(seen.Id)
}

View File

@ -1,11 +1,10 @@
package acltree
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"sync"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
)
type AddResultSummary int
@ -30,8 +29,8 @@ type TreeUpdateListener interface {
type ACLTree interface {
ACLState() *ACLState
AddContent(f func(builder ChangeBuilder) error) (*Change, error)
AddChanges(changes ...*Change) (AddResult, error)
AddContent(ctx context.Context, f func(builder ChangeBuilder) error) (*Change, error)
AddChanges(ctx context.Context, changes ...*Change) (AddResult, error)
Heads() []string
Root() *Change
Iterate(func(change *Change) bool)
@ -40,7 +39,7 @@ type ACLTree interface {
}
type aclTree struct {
thread thread.Thread
treeStorage treestorage.TreeStorage
accountData *account.AccountData
updateListener TreeUpdateListener
@ -58,18 +57,17 @@ type aclTree struct {
}
func BuildACLTree(
t thread.Thread,
t treestorage.TreeStorage,
acc *account.AccountData,
listener TreeUpdateListener) (ACLTree, error) {
decoder := keys.NewEd25519Decoder()
aclTreeBuilder := newACLTreeBuilder(t, decoder)
treeBuilder := newTreeBuilder(t, decoder)
snapshotValidator := newSnapshotValidator(decoder, acc)
aclStateBuilder := newACLStateBuilder(decoder, acc)
aclTreeBuilder := newACLTreeBuilder(t, acc.Decoder)
treeBuilder := newTreeBuilder(t, acc.Decoder)
snapshotValidator := newSnapshotValidator(acc.Decoder, acc) // TODO: this looks weird, change it
aclStateBuilder := newACLStateBuilder(acc.Decoder, acc)
changeBuilder := newChangeBuilder()
aclTree := &aclTree{
thread: t,
treeStorage: t,
accountData: acc,
fullTree: nil,
aclState: nil,
@ -80,12 +78,19 @@ func BuildACLTree(
changeBuilder: changeBuilder,
updateListener: listener,
}
err := aclTree.rebuildFromThread(false)
err := aclTree.rebuildFromStorage(false)
if err != nil {
return nil, err
}
aclTree.removeOrphans()
t.SetHeads(aclTree.Heads())
err = aclTree.removeOrphans()
if err != nil {
return nil, err
}
err = t.SetHeads(aclTree.Heads())
if err != nil {
return nil, err
}
listener.Rebuild(aclTree)
return aclTree, nil
@ -104,7 +109,7 @@ func BuildACLTree(
// return err
// }
// if !valid {
// return a.rebuildFromThread(true)
// return a.rebuildFromStorage(true)
// }
// }
//
@ -121,11 +126,15 @@ func BuildACLTree(
// return nil
//}
func (a *aclTree) removeOrphans() {
func (a *aclTree) removeOrphans() error {
// removing attached or invalid orphans
var toRemove []string
for _, orphan := range a.thread.Orphans() {
orphans, err := a.treeStorage.Orphans()
if err != nil {
return err
}
for _, orphan := range orphans {
if _, exists := a.fullTree.attached[orphan]; exists {
toRemove = append(toRemove, orphan)
}
@ -133,10 +142,10 @@ func (a *aclTree) removeOrphans() {
toRemove = append(toRemove, orphan)
}
}
a.thread.RemoveOrphans(toRemove...)
return a.treeStorage.RemoveOrphans(toRemove...)
}
func (a *aclTree) rebuildFromThread(fromStart bool) error {
func (a *aclTree) rebuildFromStorage(fromStart bool) error {
a.treeBuilder.Init()
a.aclTreeBuilder.Init()
@ -163,7 +172,7 @@ func (a *aclTree) rebuildFromThread(fromStart bool) error {
return err
}
if !valid {
return a.rebuildFromThread(true)
return a.rebuildFromStorage(true)
}
}
// TODO: there is a question how we can validate not only that the full tree is built correctly
@ -189,7 +198,7 @@ func (a *aclTree) ACLState() *ACLState {
return a.aclState
}
func (a *aclTree) AddContent(build func(builder ChangeBuilder) error) (*Change, error) {
func (a *aclTree) AddContent(ctx context.Context, build func(builder ChangeBuilder) error) (*Change, error) {
// TODO: add snapshot creation logic
a.Lock()
defer func() {
@ -210,7 +219,7 @@ func (a *aclTree) AddContent(build func(builder ChangeBuilder) error) (*Change,
}
a.fullTree.AddFast(ch)
err = a.thread.AddRawChange(&thread.RawChange{
err = a.treeStorage.AddRawChange(&treestorage.RawChange{
Payload: marshalled,
Signature: ch.Signature(),
Id: ch.Id,
@ -219,11 +228,14 @@ func (a *aclTree) AddContent(build func(builder ChangeBuilder) error) (*Change,
return nil, err
}
a.thread.SetHeads([]string{ch.Id})
err = a.treeStorage.SetHeads([]string{ch.Id})
if err != nil {
return nil, err
}
return ch, nil
}
func (a *aclTree) AddChanges(changes ...*Change) (AddResult, error) {
func (a *aclTree) AddChanges(ctx context.Context, changes ...*Change) (AddResult, error) {
a.Lock()
// TODO: make proper error handling, because there are a lot of corner cases where this will break
var err error
@ -233,8 +245,17 @@ func (a *aclTree) AddChanges(changes ...*Change) (AddResult, error) {
if err != nil {
return
}
a.removeOrphans()
a.thread.SetHeads(a.fullTree.Heads())
err = a.removeOrphans()
if err != nil {
return
}
err = a.treeStorage.SetHeads(a.fullTree.Heads())
if err != nil {
return
}
a.Unlock()
switch mode {
case Append:
@ -247,11 +268,14 @@ func (a *aclTree) AddChanges(changes ...*Change) (AddResult, error) {
}()
for _, ch := range changes {
err = a.thread.AddChange(ch)
err = a.treeStorage.AddChange(ch)
if err != nil {
return AddResult{}, err
}
err = a.treeStorage.AddOrphans(ch.Id)
if err != nil {
return AddResult{}, err
}
a.thread.AddOrphans(ch.Id)
}
prevHeads := a.fullTree.Heads()
@ -265,7 +289,7 @@ func (a *aclTree) AddChanges(changes ...*Change) (AddResult, error) {
}, nil
case Rebuild:
err = a.rebuildFromThread(false)
err = a.rebuildFromStorage(false)
if err != nil {
return AddResult{}, err
}
@ -276,7 +300,7 @@ func (a *aclTree) AddChanges(changes ...*Change) (AddResult, error) {
Summary: AddResultSummaryRebuild,
}, nil
default:
// just rebuilding the state from start without reloading everything from thread
// just rebuilding the state from start without reloading everything from tree storage
// as an optimization we could've started from current heads, but I didn't implement that
a.aclState, err = a.aclStateBuilder.Build()
if err != nil {

View File

@ -1,9 +1,11 @@
package acltree
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/threadbuilder"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/treestoragebuilder"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"testing"
"github.com/stretchr/testify/assert"
@ -16,7 +18,7 @@ func (m *mockListener) Update(tree ACLTree) {}
func (m *mockListener) Rebuild(tree ACLTree) {}
func TestACLTree_UserJoinBuild(t *testing.T) {
thr, err := threadbuilder.NewThreadBuilderWithTestName("userjoinexample.yml")
thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userjoinexample.yml")
if err != nil {
t.Fatal(err)
}
@ -25,6 +27,7 @@ func TestACLTree_UserJoinBuild(t *testing.T) {
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
listener := &mockListener{}
tree, err := BuildACLTree(thr, accountData, listener)
@ -37,9 +40,9 @@ func TestACLTree_UserJoinBuild(t *testing.T) {
cId := keychain.GeneratedIdentities["C"]
assert.Equal(t, aclState.identity, aId)
assert.Equal(t, aclState.userStates[aId].Permissions, pb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[bId].Permissions, pb.ACLChange_Writer)
assert.Equal(t, aclState.userStates[cId].Permissions, pb.ACLChange_Reader)
assert.Equal(t, aclState.userStates[aId].Permissions, aclpb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[bId].Permissions, aclpb.ACLChange_Writer)
assert.Equal(t, aclState.userStates[cId].Permissions, aclpb.ACLChange_Reader)
var changeIds []string
tree.Iterate(func(c *Change) (isContinue bool) {
@ -50,7 +53,7 @@ func TestACLTree_UserJoinBuild(t *testing.T) {
}
func TestACLTree_UserJoinUpdate_Append(t *testing.T) {
thr, err := threadbuilder.NewThreadBuilderWithTestName("userjoinexampleupdate.yml")
thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userjoinexampleupdate.yml")
if err != nil {
t.Fatal(err)
}
@ -59,6 +62,7 @@ func TestACLTree_UserJoinUpdate_Append(t *testing.T) {
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
listener := &mockListener{}
tree, err := BuildACLTree(thr, accountData, listener)
@ -75,7 +79,7 @@ func TestACLTree_UserJoinUpdate_Append(t *testing.T) {
changes = append(changes, newCh)
}
res, err := tree.AddChanges(changes...)
res, err := tree.AddChanges(context.Background(), changes...)
assert.Equal(t, res.Summary, AddResultSummaryAppend)
aclState := tree.ACLState()
@ -85,10 +89,10 @@ func TestACLTree_UserJoinUpdate_Append(t *testing.T) {
dId := keychain.GeneratedIdentities["D"]
assert.Equal(t, aclState.identity, aId)
assert.Equal(t, aclState.userStates[aId].Permissions, pb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[bId].Permissions, pb.ACLChange_Writer)
assert.Equal(t, aclState.userStates[cId].Permissions, pb.ACLChange_Reader)
assert.Equal(t, aclState.userStates[dId].Permissions, pb.ACLChange_Writer)
assert.Equal(t, aclState.userStates[aId].Permissions, aclpb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[bId].Permissions, aclpb.ACLChange_Writer)
assert.Equal(t, aclState.userStates[cId].Permissions, aclpb.ACLChange_Reader)
assert.Equal(t, aclState.userStates[dId].Permissions, aclpb.ACLChange_Writer)
var changeIds []string
tree.Iterate(func(c *Change) (isContinue bool) {
@ -99,7 +103,7 @@ func TestACLTree_UserJoinUpdate_Append(t *testing.T) {
}
func TestACLTree_UserJoinUpdate_Rebuild(t *testing.T) {
thr, err := threadbuilder.NewThreadBuilderWithTestName("userjoinexampleupdate.yml")
thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userjoinexampleupdate.yml")
if err != nil {
t.Fatal(err)
}
@ -108,6 +112,7 @@ func TestACLTree_UserJoinUpdate_Rebuild(t *testing.T) {
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
listener := &mockListener{}
tree, err := BuildACLTree(thr, accountData, listener)
@ -124,7 +129,7 @@ func TestACLTree_UserJoinUpdate_Rebuild(t *testing.T) {
changes = append(changes, newCh)
}
res, err := tree.AddChanges(changes...)
res, err := tree.AddChanges(context.Background(), changes...)
assert.Equal(t, res.Summary, AddResultSummaryRebuild)
aclState := tree.ACLState()
@ -134,10 +139,10 @@ func TestACLTree_UserJoinUpdate_Rebuild(t *testing.T) {
dId := keychain.GeneratedIdentities["D"]
assert.Equal(t, aclState.identity, aId)
assert.Equal(t, aclState.userStates[aId].Permissions, pb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[bId].Permissions, pb.ACLChange_Writer)
assert.Equal(t, aclState.userStates[cId].Permissions, pb.ACLChange_Reader)
assert.Equal(t, aclState.userStates[dId].Permissions, pb.ACLChange_Writer)
assert.Equal(t, aclState.userStates[aId].Permissions, aclpb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[bId].Permissions, aclpb.ACLChange_Writer)
assert.Equal(t, aclState.userStates[cId].Permissions, aclpb.ACLChange_Reader)
assert.Equal(t, aclState.userStates[dId].Permissions, aclpb.ACLChange_Writer)
var changeIds []string
@ -149,7 +154,7 @@ func TestACLTree_UserJoinUpdate_Rebuild(t *testing.T) {
}
func TestACLTree_UserRemoveBuild(t *testing.T) {
thr, err := threadbuilder.NewThreadBuilderWithTestName("userremoveexample.yml")
thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userremoveexample.yml")
if err != nil {
t.Fatal(err)
}
@ -158,6 +163,7 @@ func TestACLTree_UserRemoveBuild(t *testing.T) {
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
listener := &mockListener{}
tree, err := BuildACLTree(thr, accountData, listener)
@ -168,7 +174,7 @@ func TestACLTree_UserRemoveBuild(t *testing.T) {
aId := keychain.GeneratedIdentities["A"]
assert.Equal(t, aclState.identity, aId)
assert.Equal(t, aclState.userStates[aId].Permissions, pb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[aId].Permissions, aclpb.ACLChange_Admin)
var changeIds []string
tree.Iterate(func(c *Change) (isContinue bool) {
@ -179,7 +185,7 @@ func TestACLTree_UserRemoveBuild(t *testing.T) {
}
func TestACLTree_UserRemoveBeforeBuild(t *testing.T) {
thr, err := threadbuilder.NewThreadBuilderWithTestName("userremovebeforeexample.yml")
thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userremovebeforeexample.yml")
if err != nil {
t.Fatal(err)
}
@ -188,6 +194,7 @@ func TestACLTree_UserRemoveBeforeBuild(t *testing.T) {
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
listener := &mockListener{}
tree, err := BuildACLTree(thr, accountData, listener)
@ -196,7 +203,7 @@ func TestACLTree_UserRemoveBeforeBuild(t *testing.T) {
}
aclState := tree.ACLState()
for _, s := range []string{"A", "C", "E"} {
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, aclpb.ACLChange_Admin)
}
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))
assert.Nil(t, aclState.userStates[keychain.GetIdentity("B")])
@ -210,7 +217,7 @@ func TestACLTree_UserRemoveBeforeBuild(t *testing.T) {
}
func TestACLTree_InvalidSnapshotBuild(t *testing.T) {
thr, err := threadbuilder.NewThreadBuilderWithTestName("invalidsnapshotexample.yml")
thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("invalidsnapshotexample.yml")
if err != nil {
t.Fatal(err)
}
@ -219,6 +226,7 @@ func TestACLTree_InvalidSnapshotBuild(t *testing.T) {
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
listener := &mockListener{}
tree, err := BuildACLTree(thr, accountData, listener)
@ -227,7 +235,7 @@ func TestACLTree_InvalidSnapshotBuild(t *testing.T) {
}
aclState := tree.ACLState()
for _, s := range []string{"A", "B", "C", "D", "E", "F"} {
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, aclpb.ACLChange_Admin)
}
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))
@ -240,7 +248,7 @@ func TestACLTree_InvalidSnapshotBuild(t *testing.T) {
}
func TestACLTree_ValidSnapshotBuild(t *testing.T) {
thr, err := threadbuilder.NewThreadBuilderWithTestName("validsnapshotexample.yml")
thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("validsnapshotexample.yml")
if err != nil {
t.Fatal(err)
}
@ -249,6 +257,7 @@ func TestACLTree_ValidSnapshotBuild(t *testing.T) {
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
listener := &mockListener{}
tree, err := BuildACLTree(thr, accountData, listener)
@ -257,7 +266,7 @@ func TestACLTree_ValidSnapshotBuild(t *testing.T) {
}
aclState := tree.ACLState()
for _, s := range []string{"A", "B", "C", "D", "E", "F"} {
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, aclpb.ACLChange_Admin)
}
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))

View File

@ -2,26 +2,26 @@ package acltree
import (
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
)
type aclTreeBuilder struct {
cache map[string]*Change
identityKeys map[string]keys.SigningPubKey
signingPubKeyDecoder keys.SigningPubKeyDecoder
identityKeys map[string]signingkey.PubKey
signingPubKeyDecoder signingkey.PubKeyDecoder
tree *Tree
thread thread.Thread
treeStorage treestorage.TreeStorage
*changeLoader
}
func newACLTreeBuilder(t thread.Thread, decoder keys.SigningPubKeyDecoder) *aclTreeBuilder {
func newACLTreeBuilder(t treestorage.TreeStorage, decoder signingkey.PubKeyDecoder) *aclTreeBuilder {
return &aclTreeBuilder{
signingPubKeyDecoder: decoder,
thread: t,
treeStorage: t,
changeLoader: newChangeLoader(
t,
decoder,
@ -31,15 +31,23 @@ func newACLTreeBuilder(t thread.Thread, decoder keys.SigningPubKeyDecoder) *aclT
func (tb *aclTreeBuilder) Init() {
tb.cache = make(map[string]*Change)
tb.identityKeys = make(map[string]keys.SigningPubKey)
tb.identityKeys = make(map[string]signingkey.PubKey)
tb.tree = &Tree{}
tb.changeLoader.Init(tb.cache, tb.identityKeys)
}
func (tb *aclTreeBuilder) Build() (*Tree, error) {
var headsAndOrphans []string
headsAndOrphans = append(headsAndOrphans, tb.thread.Orphans()...)
headsAndOrphans = append(headsAndOrphans, tb.thread.Heads()...)
orphans, err := tb.treeStorage.Orphans()
if err != nil {
return nil, err
}
heads, err := tb.treeStorage.Heads()
if err != nil {
return nil, err
}
headsAndOrphans = append(headsAndOrphans, orphans...)
headsAndOrphans = append(headsAndOrphans, heads...)
aclHeads, err := tb.getACLHeads(headsAndOrphans)
if err != nil {
@ -94,7 +102,11 @@ func (tb *aclTreeBuilder) dfsFromStart(heads []string) (buf []*Change, root *Cha
possibleRoots = append(possibleRoots, ch)
}
}
header := tb.thread.Header()
header, err := tb.treeStorage.Header()
if err != nil {
return nil, nil, err
}
for _, r := range possibleRoots {
if r.Id == header.FirstChangeId {
return buf, r, nil
@ -123,7 +135,7 @@ func (tb *aclTreeBuilder) getACLHeads(heads []string) (aclTreeHeads []string, er
}
if len(aclTreeHeads) == 0 {
return nil, fmt.Errorf("no usable ACL heads in thread")
return nil, fmt.Errorf("no usable ACL heads in tree storage")
}
return aclTreeHeads, nil
}

View File

@ -2,17 +2,17 @@ package acltree
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
)
func BuildThreadWithACL(
func BuildTreeStorageWithACL(
acc *account.AccountData,
build func(builder ChangeBuilder) error,
create func(change *thread.RawChange) (thread.Thread, error)) (thread.Thread, error) {
create func(change *treestorage.RawChange) (treestorage.TreeStorage, error)) (treestorage.TreeStorage, error) {
bld := newChangeBuilder()
bld.Init(
newACLState(acc.Identity, acc.EncKey, keys.NewEd25519Decoder()),
newACLState(acc.Identity, acc.EncKey, signingkey.NewEd25519Decoder()),
&Tree{},
acc)
err := build(bld)
@ -26,7 +26,7 @@ func BuildThreadWithACL(
return nil, err
}
rawChange := &thread.RawChange{
rawChange := &treestorage.RawChange{
Payload: payload,
Signature: change.Signature(),
Id: change.CID(),
@ -37,6 +37,9 @@ func BuildThreadWithACL(
return nil, err
}
thr.SetHeads([]string{change.CID()})
err = thr.SetHeads([]string{change.CID()})
if err != nil {
return nil, err
}
return thr, nil
}

View File

@ -3,15 +3,15 @@ package acltree
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/threadbuilder"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/treestoragebuilder"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"github.com/stretchr/testify/assert"
"testing"
)
func TestBuildThreadWithACL(t *testing.T) {
keychain := threadbuilder.NewKeychain()
func Test_BuildTreeStorageWithACL(t *testing.T) {
keychain := treestoragebuilder.NewKeychain()
keychain.AddSigningKey("A")
keychain.AddEncryptionKey("A")
data := &account.AccountData{
@ -19,27 +19,39 @@ func TestBuildThreadWithACL(t *testing.T) {
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
}
thr, err := BuildThreadWithACL(
thr, err := BuildTreeStorageWithACL(
data,
func(builder ChangeBuilder) error {
return builder.UserAdd(
keychain.GetIdentity("A"),
keychain.EncryptionKeys["A"].GetPublic(),
pb.ACLChange_Admin)
aclpb.ACLChange_Admin)
},
thread.NewInMemoryThread)
treestorage.NewInMemoryTreeStorage)
if err != nil {
t.Fatalf("build should not return error")
}
if len(thr.Heads()) == 0 {
t.Fatalf("thread should have non-empty heads")
heads, err := thr.Heads()
if err != nil {
t.Fatalf("should return heads: %v", err)
}
if thr.Header() == nil {
t.Fatalf("thread should have non-empty header")
if len(heads) == 0 {
t.Fatalf("tree storage should have non-empty heads")
}
assert.Equal(t, thr.Heads()[0], thr.Header().FirstChangeId)
assert.NotEmpty(t, thr.ID())
ch, err := thr.GetChange(context.Background(), thr.Header().FirstChangeId)
header, err := thr.Header()
if err != nil {
t.Fatalf("tree storage header should return without error: %v", err)
}
assert.Equal(t, heads[0], header.FirstChangeId)
treeId, err := thr.TreeID()
if err != nil {
t.Fatalf("tree id should return without error: %v", err)
}
assert.NotEmpty(t, treeId)
ch, err := thr.GetChange(context.Background(), header.FirstChangeId)
if err != nil {
t.Fatalf("get change should not return error: %v", err)
}

View File

@ -2,16 +2,16 @@ package acltree
import (
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"github.com/gogo/protobuf/proto"
"github.com/textileio/go-threads/crypto/symmetric"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
)
type ChangeContent struct {
ChangesData proto.Marshaler
ACLData *pb.ACLChangeACLData
ACLData *aclpb.ACLChangeACLData
Id string // TODO: this is just for testing, because id should be created automatically from content
}
@ -25,7 +25,7 @@ type Change struct {
IsSnapshot bool
DecryptedDocumentChange []byte
Content *pb.ACLChange
Content *aclpb.ACLChange
Sign []byte
}
@ -47,8 +47,8 @@ func (ch *Change) IsACLChange() bool {
return ch.Content.GetAclData() != nil
}
func NewFromRawChange(rawChange *thread.RawChange) (*Change, error) {
unmarshalled := &pb.ACLChange{}
func NewFromRawChange(rawChange *treestorage.RawChange) (*Change, error) {
unmarshalled := &aclpb.ACLChange{}
err := proto.Unmarshal(rawChange.Payload, unmarshalled)
if err != nil {
return nil, err
@ -59,7 +59,7 @@ func NewFromRawChange(rawChange *thread.RawChange) (*Change, error) {
return ch, nil
}
func NewChange(id string, ch *pb.ACLChange) *Change {
func NewChange(id string, ch *aclpb.ACLChange) *Change {
return &Change{
Next: nil,
PreviousIds: ch.TreeHeadIds,
@ -70,7 +70,7 @@ func NewChange(id string, ch *pb.ACLChange) *Change {
}
}
func NewACLChange(id string, ch *pb.ACLChange) *Change {
func NewACLChange(id string, ch *aclpb.ACLChange) *Change {
return &Change{
Next: nil,
PreviousIds: ch.AclHeadIds,
@ -81,7 +81,7 @@ func NewACLChange(id string, ch *pb.ACLChange) *Change {
}
}
func (ch *Change) ProtoChange() *pb.ACLChange {
func (ch *Change) ProtoChange() *aclpb.ACLChange {
return ch.Content
}

View File

@ -2,11 +2,11 @@ package acltree
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
"github.com/gogo/protobuf/proto"
"github.com/textileio/go-threads/crypto/symmetric"
"hash/fnv"
"time"
)
@ -14,7 +14,7 @@ import (
type MarshalledChange = []byte
type ACLChangeBuilder interface {
UserAdd(identity string, encryptionKey keys.EncryptionPubKey, permissions pb.ACLChangeUserPermissions) error
UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLChangeUserPermissions) error
AddId(id string) // TODO: this is only for testing
SetMakeSnapshot(bool) // TODO: who should decide this? probably ACLTree so we can delete it
}
@ -29,7 +29,7 @@ type changeBuilder struct {
tree *Tree
acc *account.AccountData
aclData *pb.ACLChangeACLData
aclData *aclpb.ACLChangeACLData
changeContent proto.Marshaler
id string
makeSnapshot bool
@ -46,7 +46,7 @@ func (c *changeBuilder) Init(state *ACLState, tree *Tree, acc *account.AccountDa
c.tree = tree
c.acc = acc
c.aclData = &pb.ACLChangeACLData{}
c.aclData = &aclpb.ACLChangeACLData{}
// setting read key for further encryption etc
if state.currentReadKeyHash == 0 {
c.readKey, _ = symmetric.NewRandom()
@ -68,7 +68,7 @@ func (c *changeBuilder) SetMakeSnapshot(b bool) {
c.makeSnapshot = b
}
func (c *changeBuilder) UserAdd(identity string, encryptionKey keys.EncryptionPubKey, permissions pb.ACLChangeUserPermissions) error {
func (c *changeBuilder) UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLChangeUserPermissions) error {
var allKeys []*symmetric.Key
if c.aclState.currentReadKeyHash != 0 {
for _, key := range c.aclState.userReadKeys {
@ -91,9 +91,9 @@ func (c *changeBuilder) UserAdd(identity string, encryptionKey keys.EncryptionPu
if err != nil {
return err
}
ch := &pb.ACLChangeACLContentValue{
Value: &pb.ACLChangeACLContentValueValueOfUserAdd{
UserAdd: &pb.ACLChangeUserAdd{
ch := &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{
UserAdd: &aclpb.ACLChangeUserAdd{
Identity: identity,
EncryptionKey: rawKey,
EncryptedReadKeys: encryptedKeys,
@ -106,7 +106,7 @@ func (c *changeBuilder) UserAdd(identity string, encryptionKey keys.EncryptionPu
}
func (c *changeBuilder) BuildAndApply() (*Change, []byte, error) {
aclChange := &pb.ACLChange{
aclChange := &aclpb.ACLChange{
TreeHeadIds: c.tree.Heads(),
AclHeadIds: c.tree.ACLHeads(),
SnapshotBaseId: c.tree.RootId(),

View File

@ -3,35 +3,35 @@ package acltree
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"time"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/gogo/protobuf/proto"
)
type changeLoader struct {
cache map[string]*Change
identityKeys map[string]keys.SigningPubKey
signingPubKeyDecoder keys.SigningPubKeyDecoder
thread thread.Thread
changeCreator func(id string, ch *pb.ACLChange) *Change
identityKeys map[string]signingkey.PubKey
signingPubKeyDecoder signingkey.PubKeyDecoder
treeStorage treestorage.TreeStorage
changeCreator func(id string, ch *aclpb.ACLChange) *Change
}
func newChangeLoader(
thread thread.Thread,
signingPubKeyDecoder keys.SigningPubKeyDecoder,
changeCreator func(id string, ch *pb.ACLChange) *Change) *changeLoader {
treeStorage treestorage.TreeStorage,
signingPubKeyDecoder signingkey.PubKeyDecoder,
changeCreator func(id string, ch *aclpb.ACLChange) *Change) *changeLoader {
return &changeLoader{
signingPubKeyDecoder: signingPubKeyDecoder,
thread: thread,
treeStorage: treeStorage,
changeCreator: changeCreator,
}
}
func (c *changeLoader) Init(cache map[string]*Change,
identityKeys map[string]keys.SigningPubKey) {
identityKeys map[string]signingkey.PubKey) {
c.cache = cache
c.identityKeys = identityKeys
}
@ -45,7 +45,7 @@ func (c *changeLoader) loadChange(id string) (ch *Change, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
change, err := c.thread.GetChange(ctx, id)
change, err := c.treeStorage.GetChange(ctx, id)
if err != nil {
return nil, err
}
@ -73,8 +73,8 @@ func (c *changeLoader) verify(identity string, payload, signature []byte) (isVer
return identityKey.Verify(payload, signature)
}
func (c *changeLoader) makeVerifiedACLChange(change *thread.RawChange) (aclChange *pb.ACLChange, err error) {
aclChange = new(pb.ACLChange)
func (c *changeLoader) makeVerifiedACLChange(change *treestorage.RawChange) (aclChange *aclpb.ACLChange, err error) {
aclChange = new(aclpb.ACLChange)
// TODO: think what should we do with such cases, because this can be used by attacker to break our Tree
if err = proto.Unmarshal(change.Payload, aclChange); err != nil {

View File

@ -3,20 +3,20 @@ package acltree
import (
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
)
type snapshotValidator struct {
aclTree *Tree
identity string
key keys.EncryptionPrivKey
decoder keys.SigningPubKeyDecoder
key encryptionkey.PrivKey
decoder signingkey.PubKeyDecoder
stateBuilder *aclStateBuilder
}
func newSnapshotValidator(
decoder keys.SigningPubKeyDecoder,
decoder signingkey.PubKeyDecoder,
accountData *account.AccountData) *snapshotValidator {
return &snapshotValidator{
identity: accountData.Identity,

View File

@ -3,33 +3,32 @@ package acltree
import (
"errors"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
//"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/lib/logging"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
"github.com/prometheus/common/log"
)
var (
//log = logging.Logger("anytype-data")
log = logger.NewNamed("acltree").Sugar()
ErrEmpty = errors.New("logs empty")
)
type treeBuilder struct {
cache map[string]*Change
identityKeys map[string]keys.SigningPubKey
signingPubKeyDecoder keys.SigningPubKeyDecoder
identityKeys map[string]signingkey.PubKey
signingPubKeyDecoder signingkey.PubKeyDecoder
tree *Tree
thread thread.Thread
treeStorage treestorage.TreeStorage
*changeLoader
}
func newTreeBuilder(t thread.Thread, decoder keys.SigningPubKeyDecoder) *treeBuilder {
func newTreeBuilder(t treestorage.TreeStorage, decoder signingkey.PubKeyDecoder) *treeBuilder {
return &treeBuilder{
signingPubKeyDecoder: decoder,
thread: t,
treeStorage: t,
changeLoader: newChangeLoader(
t,
decoder,
@ -39,15 +38,23 @@ func newTreeBuilder(t thread.Thread, decoder keys.SigningPubKeyDecoder) *treeBui
func (tb *treeBuilder) Init() {
tb.cache = make(map[string]*Change)
tb.identityKeys = make(map[string]keys.SigningPubKey)
tb.identityKeys = make(map[string]signingkey.PubKey)
tb.tree = &Tree{}
tb.changeLoader.Init(tb.cache, tb.identityKeys)
}
func (tb *treeBuilder) Build(fromStart bool) (*Tree, error) {
var headsAndOrphans []string
headsAndOrphans = append(headsAndOrphans, tb.thread.Orphans()...)
headsAndOrphans = append(headsAndOrphans, tb.thread.Heads()...)
orphans, err := tb.treeStorage.Orphans()
if err != nil {
return nil, err
}
heads, err := tb.treeStorage.Heads()
if err != nil {
return nil, err
}
headsAndOrphans = append(headsAndOrphans, orphans...)
headsAndOrphans = append(headsAndOrphans, heads...)
if fromStart {
if err := tb.buildTreeFromStart(headsAndOrphans); err != nil {
@ -109,7 +116,10 @@ func (tb *treeBuilder) dfsFromStart(heads []string) (buf []*Change, root *Change
possibleRoots = append(possibleRoots, ch)
}
}
header := tb.thread.Header()
header, err := tb.treeStorage.Header()
if err != nil {
return nil, nil, err
}
for _, r := range possibleRoots {
if r.Id == header.FirstChangeId {
return buf, r, nil

View File

@ -1,19 +1,20 @@
package plaintextdocument
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
aclpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
aclpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"github.com/gogo/protobuf/proto"
)
type PlainTextDocument interface {
Text() string
AddText(text string) error
AddText(ctx context.Context, text string) error
}
type plainTextDocument struct {
@ -29,11 +30,11 @@ func (p *plainTextDocument) Text() string {
return ""
}
func (p *plainTextDocument) AddText(text string) error {
_, err := p.aclTree.AddContent(func(builder acltree.ChangeBuilder) error {
func (p *plainTextDocument) AddText(ctx context.Context, text string) error {
_, err := p.aclTree.AddContent(ctx, func(builder acltree.ChangeBuilder) error {
builder.AddChangeContent(
&pb.PlainTextChangeData{
Content: []*pb.PlainTextChangeContent{
&testchangepb.PlainTextChangeData{
Content: []*testchangepb.PlainTextChangeContent{
createAppendTextChangeContent(text),
},
})
@ -111,12 +112,12 @@ func (p *plainTextDocument) Rebuild(tree acltree.ACLTree) {
}
func NewInMemoryPlainTextDocument(acc *account.AccountData, text string) (PlainTextDocument, error) {
return NewPlainTextDocument(acc, thread.NewInMemoryThread, text)
return NewPlainTextDocument(acc, treestorage.NewInMemoryTreeStorage, text)
}
func NewPlainTextDocument(
acc *account.AccountData,
create func(change *thread.RawChange) (thread.Thread, error),
create func(change *treestorage.RawChange) (treestorage.TreeStorage, error),
text string) (PlainTextDocument, error) {
changeBuilder := func(builder acltree.ChangeBuilder) error {
err := builder.UserAdd(acc.Identity, acc.EncKey.GetPublic(), aclpb.ACLChange_Admin)
@ -126,7 +127,7 @@ func NewPlainTextDocument(
builder.AddChangeContent(createInitialChangeContent(text))
return nil
}
t, err := acltree.BuildThreadWithACL(
t, err := acltree.BuildTreeStorageWithACL(
acc,
changeBuilder,
create)
@ -148,18 +149,18 @@ func NewPlainTextDocument(
}
func createInitialChangeContent(text string) proto.Marshaler {
return &pb.PlainTextChangeData{
Content: []*pb.PlainTextChangeContent{
return &testchangepb.PlainTextChangeData{
Content: []*testchangepb.PlainTextChangeContent{
createAppendTextChangeContent(text),
},
Snapshot: &pb.PlainTextChangeSnapshot{Text: text},
Snapshot: &testchangepb.PlainTextChangeSnapshot{Text: text},
}
}
func createAppendTextChangeContent(text string) *pb.PlainTextChangeContent {
return &pb.PlainTextChangeContent{
Value: &pb.PlainTextChangeContentValueOfTextAppend{
TextAppend: &pb.PlainTextChangeTextAppend{
func createAppendTextChangeContent(text string) *testchangepb.PlainTextChangeContent {
return &testchangepb.PlainTextChangeContent{
Value: &testchangepb.PlainTextChangeContentValueOfTextAppend{
TextAppend: &testchangepb.PlainTextChangeTextAppend{
Text: text,
},
},

View File

@ -1,24 +1,27 @@
package plaintextdocument
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/threadbuilder"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/treestoragebuilder"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"github.com/stretchr/testify/assert"
"testing"
)
func TestDocument_NewPlainTextDocument(t *testing.T) {
keychain := threadbuilder.NewKeychain()
keychain := treestoragebuilder.NewKeychain()
keychain.AddSigningKey("A")
keychain.AddEncryptionKey("A")
data := &account.AccountData{
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
doc, err := NewPlainTextDocument(data, thread.NewInMemoryThread, "Some text")
doc, err := NewPlainTextDocument(data, treestorage.NewInMemoryTreeStorage, "Some text")
if err != nil {
t.Fatalf("should not create document with error: %v", err)
}
@ -26,27 +29,28 @@ func TestDocument_NewPlainTextDocument(t *testing.T) {
}
func TestDocument_PlainTextDocument_AddText(t *testing.T) {
keychain := threadbuilder.NewKeychain()
keychain := treestoragebuilder.NewKeychain()
keychain.AddSigningKey("A")
keychain.AddEncryptionKey("A")
data := &account.AccountData{
Identity: keychain.GetIdentity("A"),
SignKey: keychain.SigningKeys["A"],
EncKey: keychain.EncryptionKeys["A"],
Decoder: signingkey.NewEd25519Decoder(),
}
doc, err := NewPlainTextDocument(data, thread.NewInMemoryThread, "Some text")
doc, err := NewPlainTextDocument(data, treestorage.NewInMemoryTreeStorage, "Some text")
if err != nil {
t.Fatalf("should not create document with error: %v", err)
}
err = doc.AddText("Next")
err = doc.AddText(context.Background(), "Next")
if err != nil {
t.Fatalf("should be able to add document: %v", err)
}
assert.Equal(t, doc.Text(), "Some text|Next")
err = doc.AddText("Shmext")
err = doc.AddText(context.Background(), "Shmext")
if err != nil {
t.Fatalf("should be able to add document: %v", err)
}

View File

@ -2,7 +2,7 @@ package plaintextdocument
import (
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb"
"github.com/gogo/protobuf/proto"
)
@ -20,7 +20,7 @@ func NewDocumentState(text string, id string) *DocumentState {
}
func BuildDocumentStateFromChange(change []byte, id string) (*DocumentState, error) {
var changesData pb.PlainTextChangeData
var changesData testchangepb.PlainTextChangeData
err := proto.Unmarshal(change, &changesData)
if err != nil {
return nil, err
@ -33,7 +33,7 @@ func BuildDocumentStateFromChange(change []byte, id string) (*DocumentState, err
}
func (p *DocumentState) ApplyChange(change []byte, id string) (*DocumentState, error) {
var changesData pb.PlainTextChangeData
var changesData testchangepb.PlainTextChangeData
err := proto.Unmarshal(change, &changesData)
if err != nil {
return nil, err
@ -49,7 +49,7 @@ func (p *DocumentState) ApplyChange(change []byte, id string) (*DocumentState, e
return p, nil
}
func (p *DocumentState) applyChange(ch *pb.PlainTextChangeContent) error {
func (p *DocumentState) applyChange(ch *testchangepb.PlainTextChangeContent) error {
switch {
case ch.GetTextAppend() != nil:
text := ch.GetTextAppend().GetText()

View File

@ -1,6 +1,6 @@
syntax = "proto3";
package anytype;
option go_package = "pb";
option go_package = "testchangepb";
// TODO: move to separate package

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: data/pb/protos/plaintextchanges.proto
// source: pkg/acl/testutils/testchanges/testchangepb/protos/testdocumentchanges.proto
package pb
package testchangepb
import (
fmt "fmt"
@ -29,7 +29,7 @@ func (m *PlainTextChange) Reset() { *m = PlainTextChange{} }
func (m *PlainTextChange) String() string { return proto.CompactTextString(m) }
func (*PlainTextChange) ProtoMessage() {}
func (*PlainTextChange) Descriptor() ([]byte, []int) {
return fileDescriptor_970a1e91eeb094c9, []int{0}
return fileDescriptor_c07268f9f08f2beb, []int{0}
}
func (m *PlainTextChange) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -68,7 +68,7 @@ func (m *PlainTextChangeContent) Reset() { *m = PlainTextChangeContent{}
func (m *PlainTextChangeContent) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeContent) ProtoMessage() {}
func (*PlainTextChangeContent) Descriptor() ([]byte, []int) {
return fileDescriptor_970a1e91eeb094c9, []int{0, 0}
return fileDescriptor_c07268f9f08f2beb, []int{0, 0}
}
func (m *PlainTextChangeContent) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -138,7 +138,7 @@ func (m *PlainTextChangeTextAppend) Reset() { *m = PlainTextChangeTextAp
func (m *PlainTextChangeTextAppend) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeTextAppend) ProtoMessage() {}
func (*PlainTextChangeTextAppend) Descriptor() ([]byte, []int) {
return fileDescriptor_970a1e91eeb094c9, []int{0, 1}
return fileDescriptor_c07268f9f08f2beb, []int{0, 1}
}
func (m *PlainTextChangeTextAppend) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -182,7 +182,7 @@ func (m *PlainTextChangeSnapshot) Reset() { *m = PlainTextChangeSnapshot
func (m *PlainTextChangeSnapshot) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeSnapshot) ProtoMessage() {}
func (*PlainTextChangeSnapshot) Descriptor() ([]byte, []int) {
return fileDescriptor_970a1e91eeb094c9, []int{0, 2}
return fileDescriptor_c07268f9f08f2beb, []int{0, 2}
}
func (m *PlainTextChangeSnapshot) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -227,7 +227,7 @@ func (m *PlainTextChangeData) Reset() { *m = PlainTextChangeData{} }
func (m *PlainTextChangeData) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeData) ProtoMessage() {}
func (*PlainTextChangeData) Descriptor() ([]byte, []int) {
return fileDescriptor_970a1e91eeb094c9, []int{0, 3}
return fileDescriptor_c07268f9f08f2beb, []int{0, 3}
}
func (m *PlainTextChangeData) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -279,28 +279,29 @@ func init() {
}
func init() {
proto.RegisterFile("data/pb/protos/plaintextchanges.proto", fileDescriptor_970a1e91eeb094c9)
proto.RegisterFile("pkg/acl/testutils/testchanges/testchangepb/protos/testdocumentchanges.proto", fileDescriptor_c07268f9f08f2beb)
}
var fileDescriptor_970a1e91eeb094c9 = []byte{
// 259 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4d, 0x49, 0x2c, 0x49,
0xd4, 0x2f, 0x48, 0xd2, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x2f, 0xd6, 0x2f, 0xc8, 0x49, 0xcc, 0xcc,
0x2b, 0x49, 0xad, 0x28, 0x49, 0xce, 0x48, 0xcc, 0x4b, 0x4f, 0x2d, 0xd6, 0x03, 0x8b, 0x0b, 0xb1,
0x27, 0xe6, 0x55, 0x96, 0x54, 0x16, 0xa4, 0x2a, 0x6d, 0x62, 0xe2, 0xe2, 0x0f, 0x00, 0xa9, 0x09,
0x49, 0xad, 0x28, 0x71, 0x06, 0xab, 0x91, 0x8a, 0xe4, 0x62, 0x77, 0xce, 0xcf, 0x2b, 0x49, 0xcd,
0x2b, 0x11, 0x72, 0xe5, 0xe2, 0x02, 0x69, 0x76, 0x2c, 0x28, 0x48, 0xcd, 0x4b, 0x91, 0x60, 0x54,
0x60, 0xd4, 0xe0, 0x36, 0x52, 0xd6, 0x83, 0x6a, 0xd6, 0x43, 0xd3, 0xa8, 0x17, 0x02, 0x57, 0xea,
0xc1, 0x10, 0x84, 0xa4, 0xd1, 0x89, 0x9d, 0x8b, 0xb5, 0x2c, 0x31, 0xa7, 0x34, 0x55, 0x4a, 0x81,
0x8b, 0x0b, 0xa1, 0x48, 0x48, 0x88, 0x8b, 0x05, 0xa4, 0x08, 0x6c, 0x2e, 0x67, 0x10, 0x98, 0x2d,
0x25, 0xc7, 0xc5, 0x11, 0x9c, 0x97, 0x58, 0x50, 0x9c, 0x91, 0x5f, 0x82, 0x55, 0xbe, 0x91, 0x91,
0x8b, 0xc5, 0x25, 0xb1, 0x24, 0x51, 0xc8, 0x8a, 0x8b, 0x3d, 0x19, 0xe2, 0x4a, 0x09, 0x46, 0x05,
0x66, 0x0d, 0x6e, 0x23, 0x05, 0x9c, 0xee, 0x82, 0xfa, 0x26, 0x08, 0xa6, 0x41, 0xc8, 0x96, 0x8b,
0xa3, 0x18, 0x6a, 0x89, 0x04, 0x13, 0xd8, 0x53, 0x8a, 0x38, 0x35, 0xc3, 0x5c, 0x13, 0x04, 0xd7,
0xe2, 0x24, 0x73, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e,
0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x4c, 0x05, 0x49,
0x49, 0x6c, 0xe0, 0x20, 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xd3, 0x1e, 0xb0, 0x6a, 0x8b,
0x01, 0x00, 0x00,
var fileDescriptor_c07268f9f08f2beb = []byte{
// 278 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xf2, 0x2e, 0xc8, 0x4e, 0xd7,
0x4f, 0x4c, 0xce, 0xd1, 0x2f, 0x49, 0x2d, 0x2e, 0x29, 0x2d, 0xc9, 0xcc, 0x29, 0x06, 0xb3, 0x92,
0x33, 0x12, 0xf3, 0xd2, 0x53, 0x91, 0xd9, 0x05, 0x49, 0xfa, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x10,
0xb1, 0x94, 0xfc, 0xe4, 0xd2, 0xdc, 0xd4, 0x3c, 0x98, 0x3a, 0x3d, 0xb0, 0x94, 0x10, 0x7b, 0x62,
0x5e, 0x65, 0x49, 0x65, 0x41, 0xaa, 0xd2, 0x26, 0x26, 0x2e, 0xfe, 0x80, 0x9c, 0xc4, 0xcc, 0xbc,
0x90, 0xd4, 0x8a, 0x12, 0x67, 0xb0, 0x1a, 0xa9, 0x48, 0x2e, 0x76, 0xe7, 0xfc, 0xbc, 0x92, 0xd4,
0xbc, 0x12, 0x21, 0x57, 0x2e, 0xae, 0x92, 0xd4, 0x8a, 0x12, 0xc7, 0x82, 0x82, 0xd4, 0xbc, 0x14,
0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x65, 0x3d, 0xa8, 0x66, 0x3d, 0x34, 0x8d, 0x7a, 0x21,
0x70, 0xa5, 0x1e, 0x0c, 0x41, 0x48, 0x1a, 0x9d, 0xd8, 0xb9, 0x58, 0xcb, 0x12, 0x73, 0x4a, 0x53,
0xa5, 0x14, 0xb8, 0xb8, 0x10, 0x8a, 0x84, 0x84, 0xb8, 0x58, 0x40, 0x8a, 0xc0, 0xe6, 0x72, 0x06,
0x81, 0xd9, 0x52, 0x72, 0x5c, 0x1c, 0xc1, 0x79, 0x89, 0x05, 0xc5, 0x19, 0xf9, 0x25, 0x58, 0xe5,
0x1b, 0x19, 0xb9, 0x58, 0x5c, 0x12, 0x4b, 0x12, 0x85, 0xac, 0xb8, 0xd8, 0x93, 0x21, 0xae, 0x94,
0x60, 0x54, 0x60, 0xd6, 0xe0, 0x36, 0x52, 0xc0, 0xe9, 0x2e, 0xa8, 0x6f, 0x82, 0x60, 0x1a, 0x84,
0x6c, 0xb9, 0x38, 0x8a, 0xa1, 0x96, 0x48, 0x30, 0x81, 0x3d, 0xa5, 0x88, 0x53, 0x33, 0xcc, 0x35,
0x41, 0x70, 0x2d, 0x4e, 0x6a, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91,
0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xc5,
0x83, 0x1c, 0x0d, 0x49, 0x6c, 0xe0, 0xc0, 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x73,
0xe1, 0xf2, 0xbb, 0x01, 0x00, 0x00,
}
func (m *PlainTextChange) Marshal() (dAtA []byte, err error) {
@ -372,7 +373,7 @@ func (m *PlainTextChangeContentValueOfTextAppend) MarshalToSizedBuffer(dAtA []by
return 0, err
}
i -= size
i = encodeVarintPlaintextchanges(dAtA, i, uint64(size))
i = encodeVarintTestdocumentchanges(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
@ -402,7 +403,7 @@ func (m *PlainTextChangeTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, erro
if len(m.Text) > 0 {
i -= len(m.Text)
copy(dAtA[i:], m.Text)
i = encodeVarintPlaintextchanges(dAtA, i, uint64(len(m.Text)))
i = encodeVarintTestdocumentchanges(dAtA, i, uint64(len(m.Text)))
i--
dAtA[i] = 0xa
}
@ -432,7 +433,7 @@ func (m *PlainTextChangeSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error)
if len(m.Text) > 0 {
i -= len(m.Text)
copy(dAtA[i:], m.Text)
i = encodeVarintPlaintextchanges(dAtA, i, uint64(len(m.Text)))
i = encodeVarintTestdocumentchanges(dAtA, i, uint64(len(m.Text)))
i--
dAtA[i] = 0xa
}
@ -466,7 +467,7 @@ func (m *PlainTextChangeData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return 0, err
}
i -= size
i = encodeVarintPlaintextchanges(dAtA, i, uint64(size))
i = encodeVarintTestdocumentchanges(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
@ -479,7 +480,7 @@ func (m *PlainTextChangeData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return 0, err
}
i -= size
i = encodeVarintPlaintextchanges(dAtA, i, uint64(size))
i = encodeVarintTestdocumentchanges(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
@ -488,8 +489,8 @@ func (m *PlainTextChangeData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func encodeVarintPlaintextchanges(dAtA []byte, offset int, v uint64) int {
offset -= sovPlaintextchanges(v)
func encodeVarintTestdocumentchanges(dAtA []byte, offset int, v uint64) int {
offset -= sovTestdocumentchanges(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@ -528,7 +529,7 @@ func (m *PlainTextChangeContentValueOfTextAppend) Size() (n int) {
_ = l
if m.TextAppend != nil {
l = m.TextAppend.Size()
n += 1 + l + sovPlaintextchanges(uint64(l))
n += 1 + l + sovTestdocumentchanges(uint64(l))
}
return n
}
@ -540,7 +541,7 @@ func (m *PlainTextChangeTextAppend) Size() (n int) {
_ = l
l = len(m.Text)
if l > 0 {
n += 1 + l + sovPlaintextchanges(uint64(l))
n += 1 + l + sovTestdocumentchanges(uint64(l))
}
return n
}
@ -553,7 +554,7 @@ func (m *PlainTextChangeSnapshot) Size() (n int) {
_ = l
l = len(m.Text)
if l > 0 {
n += 1 + l + sovPlaintextchanges(uint64(l))
n += 1 + l + sovTestdocumentchanges(uint64(l))
}
return n
}
@ -567,21 +568,21 @@ func (m *PlainTextChangeData) Size() (n int) {
if len(m.Content) > 0 {
for _, e := range m.Content {
l = e.Size()
n += 1 + l + sovPlaintextchanges(uint64(l))
n += 1 + l + sovTestdocumentchanges(uint64(l))
}
}
if m.Snapshot != nil {
l = m.Snapshot.Size()
n += 1 + l + sovPlaintextchanges(uint64(l))
n += 1 + l + sovTestdocumentchanges(uint64(l))
}
return n
}
func sovPlaintextchanges(x uint64) (n int) {
func sovTestdocumentchanges(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozPlaintextchanges(x uint64) (n int) {
return sovPlaintextchanges(uint64((x << 1) ^ uint64((int64(x) >> 63))))
func sozTestdocumentchanges(x uint64) (n int) {
return sovTestdocumentchanges(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *PlainTextChange) Unmarshal(dAtA []byte) error {
l := len(dAtA)
@ -591,7 +592,7 @@ func (m *PlainTextChange) Unmarshal(dAtA []byte) error {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -614,12 +615,12 @@ func (m *PlainTextChange) Unmarshal(dAtA []byte) error {
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipPlaintextchanges(dAtA[iNdEx:])
skippy, err := skipTestdocumentchanges(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
@ -641,7 +642,7 @@ func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -669,7 +670,7 @@ func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -682,11 +683,11 @@ func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
}
}
if msglen < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if postIndex > l {
return io.ErrUnexpectedEOF
@ -699,12 +700,12 @@ func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPlaintextchanges(dAtA[iNdEx:])
skippy, err := skipTestdocumentchanges(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
@ -726,7 +727,7 @@ func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -754,7 +755,7 @@ func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error {
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -768,11 +769,11 @@ func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error {
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if postIndex > l {
return io.ErrUnexpectedEOF
@ -781,12 +782,12 @@ func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPlaintextchanges(dAtA[iNdEx:])
skippy, err := skipTestdocumentchanges(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
@ -808,7 +809,7 @@ func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -836,7 +837,7 @@ func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error {
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -850,11 +851,11 @@ func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error {
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if postIndex > l {
return io.ErrUnexpectedEOF
@ -863,12 +864,12 @@ func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPlaintextchanges(dAtA[iNdEx:])
skippy, err := skipTestdocumentchanges(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
@ -890,7 +891,7 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -918,7 +919,7 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -931,11 +932,11 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
}
}
if msglen < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if postIndex > l {
return io.ErrUnexpectedEOF
@ -952,7 +953,7 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlaintextchanges
return ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -965,11 +966,11 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
}
}
if msglen < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if postIndex > l {
return io.ErrUnexpectedEOF
@ -983,12 +984,12 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPlaintextchanges(dAtA[iNdEx:])
skippy, err := skipTestdocumentchanges(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthPlaintextchanges
return ErrInvalidLengthTestdocumentchanges
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
@ -1002,7 +1003,7 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
}
return nil
}
func skipPlaintextchanges(dAtA []byte) (n int, err error) {
func skipTestdocumentchanges(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
@ -1010,7 +1011,7 @@ func skipPlaintextchanges(dAtA []byte) (n int, err error) {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPlaintextchanges
return 0, ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
@ -1027,7 +1028,7 @@ func skipPlaintextchanges(dAtA []byte) (n int, err error) {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPlaintextchanges
return 0, ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
@ -1043,7 +1044,7 @@ func skipPlaintextchanges(dAtA []byte) (n int, err error) {
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPlaintextchanges
return 0, ErrIntOverflowTestdocumentchanges
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
@ -1056,14 +1057,14 @@ func skipPlaintextchanges(dAtA []byte) (n int, err error) {
}
}
if length < 0 {
return 0, ErrInvalidLengthPlaintextchanges
return 0, ErrInvalidLengthTestdocumentchanges
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupPlaintextchanges
return 0, ErrUnexpectedEndOfGroupTestdocumentchanges
}
depth--
case 5:
@ -1072,7 +1073,7 @@ func skipPlaintextchanges(dAtA []byte) (n int, err error) {
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthPlaintextchanges
return 0, ErrInvalidLengthTestdocumentchanges
}
if depth == 0 {
return iNdEx, nil
@ -1082,7 +1083,7 @@ func skipPlaintextchanges(dAtA []byte) (n int, err error) {
}
var (
ErrInvalidLengthPlaintextchanges = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowPlaintextchanges = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupPlaintextchanges = fmt.Errorf("proto: unexpected end of group")
ErrInvalidLengthTestdocumentchanges = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowTestdocumentchanges = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupTestdocumentchanges = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -1,12 +1,12 @@
package threadbuilder
package treestoragebuilder
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"hash/fnv"
"strings"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/textileio/go-threads/crypto/symmetric"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
)
type SymKey struct {
@ -15,24 +15,24 @@ type SymKey struct {
}
type Keychain struct {
SigningKeys map[string]keys.SigningPrivKey
SigningKeysByIdentity map[string]keys.SigningPrivKey
EncryptionKeys map[string]keys.EncryptionPrivKey
SigningKeys map[string]signingkey.PrivKey
SigningKeysByIdentity map[string]signingkey.PrivKey
EncryptionKeys map[string]encryptionkey.PrivKey
ReadKeys map[string]*SymKey
ReadKeysByHash map[uint64]*SymKey
GeneratedIdentities map[string]string
coder *keys.Ed25519SigningPubKeyDecoder
coder signingkey.PubKeyDecoder
}
func NewKeychain() *Keychain {
return &Keychain{
SigningKeys: map[string]keys.SigningPrivKey{},
SigningKeysByIdentity: map[string]keys.SigningPrivKey{},
EncryptionKeys: map[string]keys.EncryptionPrivKey{},
SigningKeys: map[string]signingkey.PrivKey{},
SigningKeysByIdentity: map[string]signingkey.PrivKey{},
EncryptionKeys: map[string]encryptionkey.PrivKey{},
GeneratedIdentities: map[string]string{},
ReadKeys: map[string]*SymKey{},
ReadKeysByHash: map[uint64]*SymKey{},
coder: keys.NewEd25519Decoder(),
coder: signingkey.NewEd25519Decoder(),
}
}
@ -54,7 +54,7 @@ func (k *Keychain) AddEncryptionKey(name string) {
if _, exists := k.EncryptionKeys[name]; exists {
return
}
newPrivKey, _, err := keys.GenerateRandomRSAKeyPair(2048)
newPrivKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048)
if err != nil {
panic(err)
}
@ -66,7 +66,7 @@ func (k *Keychain) AddSigningKey(name string) {
if _, exists := k.SigningKeys[name]; exists {
return
}
newPrivKey, pubKey, err := keys.GenerateRandomEd25519KeyPair()
newPrivKey, pubKey, err := signingkey.GenerateRandomEd25519KeyPair()
if err != nil {
panic(err)
}

View File

@ -1,94 +1,94 @@
package threadbuilder
package treestoragebuilder
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/pb"
testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/yamltests"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread"
threadpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage"
storagepb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
"io/ioutil"
"path"
"github.com/gogo/protobuf/proto"
"gopkg.in/yaml.v3"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
)
const plainTextDocType uint16 = 1
type threadChange struct {
*pb.ACLChange
type treeChange struct {
*aclpb.ACLChange
id string
readKey *SymKey
signKey keys.SigningPrivKey
signKey signingkey.PrivKey
changesDataDecrypted []byte
}
type updateUseCase struct {
changes map[string]*threadChange
changes map[string]*treeChange
}
type ThreadBuilder struct {
threadId string
allChanges map[string]*threadChange
type TreeStorageBuilder struct {
treeId string
allChanges map[string]*treeChange
updates map[string]*updateUseCase
heads []string
orphans []string
keychain *Keychain
header *threadpb.ThreadHeader
header *storagepb.TreeHeader
}
func NewThreadBuilder(keychain *Keychain) *ThreadBuilder {
return &ThreadBuilder{
allChanges: make(map[string]*threadChange),
func NewTreeStorageBuilder(keychain *Keychain) *TreeStorageBuilder {
return &TreeStorageBuilder{
allChanges: make(map[string]*treeChange),
updates: make(map[string]*updateUseCase),
keychain: keychain,
}
}
func NewThreadBuilderWithTestName(name string) (*ThreadBuilder, error) {
func NewTreeStorageBuilderWithTestName(name string) (*TreeStorageBuilder, error) {
filePath := path.Join(yamltests.Path(), name)
return NewThreadBuilderFromFile(filePath)
return NewTreeStorageBuilderFromFile(filePath)
}
func NewThreadBuilderFromFile(file string) (*ThreadBuilder, error) {
func NewTreeStorageBuilderFromFile(file string) (*TreeStorageBuilder, error) {
content, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
thread := YMLThread{}
err = yaml.Unmarshal(content, &thread)
ymlTree := YMLTree{}
err = yaml.Unmarshal(content, &ymlTree)
if err != nil {
return nil, err
}
tb := NewThreadBuilder(NewKeychain())
tb.Parse(&thread)
tb := NewTreeStorageBuilder(NewKeychain())
tb.Parse(&ymlTree)
return tb, nil
}
func (t *ThreadBuilder) ID() string {
return t.threadId
func (t *TreeStorageBuilder) TreeID() (string, error) {
return t.treeId, nil
}
func (t *ThreadBuilder) GetKeychain() *Keychain {
func (t *TreeStorageBuilder) GetKeychain() *Keychain {
return t.keychain
}
func (t *ThreadBuilder) Heads() []string {
return t.heads
func (t *TreeStorageBuilder) Heads() ([]string, error) {
return t.heads, nil
}
func (t *ThreadBuilder) AddRawChange(change *thread.RawChange) error {
aclChange := new(pb.ACLChange)
func (t *TreeStorageBuilder) AddRawChange(change *treestorage.RawChange) error {
aclChange := new(aclpb.ACLChange)
var err error
if err = proto.Unmarshal(change.Payload, aclChange); err != nil {
@ -108,7 +108,7 @@ func (t *ThreadBuilder) AddRawChange(change *thread.RawChange) error {
// get correct signing key
signKey := t.keychain.SigningKeysByIdentity[aclChange.Identity]
t.allChanges[change.Id] = &threadChange{
t.allChanges[change.Id] = &treeChange{
ACLChange: aclChange,
id: change.Id,
readKey: readKey,
@ -118,11 +118,12 @@ func (t *ThreadBuilder) AddRawChange(change *thread.RawChange) error {
return nil
}
func (t *ThreadBuilder) AddOrphans(orphans ...string) {
func (t *TreeStorageBuilder) AddOrphans(orphans ...string) error {
t.orphans = append(t.orphans, orphans...)
return nil
}
func (t *ThreadBuilder) AddChange(change aclchanges.Change) error {
func (t *TreeStorageBuilder) AddChange(change aclchanges.Change) error {
aclChange := change.ProtoChange()
var err error
var changesData []byte
@ -139,7 +140,7 @@ func (t *ThreadBuilder) AddChange(change aclchanges.Change) error {
// get correct signing key
signKey := t.keychain.SigningKeysByIdentity[aclChange.Identity]
t.allChanges[change.CID()] = &threadChange{
t.allChanges[change.CID()] = &treeChange{
ACLChange: aclChange,
id: change.CID(),
readKey: readKey,
@ -149,25 +150,27 @@ func (t *ThreadBuilder) AddChange(change aclchanges.Change) error {
return nil
}
func (t *ThreadBuilder) Orphans() []string {
return t.orphans
func (t *TreeStorageBuilder) Orphans() ([]string, error) {
return t.orphans, nil
}
func (t *ThreadBuilder) SetHeads(heads []string) {
func (t *TreeStorageBuilder) SetHeads(heads []string) error {
// we should copy here instead of just setting the value
t.heads = heads
return nil
}
func (t *ThreadBuilder) RemoveOrphans(orphans ...string) {
func (t *TreeStorageBuilder) RemoveOrphans(orphans ...string) error {
t.orphans = slice.Difference(t.orphans, orphans)
return nil
}
func (t *ThreadBuilder) GetChange(ctx context.Context, recordID string) (*thread.RawChange, error) {
func (t *TreeStorageBuilder) GetChange(ctx context.Context, recordID string) (*treestorage.RawChange, error) {
return t.getChange(recordID, t.allChanges), nil
}
func (t *ThreadBuilder) GetUpdates(useCase string) []*thread.RawChange {
var res []*thread.RawChange
func (t *TreeStorageBuilder) GetUpdates(useCase string) []*treestorage.RawChange {
var res []*treestorage.RawChange
update := t.updates[useCase]
for _, ch := range update.changes {
rawCh := t.getChange(ch.id, update.changes)
@ -176,11 +179,11 @@ func (t *ThreadBuilder) GetUpdates(useCase string) []*thread.RawChange {
return res
}
func (t *ThreadBuilder) Header() *threadpb.ThreadHeader {
return t.header
func (t *TreeStorageBuilder) Header() (*storagepb.TreeHeader, error) {
return t.header, nil
}
func (t *ThreadBuilder) getChange(changeId string, m map[string]*threadChange) *thread.RawChange {
func (t *TreeStorageBuilder) getChange(changeId string, m map[string]*treeChange) *treestorage.RawChange {
rec := m[changeId]
if rec.changesDataDecrypted != nil {
@ -202,7 +205,7 @@ func (t *ThreadBuilder) getChange(changeId string, m map[string]*threadChange) *
panic("should be able to sign final acl message!")
}
transformedRec := &thread.RawChange{
transformedRec := &treestorage.RawChange{
Payload: aclMarshaled,
Signature: signature,
Id: changeId,
@ -210,39 +213,39 @@ func (t *ThreadBuilder) getChange(changeId string, m map[string]*threadChange) *
return transformedRec
}
func (t *ThreadBuilder) Parse(thread *YMLThread) {
func (t *TreeStorageBuilder) Parse(tree *YMLTree) {
// Just to clarify - we are generating new identities for the ones that
// are specified in the yml file, because our identities should be Ed25519
// the same thing is happening for the encryption keys
t.keychain.ParseKeys(&thread.Keys)
t.threadId = t.parseThreadId(thread.Description)
for _, ch := range thread.Changes {
t.keychain.ParseKeys(&tree.Keys)
t.treeId = t.parseTreeId(tree.Description)
for _, ch := range tree.Changes {
newChange := t.parseChange(ch)
t.allChanges[newChange.id] = newChange
}
t.parseGraph(thread)
t.parseOrphans(thread)
t.parseHeader(thread)
t.parseUpdates(thread.Updates)
t.parseGraph(tree)
t.parseOrphans(tree)
t.parseHeader(tree)
t.parseUpdates(tree.Updates)
}
func (t *ThreadBuilder) parseChange(ch *Change) *threadChange {
newChange := &threadChange{
func (t *TreeStorageBuilder) parseChange(ch *Change) *treeChange {
newChange := &treeChange{
id: ch.Id,
}
k := t.keychain.GetKey(ch.ReadKey).(*SymKey)
newChange.readKey = k
newChange.signKey = t.keychain.SigningKeys[ch.Identity]
aclChange := &pb.ACLChange{}
aclChange := &aclpb.ACLChange{}
aclChange.Identity = t.keychain.GetIdentity(ch.Identity)
if len(ch.AclChanges) > 0 || ch.AclSnapshot != nil {
aclChange.AclData = &pb.ACLChangeACLData{}
aclChange.AclData = &aclpb.ACLChangeACLData{}
if ch.AclSnapshot != nil {
aclChange.AclData.AclSnapshot = t.parseACLSnapshot(ch.AclSnapshot)
}
if ch.AclChanges != nil {
var aclChangeContents []*pb.ACLChangeACLContentValue
var aclChangeContents []*aclpb.ACLChangeACLContentValue
for _, ch := range ch.AclChanges {
aclChangeContent := t.parseACLChange(ch)
aclChangeContents = append(aclChangeContents, aclChangeContent)
@ -274,33 +277,27 @@ func (t *ThreadBuilder) parseChange(ch *Change) *threadChange {
return newChange
}
func (t *ThreadBuilder) parseThreadId(description *ThreadDescription) string {
func (t *TreeStorageBuilder) parseTreeId(description *TreeDescription) string {
if description == nil {
panic("no author in thread")
panic("no author in tree")
}
key := t.keychain.SigningKeys[description.Author]
id, err := thread.CreateACLThreadID(key.GetPublic(), plainTextDocType)
if err != nil {
panic(err)
return description.Author + ".tree.id"
}
return id.String()
}
func (t *ThreadBuilder) parseChangeSnapshot(s *PlainTextSnapshot) *testpb.PlainTextChangeSnapshot {
func (t *TreeStorageBuilder) parseChangeSnapshot(s *PlainTextSnapshot) *testpb.PlainTextChangeSnapshot {
return &testpb.PlainTextChangeSnapshot{
Text: s.Text,
}
}
func (t *ThreadBuilder) parseACLSnapshot(s *ACLSnapshot) *pb.ACLChangeACLSnapshot {
newState := &pb.ACLChangeACLState{}
func (t *TreeStorageBuilder) parseACLSnapshot(s *ACLSnapshot) *aclpb.ACLChangeACLSnapshot {
newState := &aclpb.ACLChangeACLState{}
for _, state := range s.UserStates {
aclUserState := &pb.ACLChangeUserState{}
aclUserState := &aclpb.ACLChangeUserState{}
aclUserState.Identity = t.keychain.GetIdentity(state.Identity)
encKey := t.keychain.
GetKey(state.EncryptionKey).(keys.EncryptionPrivKey)
GetKey(state.EncryptionKey).(encryptionkey.PrivKey)
rawKey, _ := encKey.GetPublic().Raw()
aclUserState.EncryptionKey = rawKey
@ -308,12 +305,12 @@ func (t *ThreadBuilder) parseACLSnapshot(s *ACLSnapshot) *pb.ACLChangeACLSnapsho
aclUserState.Permissions = t.convertPermission(state.Permissions)
newState.UserStates = append(newState.UserStates, aclUserState)
}
return &pb.ACLChangeACLSnapshot{
return &aclpb.ACLChangeACLSnapshot{
AclState: newState,
}
}
func (t *ThreadBuilder) parseDocumentChange(ch *PlainTextChange) (convCh *testpb.PlainTextChangeContent) {
func (t *TreeStorageBuilder) parseDocumentChange(ch *PlainTextChange) (convCh *testpb.PlainTextChangeContent) {
switch {
case ch.TextAppend != nil:
convCh = &testpb.PlainTextChangeContent{
@ -331,18 +328,18 @@ func (t *ThreadBuilder) parseDocumentChange(ch *PlainTextChange) (convCh *testpb
return convCh
}
func (t *ThreadBuilder) parseACLChange(ch *ACLChange) (convCh *pb.ACLChangeACLContentValue) {
func (t *TreeStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACLChangeACLContentValue) {
switch {
case ch.UserAdd != nil:
add := ch.UserAdd
encKey := t.keychain.
GetKey(add.EncryptionKey).(keys.EncryptionPrivKey)
GetKey(add.EncryptionKey).(encryptionkey.PrivKey)
rawKey, _ := encKey.GetPublic().Raw()
convCh = &pb.ACLChangeACLContentValue{
Value: &pb.ACLChangeACLContentValueValueOfUserAdd{
UserAdd: &pb.ACLChangeUserAdd{
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{
UserAdd: &aclpb.ACLChangeUserAdd{
Identity: t.keychain.GetIdentity(add.Identity),
EncryptionKey: rawKey,
EncryptedReadKeys: t.encryptReadKeys(add.EncryptedReadKeys, encKey),
@ -354,19 +351,19 @@ func (t *ThreadBuilder) parseACLChange(ch *ACLChange) (convCh *pb.ACLChangeACLCo
join := ch.UserJoin
encKey := t.keychain.
GetKey(join.EncryptionKey).(keys.EncryptionPrivKey)
GetKey(join.EncryptionKey).(encryptionkey.PrivKey)
rawKey, _ := encKey.GetPublic().Raw()
idKey, _ := t.keychain.SigningKeys[join.Identity].GetPublic().Raw()
signKey := t.keychain.GetKey(join.AcceptSignature).(keys.SigningPrivKey)
signKey := t.keychain.GetKey(join.AcceptSignature).(signingkey.PrivKey)
signature, err := signKey.Sign(idKey)
if err != nil {
panic(err)
}
convCh = &pb.ACLChangeACLContentValue{
Value: &pb.ACLChangeACLContentValueValueOfUserJoin{
UserJoin: &pb.ACLChangeUserJoin{
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserJoin{
UserJoin: &aclpb.ACLChangeUserJoin{
Identity: t.keychain.GetIdentity(join.Identity),
EncryptionKey: rawKey,
AcceptSignature: signature,
@ -377,14 +374,14 @@ func (t *ThreadBuilder) parseACLChange(ch *ACLChange) (convCh *pb.ACLChangeACLCo
}
case ch.UserInvite != nil:
invite := ch.UserInvite
rawAcceptKey, _ := t.keychain.GetKey(invite.AcceptKey).(keys.SigningPrivKey).GetPublic().Raw()
rawAcceptKey, _ := t.keychain.GetKey(invite.AcceptKey).(signingkey.PrivKey).GetPublic().Raw()
encKey := t.keychain.
GetKey(invite.EncryptionKey).(keys.EncryptionPrivKey)
GetKey(invite.EncryptionKey).(encryptionkey.PrivKey)
rawEncKey, _ := encKey.GetPublic().Raw()
convCh = &pb.ACLChangeACLContentValue{
Value: &pb.ACLChangeACLContentValueValueOfUserInvite{
UserInvite: &pb.ACLChangeUserInvite{
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserInvite{
UserInvite: &aclpb.ACLChangeUserInvite{
AcceptPublicKey: rawAcceptKey,
EncryptPublicKey: rawEncKey,
EncryptedReadKeys: t.encryptReadKeys(invite.EncryptedReadKeys, encKey),
@ -396,9 +393,9 @@ func (t *ThreadBuilder) parseACLChange(ch *ACLChange) (convCh *pb.ACLChangeACLCo
case ch.UserConfirm != nil:
confirm := ch.UserConfirm
convCh = &pb.ACLChangeACLContentValue{
Value: &pb.ACLChangeACLContentValueValueOfUserConfirm{
UserConfirm: &pb.ACLChangeUserConfirm{
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserConfirm{
UserConfirm: &aclpb.ACLChangeUserConfirm{
Identity: t.keychain.GetIdentity(confirm.Identity),
UserAddId: confirm.UserAddId,
},
@ -407,9 +404,9 @@ func (t *ThreadBuilder) parseACLChange(ch *ACLChange) (convCh *pb.ACLChangeACLCo
case ch.UserPermissionChange != nil:
permissionChange := ch.UserPermissionChange
convCh = &pb.ACLChangeACLContentValue{
Value: &pb.ACLChangeACLContentValueValueOfUserPermissionChange{
UserPermissionChange: &pb.ACLChangeUserPermissionChange{
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserPermissionChange{
UserPermissionChange: &aclpb.ACLChangeUserPermissionChange{
Identity: t.keychain.GetIdentity(permissionChange.Identity),
Permissions: t.convertPermission(permissionChange.Permission),
},
@ -420,7 +417,7 @@ func (t *ThreadBuilder) parseACLChange(ch *ACLChange) (convCh *pb.ACLChangeACLCo
newReadKey := t.keychain.GetKey(remove.NewReadKey).(*SymKey)
var replaces []*pb.ACLChangeReadKeyReplace
var replaces []*aclpb.ACLChangeReadKeyReplace
for _, id := range remove.IdentitiesLeft {
identity := t.keychain.GetIdentity(id)
encKey := t.keychain.EncryptionKeys[id]
@ -429,16 +426,16 @@ func (t *ThreadBuilder) parseACLChange(ch *ACLChange) (convCh *pb.ACLChangeACLCo
if err != nil {
panic(err)
}
replaces = append(replaces, &pb.ACLChangeReadKeyReplace{
replaces = append(replaces, &aclpb.ACLChangeReadKeyReplace{
Identity: identity,
EncryptionKey: rawEncKey,
EncryptedReadKey: encReadKey,
})
}
convCh = &pb.ACLChangeACLContentValue{
Value: &pb.ACLChangeACLContentValueValueOfUserRemove{
UserRemove: &pb.ACLChangeUserRemove{
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserRemove{
UserRemove: &aclpb.ACLChangeUserRemove{
Identity: t.keychain.GetIdentity(remove.RemovedIdentity),
ReadKeyReplaces: replaces,
},
@ -452,7 +449,7 @@ func (t *ThreadBuilder) parseACLChange(ch *ACLChange) (convCh *pb.ACLChangeACLCo
return convCh
}
func (t *ThreadBuilder) encryptReadKeys(keys []string, encKey keys.EncryptionPrivKey) (enc [][]byte) {
func (t *TreeStorageBuilder) encryptReadKeys(keys []string, encKey encryptionkey.PrivKey) (enc [][]byte) {
for _, k := range keys {
realKey := t.keychain.GetKey(k).(*SymKey).Key.Bytes()
res, err := encKey.GetPublic().Encrypt(realKey)
@ -465,20 +462,20 @@ func (t *ThreadBuilder) encryptReadKeys(keys []string, encKey keys.EncryptionPri
return
}
func (t *ThreadBuilder) convertPermission(perm string) pb.ACLChangeUserPermissions {
func (t *TreeStorageBuilder) convertPermission(perm string) aclpb.ACLChangeUserPermissions {
switch perm {
case "admin":
return pb.ACLChange_Admin
return aclpb.ACLChange_Admin
case "writer":
return pb.ACLChange_Writer
return aclpb.ACLChange_Writer
case "reader":
return pb.ACLChange_Reader
return aclpb.ACLChange_Reader
default:
panic(fmt.Sprintf("incorrect permission: %s", perm))
}
}
func (t *ThreadBuilder) traverseFromHeads(f func(t *threadChange) error) error {
func (t *TreeStorageBuilder) traverseFromHeads(f func(t *treeChange) error) error {
uniqMap := map[string]struct{}{}
stack := make([]string, len(t.orphans), 10)
copy(stack, t.orphans)
@ -502,10 +499,10 @@ func (t *ThreadBuilder) traverseFromHeads(f func(t *threadChange) error) error {
return nil
}
func (t *ThreadBuilder) parseUpdates(updates []*Update) {
func (t *TreeStorageBuilder) parseUpdates(updates []*Update) {
for _, update := range updates {
useCase := &updateUseCase{
changes: map[string]*threadChange{},
changes: map[string]*treeChange{},
}
for _, ch := range update.Changes {
newChange := t.parseChange(ch)
@ -522,8 +519,8 @@ func (t *ThreadBuilder) parseUpdates(updates []*Update) {
}
}
func (t *ThreadBuilder) parseGraph(thread *YMLThread) {
for _, node := range thread.Graph {
func (t *TreeStorageBuilder) parseGraph(tree *YMLTree) {
for _, node := range tree.Graph {
rec := t.allChanges[node.Id]
rec.AclHeadIds = node.ACLHeads
rec.TreeHeadIds = node.TreeHeads
@ -531,13 +528,13 @@ func (t *ThreadBuilder) parseGraph(thread *YMLThread) {
}
}
func (t *ThreadBuilder) parseOrphans(thread *YMLThread) {
t.orphans = thread.Orphans
func (t *TreeStorageBuilder) parseOrphans(tree *YMLTree) {
t.orphans = tree.Orphans
}
func (t *ThreadBuilder) parseHeader(thread *YMLThread) {
t.header = &threadpb.ThreadHeader{
FirstChangeId: thread.Header.FirstChangeId,
IsWorkspace: thread.Header.IsWorkspace,
func (t *TreeStorageBuilder) parseHeader(tree *YMLTree) {
t.header = &storagepb.TreeHeader{
FirstChangeId: tree.Header.FirstChangeId,
IsWorkspace: tree.Header.IsWorkspace,
}
}

View File

@ -2,10 +2,10 @@
// +build !linux,!darwin android ios nographviz
// +build !amd64
package threadbuilder
package treestoragebuilder
import "fmt"
func (t *ThreadBuilder) Graph() (string, error) {
func (t *TreeStorageBuilder) Graph() (string, error) {
return "", fmt.Errorf("building graphs is not supported")
}

View File

@ -5,11 +5,11 @@
// +build !nographviz
// +build amd64 arm64
package threadbuilder
package treestoragebuilder
import (
"fmt"
testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/pb"
testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb"
"github.com/gogo/protobuf/proto"
"strings"
@ -26,14 +26,14 @@ type EdgeParameters struct {
label string
}
func (t *ThreadBuilder) Graph() (string, error) {
func (t *TreeStorageBuilder) Graph() (string, error) {
// TODO: check updates on https://github.com/goccy/go-graphviz/issues/52 or make a fix yourself to use better library here
graph := gographviz.NewGraph()
graph.SetName("G")
graph.SetDir(true)
var nodes = make(map[string]struct{})
var addNodes = func(r *threadChange) error {
var addNodes = func(r *treeChange) error {
// TODO: revisit function after checking
style := "solid"
@ -114,7 +114,7 @@ func (t *ThreadBuilder) Graph() (string, error) {
return nil
}
var addLinks = func(t *threadChange) error {
var addLinks = func(t *treeChange) error {
for _, prevId := range t.AclHeadIds {
err := createEdge(t.id, prevId, EdgeParameters{
style: "dashed",

View File

@ -1,6 +1,6 @@
package threadbuilder
package treestoragebuilder
type ThreadDescription struct {
type TreeDescription struct {
Author string `yaml:"author"`
}
@ -102,8 +102,8 @@ type Update struct {
Graph []*GraphNode `yaml:"graph"`
}
type YMLThread struct {
Description *ThreadDescription `yaml:"thread"`
type YMLTree struct {
Description *TreeDescription `yaml:"tree"`
Changes []*Change `yaml:"changes"`
Updates []*Update `yaml:"updates"`

View File

@ -1,4 +1,4 @@
package threadbuilder
package treestoragebuilder
import (
"fmt"
@ -6,7 +6,7 @@ import (
)
func Test_YamlParse(t *testing.T) {
tb, _ := NewThreadBuilderWithTestName("userjoinexampleupdate.yml")
tb, _ := NewTreeStorageBuilderWithTestName("userjoinexampleupdate.yml")
gr, _ := tb.Graph()
fmt.Println(gr)
}

View File

@ -1,4 +1,4 @@
thread:
tree:
author: A
changes:
- id: A.1.1

View File

@ -1,4 +1,4 @@
thread:
tree:
author: A
changes:
- id: A.1.1

View File

@ -1,4 +1,4 @@
thread:
tree:
author: A
changes:
- id: A.1.1

View File

@ -1,4 +1,4 @@
thread:
tree:
author: A
changes:
- id: A.1.1

View File

@ -1,4 +1,4 @@
thread:
tree:
author: A
changes:
- id: A.1.1

View File

@ -1,4 +1,4 @@
thread:
tree:
author: A
changes:
- id: A.1.1

View File

@ -1,72 +0,0 @@
package thread
import (
"crypto/rand"
"encoding/binary"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"hash/fnv"
"github.com/textileio/go-threads/core/thread"
)
func CreateACLThreadID(k keys.SigningPubKey, docType uint16) (thread.ID, error) {
rndlen := 32
buf := make([]byte, 8+rndlen)
// adding random bytes in the end
_, err := rand.Read(buf[8 : 8+rndlen])
if err != nil {
panic("random read failed")
}
keyBytes, err := k.Bytes()
if err != nil {
return thread.Undef, err
}
hasher := fnv.New64()
hasher.Write(keyBytes)
res := hasher.Sum64()
// putting hash of the pubkey in the beginning
binary.LittleEndian.PutUint64(buf[:8], res)
return threadIDFromBytes(docType, buf)
}
func VerifyACLThreadID(k keys.SigningPubKey, threadId thread.ID) (bool, error) {
bytes := threadId.Bytes()
pubKeyBytes := threadId.Bytes()[len(bytes)-40 : len(bytes)-32]
hash := binary.LittleEndian.Uint64(pubKeyBytes)
keyBytes, err := k.Bytes()
if err != nil {
return false, err
}
hasher := fnv.New64()
hasher.Write(keyBytes)
realHash := hasher.Sum64()
return hash == realHash, nil
}
func threadIDFromBytes(
docType uint16,
b []byte) (thread.ID, error) {
blen := len(b)
// two 8 bytes (max) numbers plus num
buf := make([]byte, 2*binary.MaxVarintLen64+blen)
n := binary.PutUvarint(buf, thread.V1)
n += binary.PutUvarint(buf[n:], uint64(thread.AccessControlled))
n += binary.PutUvarint(buf[n:], uint64(docType))
cn := copy(buf[n:], b)
if cn != blen {
return thread.Undef, fmt.Errorf("copy length is inconsistent")
}
return thread.Cast(buf[:n+blen])
}

View File

@ -1,27 +0,0 @@
package thread
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"testing"
)
func TestCreateACLThreadIDVerify(t *testing.T) {
_, pubKey, err := keys.GenerateRandomEd25519KeyPair()
if err != nil {
t.Fatalf("should not return error after generating key pair: %v", err)
}
thread, err := CreateACLThreadID(pubKey, 1)
if err != nil {
t.Fatalf("should not return error after generating thread: %v", err)
}
verified, err := VerifyACLThreadID(pubKey, thread)
if err != nil {
t.Fatalf("verification should not return error: %v", err)
}
if !verified {
t.Fatalf("the thread should be verified")
}
}

View File

@ -1,19 +1,19 @@
package thread
package treestorage
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
"github.com/gogo/protobuf/proto"
"sync"
)
type inMemoryThread struct {
type inMemoryTreeStorage struct {
id string
header *pb.ThreadHeader
header *treepb.TreeHeader
heads []string
orphans []string
changes map[string]*RawChange
@ -21,8 +21,8 @@ type inMemoryThread struct {
sync.RWMutex
}
func NewInMemoryThread(firstChange *RawChange) (Thread, error) {
header := &pb.ThreadHeader{
func NewInMemoryTreeStorage(firstChange *RawChange) (TreeStorage, error) {
header := &treepb.TreeHeader{
FirstChangeId: firstChange.Id,
IsWorkspace: false,
}
@ -30,7 +30,7 @@ func NewInMemoryThread(firstChange *RawChange) (Thread, error) {
if err != nil {
return nil, err
}
threadId, err := cid.NewCIDFromBytes(marshalledHeader)
treeId, err := cid.NewCIDFromBytes(marshalledHeader)
if err != nil {
return nil, err
}
@ -38,8 +38,8 @@ func NewInMemoryThread(firstChange *RawChange) (Thread, error) {
changes := make(map[string]*RawChange)
changes[firstChange.Id] = firstChange
return &inMemoryThread{
id: threadId,
return &inMemoryTreeStorage{
id: treeId,
header: header,
heads: []string{firstChange.Id},
orphans: nil,
@ -48,31 +48,31 @@ func NewInMemoryThread(firstChange *RawChange) (Thread, error) {
}, nil
}
func (t *inMemoryThread) ID() string {
func (t *inMemoryTreeStorage) TreeID() (string, error) {
t.RLock()
defer t.RUnlock()
return t.id
return t.id, nil
}
func (t *inMemoryThread) Header() *pb.ThreadHeader {
func (t *inMemoryTreeStorage) Header() (*treepb.TreeHeader, error) {
t.RLock()
defer t.RUnlock()
return t.header
return t.header, nil
}
func (t *inMemoryThread) Heads() []string {
func (t *inMemoryTreeStorage) Heads() ([]string, error) {
t.RLock()
defer t.RUnlock()
return t.heads
return t.heads, nil
}
func (t *inMemoryThread) Orphans() []string {
func (t *inMemoryTreeStorage) Orphans() ([]string, error) {
t.RLock()
defer t.RUnlock()
return t.orphans
return t.orphans, nil
}
func (t *inMemoryThread) SetHeads(heads []string) {
func (t *inMemoryTreeStorage) SetHeads(heads []string) error {
t.Lock()
defer t.Unlock()
t.heads = t.heads[:0]
@ -80,21 +80,24 @@ func (t *inMemoryThread) SetHeads(heads []string) {
for _, h := range heads {
t.heads = append(t.heads, h)
}
return nil
}
func (t *inMemoryThread) RemoveOrphans(orphans ...string) {
func (t *inMemoryTreeStorage) RemoveOrphans(orphans ...string) error {
t.Lock()
defer t.Unlock()
t.orphans = slice.Difference(t.orphans, orphans)
return nil
}
func (t *inMemoryThread) AddOrphans(orphans ...string) {
func (t *inMemoryTreeStorage) AddOrphans(orphans ...string) error {
t.Lock()
defer t.Unlock()
t.orphans = append(t.orphans, orphans...)
return nil
}
func (t *inMemoryThread) AddRawChange(change *RawChange) error {
func (t *inMemoryTreeStorage) AddRawChange(change *RawChange) error {
t.Lock()
defer t.Unlock()
// TODO: better to do deep copy
@ -102,7 +105,7 @@ func (t *inMemoryThread) AddRawChange(change *RawChange) error {
return nil
}
func (t *inMemoryThread) AddChange(change aclchanges.Change) error {
func (t *inMemoryTreeStorage) AddChange(change aclchanges.Change) error {
t.Lock()
defer t.Unlock()
signature := change.Signature()
@ -122,7 +125,7 @@ func (t *inMemoryThread) AddChange(change aclchanges.Change) error {
return nil
}
func (t *inMemoryThread) GetChange(ctx context.Context, changeId string) (*RawChange, error) {
func (t *inMemoryTreeStorage) GetChange(ctx context.Context, changeId string) (*RawChange, error) {
t.RLock()
defer t.RUnlock()
if res, exists := t.changes[changeId]; exists {

View File

@ -1,21 +1,20 @@
package thread
package treestorage
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/thread/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb"
)
// TODO: change methods to have errors as a return parameter, because we will be dealing with a real database
type Thread interface {
ID() string
type TreeStorage interface {
TreeID() (string, error)
Header() *pb.ThreadHeader
Heads() []string
Orphans() []string
SetHeads(heads []string)
RemoveOrphans(orphan ...string)
AddOrphans(orphan ...string)
Header() (*treepb.TreeHeader, error)
Heads() ([]string, error)
Orphans() ([]string, error)
SetHeads(heads []string) error
RemoveOrphans(orphan ...string) error
AddOrphans(orphan ...string) error
AddRawChange(change *RawChange) error
AddChange(change aclchanges.Change) error

View File

@ -1,8 +1,8 @@
syntax = "proto3";
package anytype;
option go_package = "pb";
option go_package = "treepb";
message ThreadHeader {
message TreeHeader {
string firstChangeId = 1;
bool isWorkspace = 2;
// TODO: add user identity, signature and nano timestamp

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: thread/pb/protos/thread.proto
// source: pkg/acl/treestorage/treepb/protos/tree.proto
package pb
package treepb
import (
fmt "fmt"
@ -22,23 +22,23 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type ThreadHeader struct {
type TreeHeader struct {
FirstChangeId string `protobuf:"bytes,1,opt,name=firstChangeId,proto3" json:"firstChangeId,omitempty"`
IsWorkspace bool `protobuf:"varint,2,opt,name=isWorkspace,proto3" json:"isWorkspace,omitempty"`
}
func (m *ThreadHeader) Reset() { *m = ThreadHeader{} }
func (m *ThreadHeader) String() string { return proto.CompactTextString(m) }
func (*ThreadHeader) ProtoMessage() {}
func (*ThreadHeader) Descriptor() ([]byte, []int) {
return fileDescriptor_b228ffbfd554b168, []int{0}
func (m *TreeHeader) Reset() { *m = TreeHeader{} }
func (m *TreeHeader) String() string { return proto.CompactTextString(m) }
func (*TreeHeader) ProtoMessage() {}
func (*TreeHeader) Descriptor() ([]byte, []int) {
return fileDescriptor_e7d760b855878644, []int{0}
}
func (m *ThreadHeader) XXX_Unmarshal(b []byte) error {
func (m *TreeHeader) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ThreadHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
func (m *TreeHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ThreadHeader.Marshal(b, m, deterministic)
return xxx_messageInfo_TreeHeader.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
@ -48,26 +48,26 @@ func (m *ThreadHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
return b[:n], nil
}
}
func (m *ThreadHeader) XXX_Merge(src proto.Message) {
xxx_messageInfo_ThreadHeader.Merge(m, src)
func (m *TreeHeader) XXX_Merge(src proto.Message) {
xxx_messageInfo_TreeHeader.Merge(m, src)
}
func (m *ThreadHeader) XXX_Size() int {
func (m *TreeHeader) XXX_Size() int {
return m.Size()
}
func (m *ThreadHeader) XXX_DiscardUnknown() {
xxx_messageInfo_ThreadHeader.DiscardUnknown(m)
func (m *TreeHeader) XXX_DiscardUnknown() {
xxx_messageInfo_TreeHeader.DiscardUnknown(m)
}
var xxx_messageInfo_ThreadHeader proto.InternalMessageInfo
var xxx_messageInfo_TreeHeader proto.InternalMessageInfo
func (m *ThreadHeader) GetFirstChangeId() string {
func (m *TreeHeader) GetFirstChangeId() string {
if m != nil {
return m.FirstChangeId
}
return ""
}
func (m *ThreadHeader) GetIsWorkspace() bool {
func (m *TreeHeader) GetIsWorkspace() bool {
if m != nil {
return m.IsWorkspace
}
@ -75,26 +75,29 @@ func (m *ThreadHeader) GetIsWorkspace() bool {
}
func init() {
proto.RegisterType((*ThreadHeader)(nil), "anytype.ThreadHeader")
proto.RegisterType((*TreeHeader)(nil), "anytype.TreeHeader")
}
func init() { proto.RegisterFile("thread/pb/protos/thread.proto", fileDescriptor_b228ffbfd554b168) }
var fileDescriptor_b228ffbfd554b168 = []byte{
// 156 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2d, 0xc9, 0x28, 0x4a,
0x4d, 0x4c, 0xd1, 0x2f, 0x48, 0xd2, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x2f, 0xd6, 0x87, 0x08, 0xe8,
0x81, 0x79, 0x42, 0xec, 0x89, 0x79, 0x95, 0x25, 0x95, 0x05, 0xa9, 0x4a, 0x61, 0x5c, 0x3c, 0x21,
0x60, 0x09, 0x8f, 0xd4, 0xc4, 0x94, 0xd4, 0x22, 0x21, 0x15, 0x2e, 0xde, 0xb4, 0xcc, 0xa2, 0xe2,
0x12, 0xe7, 0x8c, 0xc4, 0xbc, 0xf4, 0x54, 0xcf, 0x14, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20,
0x54, 0x41, 0x21, 0x05, 0x2e, 0xee, 0xcc, 0xe2, 0xf0, 0xfc, 0xa2, 0xec, 0xe2, 0x82, 0xc4, 0xe4,
0x54, 0x09, 0x26, 0x05, 0x46, 0x0d, 0x8e, 0x20, 0x64, 0x21, 0x27, 0x99, 0x13, 0x8f, 0xe4, 0x18,
0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5,
0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x62, 0x2a, 0x48, 0x4a, 0x62, 0x03, 0xbb, 0xc2, 0x18, 0x10,
0x00, 0x00, 0xff, 0xff, 0x2a, 0xae, 0x9d, 0xc2, 0xa6, 0x00, 0x00, 0x00,
func init() {
proto.RegisterFile("pkg/acl/treestorage/treepb/protos/tree.proto", fileDescriptor_e7d760b855878644)
}
func (m *ThreadHeader) Marshal() (dAtA []byte, err error) {
var fileDescriptor_e7d760b855878644 = []byte{
// 170 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x29, 0xc8, 0x4e, 0xd7,
0x4f, 0x4c, 0xce, 0xd1, 0x2f, 0x29, 0x4a, 0x4d, 0x2d, 0x2e, 0xc9, 0x2f, 0x4a, 0x4c, 0x4f, 0x05,
0xb3, 0x0b, 0x92, 0xf4, 0x0b, 0x8a, 0xf2, 0x4b, 0xf2, 0x8b, 0xc1, 0x3c, 0x3d, 0x30, 0x5b, 0x88,
0x3d, 0x31, 0xaf, 0xb2, 0xa4, 0xb2, 0x20, 0x55, 0x29, 0x84, 0x8b, 0x2b, 0xa4, 0x28, 0x35, 0xd5,
0x23, 0x35, 0x31, 0x25, 0xb5, 0x48, 0x48, 0x85, 0x8b, 0x37, 0x2d, 0xb3, 0xa8, 0xb8, 0xc4, 0x39,
0x23, 0x31, 0x2f, 0x3d, 0xd5, 0x33, 0x45, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0x55, 0x50,
0x48, 0x81, 0x8b, 0x3b, 0xb3, 0x38, 0x3c, 0xbf, 0x28, 0xbb, 0xb8, 0x20, 0x31, 0x39, 0x55, 0x82,
0x49, 0x81, 0x51, 0x83, 0x23, 0x08, 0x59, 0xc8, 0x49, 0xe1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f,
0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b,
0x8f, 0xe5, 0x18, 0xa2, 0xd8, 0x20, 0x4e, 0x4a, 0x62, 0x03, 0xbb, 0xc3, 0x18, 0x10, 0x00, 0x00,
0xff, 0xff, 0xb1, 0x3f, 0x66, 0x17, 0xb7, 0x00, 0x00, 0x00,
}
func (m *TreeHeader) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -104,12 +107,12 @@ func (m *ThreadHeader) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
func (m *ThreadHeader) MarshalTo(dAtA []byte) (int, error) {
func (m *TreeHeader) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ThreadHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *TreeHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
@ -127,15 +130,15 @@ func (m *ThreadHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) {
if len(m.FirstChangeId) > 0 {
i -= len(m.FirstChangeId)
copy(dAtA[i:], m.FirstChangeId)
i = encodeVarintThread(dAtA, i, uint64(len(m.FirstChangeId)))
i = encodeVarintTree(dAtA, i, uint64(len(m.FirstChangeId)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintThread(dAtA []byte, offset int, v uint64) int {
offset -= sovThread(v)
func encodeVarintTree(dAtA []byte, offset int, v uint64) int {
offset -= sovTree(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@ -145,7 +148,7 @@ func encodeVarintThread(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
return base
}
func (m *ThreadHeader) Size() (n int) {
func (m *TreeHeader) Size() (n int) {
if m == nil {
return 0
}
@ -153,7 +156,7 @@ func (m *ThreadHeader) Size() (n int) {
_ = l
l = len(m.FirstChangeId)
if l > 0 {
n += 1 + l + sovThread(uint64(l))
n += 1 + l + sovTree(uint64(l))
}
if m.IsWorkspace {
n += 2
@ -161,13 +164,13 @@ func (m *ThreadHeader) Size() (n int) {
return n
}
func sovThread(x uint64) (n int) {
func sovTree(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozThread(x uint64) (n int) {
return sovThread(uint64((x << 1) ^ uint64((int64(x) >> 63))))
func sozTree(x uint64) (n int) {
return sovTree(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *ThreadHeader) Unmarshal(dAtA []byte) error {
func (m *TreeHeader) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@ -175,7 +178,7 @@ func (m *ThreadHeader) Unmarshal(dAtA []byte) error {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowThread
return ErrIntOverflowTree
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -190,10 +193,10 @@ func (m *ThreadHeader) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ThreadHeader: wiretype end group for non-group")
return fmt.Errorf("proto: TreeHeader: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ThreadHeader: illegal tag %d (wire type %d)", fieldNum, wire)
return fmt.Errorf("proto: TreeHeader: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
@ -203,7 +206,7 @@ func (m *ThreadHeader) Unmarshal(dAtA []byte) error {
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowThread
return ErrIntOverflowTree
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -217,11 +220,11 @@ func (m *ThreadHeader) Unmarshal(dAtA []byte) error {
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthThread
return ErrInvalidLengthTree
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthThread
return ErrInvalidLengthTree
}
if postIndex > l {
return io.ErrUnexpectedEOF
@ -235,7 +238,7 @@ func (m *ThreadHeader) Unmarshal(dAtA []byte) error {
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowThread
return ErrIntOverflowTree
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
@ -250,12 +253,12 @@ func (m *ThreadHeader) Unmarshal(dAtA []byte) error {
m.IsWorkspace = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipThread(dAtA[iNdEx:])
skippy, err := skipTree(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthThread
return ErrInvalidLengthTree
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
@ -269,7 +272,7 @@ func (m *ThreadHeader) Unmarshal(dAtA []byte) error {
}
return nil
}
func skipThread(dAtA []byte) (n int, err error) {
func skipTree(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
@ -277,7 +280,7 @@ func skipThread(dAtA []byte) (n int, err error) {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowThread
return 0, ErrIntOverflowTree
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
@ -294,7 +297,7 @@ func skipThread(dAtA []byte) (n int, err error) {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowThread
return 0, ErrIntOverflowTree
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
@ -310,7 +313,7 @@ func skipThread(dAtA []byte) (n int, err error) {
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowThread
return 0, ErrIntOverflowTree
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
@ -323,14 +326,14 @@ func skipThread(dAtA []byte) (n int, err error) {
}
}
if length < 0 {
return 0, ErrInvalidLengthThread
return 0, ErrInvalidLengthTree
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupThread
return 0, ErrUnexpectedEndOfGroupTree
}
depth--
case 5:
@ -339,7 +342,7 @@ func skipThread(dAtA []byte) (n int, err error) {
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthThread
return 0, ErrInvalidLengthTree
}
if depth == 0 {
return iNdEx, nil
@ -349,7 +352,7 @@ func skipThread(dAtA []byte) (n int, err error) {
}
var (
ErrInvalidLengthThread = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowThread = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupThread = fmt.Errorf("proto: unexpected end of group")
ErrInvalidLengthTree = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowTree = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupTree = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -0,0 +1,16 @@
package encryptionkey
import "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
type PrivKey interface {
keys.Key
Decrypt([]byte) ([]byte, error)
GetPublic() PubKey
}
type PubKey interface {
keys.Key
Encrypt(data []byte) ([]byte, error)
}

View File

@ -0,0 +1,120 @@
package encryptionkey
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha512"
"crypto/subtle"
"crypto/x509"
"errors"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"io"
)
var MinRsaKeyBits = 2048
var ErrKeyLengthTooSmall = errors.New("error key length too small")
type EncryptionRsaPrivKey struct {
privKey rsa.PrivateKey
}
type EncryptionRsaPubKey struct {
pubKey rsa.PublicKey
}
func (e *EncryptionRsaPubKey) Equals(key keys.Key) bool {
other, ok := (key).(*EncryptionRsaPubKey)
if !ok {
return keyEquals(e, key)
}
return e.pubKey.N.Cmp(other.pubKey.N) == 0 && e.pubKey.E == other.pubKey.E
}
func (e *EncryptionRsaPubKey) Raw() ([]byte, error) {
return x509.MarshalPKIXPublicKey(&e.pubKey)
}
func (e *EncryptionRsaPubKey) Encrypt(data []byte) ([]byte, error) {
hash := sha512.New()
return rsa.EncryptOAEP(hash, rand.Reader, &e.pubKey, data, nil)
}
func (e *EncryptionRsaPrivKey) Equals(key keys.Key) bool {
other, ok := (key).(*EncryptionRsaPrivKey)
if !ok {
return keyEquals(e, key)
}
return e.privKey.N.Cmp(other.privKey.N) == 0 && e.privKey.E == other.privKey.E
}
func (e *EncryptionRsaPrivKey) Raw() ([]byte, error) {
b := x509.MarshalPKCS1PrivateKey(&e.privKey)
return b, nil
}
func (e *EncryptionRsaPrivKey) Decrypt(bytes []byte) ([]byte, error) {
hash := sha512.New()
return rsa.DecryptOAEP(hash, rand.Reader, &e.privKey, bytes, nil)
}
func (e *EncryptionRsaPrivKey) GetPublic() PubKey {
return &EncryptionRsaPubKey{pubKey: e.privKey.PublicKey}
}
func GenerateRandomRSAKeyPair(bits int) (PrivKey, PubKey, error) {
return GenerateRSAKeyPair(bits, rand.Reader)
}
func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
if bits < MinRsaKeyBits {
return nil, nil, ErrKeyLengthTooSmall
}
priv, err := rsa.GenerateKey(src, bits)
if err != nil {
return nil, nil, err
}
pk := priv.PublicKey
return &EncryptionRsaPrivKey{privKey: *priv}, &EncryptionRsaPubKey{pubKey: pk}, nil
}
func NewEncryptionRsaPrivKeyFromBytes(bytes []byte) (PrivKey, error) {
sk, err := x509.ParsePKCS1PrivateKey(bytes)
if err != nil {
return nil, err
}
if sk.N.BitLen() < MinRsaKeyBits {
return nil, ErrKeyLengthTooSmall
}
return &EncryptionRsaPrivKey{privKey: *sk}, nil
}
func NewEncryptionRsaPubKeyFromBytes(bytes []byte) (PubKey, error) {
pub, err := x509.ParsePKIXPublicKey(bytes)
if err != nil {
return nil, err
}
pk, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, errors.New("not actually an rsa public key")
}
if pk.N.BitLen() < MinRsaKeyBits {
return nil, ErrKeyLengthTooSmall
}
return &EncryptionRsaPubKey{pubKey: *pk}, nil
}
func keyEquals(k1, k2 keys.Key) bool {
a, err := k1.Raw()
if err != nil {
return false
}
b, err := k2.Raw()
if err != nil {
return false
}
return subtle.ConstantTimeCompare(a, b) == 1
}

View File

@ -0,0 +1,176 @@
package signingkey
import (
"bytes"
"crypto/ed25519"
"crypto/rand"
"crypto/subtle"
"errors"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"io"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/strkey"
)
// Ed25519PrivateKey is an ed25519 private key.
type Ed25519PrivateKey struct {
k ed25519.PrivateKey
}
// Ed25519PublicKey is an ed25519 public key.
type Ed25519PublicKey struct {
k ed25519.PublicKey
}
func NewSigningEd25519PubKeyFromBytes(bytes []byte) (PubKey, error) {
return UnmarshalEd25519PublicKey(bytes)
}
func GenerateRandomEd25519KeyPair() (PrivKey, PubKey, error) {
return GenerateEd25519Key(rand.Reader)
}
// GenerateEd25519Key generates a new ed25519 private and public key pair.
func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) {
pub, priv, err := ed25519.GenerateKey(src)
if err != nil {
return nil, nil, err
}
return &Ed25519PrivateKey{
k: priv,
},
&Ed25519PublicKey{
k: pub,
},
nil
}
// Raw private key bytes.
func (k *Ed25519PrivateKey) Raw() ([]byte, error) {
// The Ed25519 private key contains two 32-bytes curve points, the private
// key and the public key.
// It makes it more efficient to get the public key without re-computing an
// elliptic curve multiplication.
buf := make([]byte, len(k.k))
copy(buf, k.k)
return buf, nil
}
func (k *Ed25519PrivateKey) pubKeyBytes() []byte {
return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:]
}
// Equals compares two ed25519 private keys.
func (k *Ed25519PrivateKey) Equals(o keys.Key) bool {
edk, ok := o.(*Ed25519PrivateKey)
if !ok {
return keys.KeyEquals(k, o)
}
return subtle.ConstantTimeCompare(k.k, edk.k) == 1
}
// GetPublic returns an ed25519 public key from a private key.
func (k *Ed25519PrivateKey) GetPublic() PubKey {
return &Ed25519PublicKey{k: k.pubKeyBytes()}
}
// Sign returns a signature from an input message.
func (k *Ed25519PrivateKey) Sign(msg []byte) ([]byte, error) {
return ed25519.Sign(k.k, msg), nil
}
// Raw public key bytes.
func (k *Ed25519PublicKey) Raw() ([]byte, error) {
return k.k, nil
}
// Equals compares two ed25519 public keys.
func (k *Ed25519PublicKey) Equals(o keys.Key) bool {
edk, ok := o.(*Ed25519PublicKey)
if !ok {
return keys.KeyEquals(k, o)
}
return bytes.Equal(k.k, edk.k)
}
// Verify checks a signature agains the input data.
func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (bool, error) {
return ed25519.Verify(k.k, data, sig), nil
}
// UnmarshalEd25519PublicKey returns a public key from input bytes.
func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) {
if len(data) != 32 {
return nil, errors.New("expect ed25519 public key data size to be 32")
}
return &Ed25519PublicKey{
k: ed25519.PublicKey(data),
}, nil
}
// UnmarshalEd25519PrivateKey returns a private key from input bytes.
func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) {
switch len(data) {
case ed25519.PrivateKeySize + ed25519.PublicKeySize:
// Remove the redundant public key. See issue #36.
redundantPk := data[ed25519.PrivateKeySize:]
pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize]
if subtle.ConstantTimeCompare(pk, redundantPk) == 0 {
return nil, errors.New("expected redundant ed25519 public key to be redundant")
}
// No point in storing the extra data.
newKey := make([]byte, ed25519.PrivateKeySize)
copy(newKey, data[:ed25519.PrivateKeySize])
data = newKey
case ed25519.PrivateKeySize:
default:
return nil, fmt.Errorf(
"expected ed25519 data size to be %d or %d, got %d",
ed25519.PrivateKeySize,
ed25519.PrivateKeySize+ed25519.PublicKeySize,
len(data),
)
}
return &Ed25519PrivateKey{
k: ed25519.PrivateKey(data),
}, nil
}
type Ed25519SigningPubKeyDecoder struct{}
func NewEd25519Decoder() PubKeyDecoder {
return &Ed25519SigningPubKeyDecoder{}
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromBytes(bytes []byte) (PubKey, error) {
return NewSigningEd25519PubKeyFromBytes(bytes)
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromString(identity string) (PubKey, error) {
pubKeyRaw, err := strkey.Decode(0x5b, identity)
if err != nil {
return nil, err
}
return e.DecodeFromBytes(pubKeyRaw)
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromStringIntoBytes(identity string) ([]byte, error) {
return strkey.Decode(0x5b, identity)
}
func (e *Ed25519SigningPubKeyDecoder) EncodeToString(pubkey PubKey) (string, error) {
raw, err := pubkey.Raw()
if err != nil {
return "", err
}
return strkey.Encode(0x5b, raw)
}

View File

@ -0,0 +1,24 @@
package signingkey
import "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
type PrivKey interface {
keys.Key
Sign([]byte) ([]byte, error)
GetPublic() PubKey
}
type PubKey interface {
keys.Key
Verify(data []byte, sig []byte) (bool, error)
}
type PubKeyDecoder interface {
DecodeFromBytes(bytes []byte) (PubKey, error)
DecodeFromString(identity string) (PubKey, error)
DecodeFromStringIntoBytes(identity string) ([]byte, error)
EncodeToString(pubkey PubKey) (string, error)
}

21
util/keys/key.go Normal file
View File

@ -0,0 +1,21 @@
package keys
import "crypto/subtle"
type Key interface {
Equals(Key) bool
Raw() ([]byte, error)
}
func KeyEquals(k1, k2 Key) bool {
a, err := k1.Raw()
if err != nil {
return false
}
b, err := k2.Raw()
if err != nil {
return false
}
return subtle.ConstantTimeCompare(a, b) == 1
}

View File

@ -1,256 +0,0 @@
package keys
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha512"
"crypto/subtle"
"crypto/x509"
"errors"
"io"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/strkey"
"github.com/libp2p/go-libp2p-core/crypto"
crypto_pb "github.com/libp2p/go-libp2p-core/crypto/pb"
)
type SigningPubKey crypto.PubKey
type SigningPrivKey crypto.PrivKey
var MinRsaKeyBits = 2048
var ErrKeyLengthTooSmall = errors.New("error key length too small")
type Key interface {
Equals(Key) bool
Raw() ([]byte, error)
}
type EncryptionPrivKey interface {
Key
Decrypt([]byte) ([]byte, error)
GetPublic() EncryptionPubKey
}
type EncryptionPubKey interface {
Key
Encrypt(data []byte) ([]byte, error)
}
type EncryptionRsaPrivKey struct {
privKey rsa.PrivateKey
}
type EncryptionRsaPubKey struct {
pubKey rsa.PublicKey
}
func (e *EncryptionRsaPubKey) Equals(key Key) bool {
other, ok := (key).(*EncryptionRsaPubKey)
if !ok {
return keyEquals(e, key)
}
return e.pubKey.N.Cmp(other.pubKey.N) == 0 && e.pubKey.E == other.pubKey.E
}
func (e *EncryptionRsaPubKey) Raw() ([]byte, error) {
return x509.MarshalPKIXPublicKey(&e.pubKey)
}
func (e *EncryptionRsaPubKey) Encrypt(data []byte) ([]byte, error) {
hash := sha512.New()
return rsa.EncryptOAEP(hash, rand.Reader, &e.pubKey, data, nil)
}
func (e *EncryptionRsaPrivKey) Equals(key Key) bool {
other, ok := (key).(*EncryptionRsaPrivKey)
if !ok {
return keyEquals(e, key)
}
return e.privKey.N.Cmp(other.privKey.N) == 0 && e.privKey.E == other.privKey.E
}
func (e *EncryptionRsaPrivKey) Raw() ([]byte, error) {
b := x509.MarshalPKCS1PrivateKey(&e.privKey)
return b, nil
}
func (e *EncryptionRsaPrivKey) Decrypt(bytes []byte) ([]byte, error) {
hash := sha512.New()
return rsa.DecryptOAEP(hash, rand.Reader, &e.privKey, bytes, nil)
}
func (e *EncryptionRsaPrivKey) GetPublic() EncryptionPubKey {
return &EncryptionRsaPubKey{pubKey: e.privKey.PublicKey}
}
func GenerateRandomRSAKeyPair(bits int) (EncryptionPrivKey, EncryptionPubKey, error) {
return GenerateRSAKeyPair(bits, rand.Reader)
}
func GenerateRSAKeyPair(bits int, src io.Reader) (EncryptionPrivKey, EncryptionPubKey, error) {
if bits < MinRsaKeyBits {
return nil, nil, ErrKeyLengthTooSmall
}
priv, err := rsa.GenerateKey(src, bits)
if err != nil {
return nil, nil, err
}
pk := priv.PublicKey
return &EncryptionRsaPrivKey{privKey: *priv}, &EncryptionRsaPubKey{pubKey: pk}, nil
}
func NewEncryptionRsaPrivKeyFromBytes(bytes []byte) (EncryptionPrivKey, error) {
sk, err := x509.ParsePKCS1PrivateKey(bytes)
if err != nil {
return nil, err
}
if sk.N.BitLen() < MinRsaKeyBits {
return nil, ErrKeyLengthTooSmall
}
return &EncryptionRsaPrivKey{privKey: *sk}, nil
}
func NewEncryptionRsaPubKeyFromBytes(bytes []byte) (EncryptionPubKey, error) {
pub, err := x509.ParsePKIXPublicKey(bytes)
if err != nil {
return nil, err
}
pk, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, errors.New("not actually an rsa public key")
}
if pk.N.BitLen() < MinRsaKeyBits {
return nil, ErrKeyLengthTooSmall
}
return &EncryptionRsaPubKey{pubKey: *pk}, nil
}
func NewSigningEd25519PubKeyFromBytes(bytes []byte) (SigningPubKey, error) {
return crypto.UnmarshalEd25519PublicKey(bytes)
}
func GenerateRandomEd25519KeyPair() (SigningPrivKey, SigningPubKey, error) {
return crypto.GenerateEd25519Key(rand.Reader)
}
func keyEquals(k1, k2 Key) bool {
a, err := k1.Raw()
if err != nil {
return false
}
b, err := k2.Raw()
if err != nil {
return false
}
return subtle.ConstantTimeCompare(a, b) == 1
}
type Ed25519SigningPubKeyDecoder struct{}
func NewEd25519Decoder() *Ed25519SigningPubKeyDecoder {
return &Ed25519SigningPubKeyDecoder{}
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromBytes(bytes []byte) (SigningPubKey, error) {
return NewSigningEd25519PubKeyFromBytes(bytes)
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromString(identity string) (SigningPubKey, error) {
pubKeyRaw, err := strkey.Decode(0x5b, identity)
if err != nil {
return nil, err
}
return e.DecodeFromBytes(pubKeyRaw)
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromStringIntoBytes(identity string) ([]byte, error) {
return strkey.Decode(0x5b, identity)
}
func (e *Ed25519SigningPubKeyDecoder) EncodeToString(pubkey crypto.PubKey) (string, error) {
raw, err := pubkey.Raw()
if err != nil {
return "", err
}
return strkey.Encode(0x5b, raw)
}
type SigningPubKeyDecoder interface {
DecodeFromBytes(bytes []byte) (SigningPubKey, error)
DecodeFromString(identity string) (SigningPubKey, error)
DecodeFromStringIntoBytes(identity string) ([]byte, error)
}
// Below keys are required for testing and mocking purposes
type EmptyRecorderEncryptionKey struct {
recordedEncrypted [][]byte
recordedDecrypted [][]byte
}
func (f *EmptyRecorderEncryptionKey) Equals(key Key) bool {
return true
}
func (f *EmptyRecorderEncryptionKey) Raw() ([]byte, error) {
panic("can't get bytes from this key")
}
func (f *EmptyRecorderEncryptionKey) GetPublic() EncryptionPubKey {
panic("this key doesn't have a public key")
}
func (f *EmptyRecorderEncryptionKey) Encrypt(msg []byte) ([]byte, error) {
f.recordedEncrypted = append(f.recordedEncrypted, msg)
return msg, nil
}
func (f *EmptyRecorderEncryptionKey) Decrypt(msg []byte) ([]byte, error) {
f.recordedDecrypted = append(f.recordedDecrypted, msg)
return msg, nil
}
type SignatureVerificationPayload struct {
message []byte
signature []byte
}
type EmptyRecorderVerificationKey struct {
verifications []SignatureVerificationPayload
}
func (e *EmptyRecorderVerificationKey) Bytes() ([]byte, error) {
panic("can't get bytes from this key")
}
func (e *EmptyRecorderVerificationKey) Equals(key crypto.Key) bool {
return true
}
func (e *EmptyRecorderVerificationKey) Raw() ([]byte, error) {
panic("can't get bytes from this key")
}
func (e *EmptyRecorderVerificationKey) Type() crypto_pb.KeyType {
panic("can't get type from this key")
}
func (e *EmptyRecorderVerificationKey) Verify(data []byte, sig []byte) (bool, error) {
e.verifications = append(e.verifications, SignatureVerificationPayload{
message: data,
signature: sig,
})
return true, nil
}
func NewMockSigningPubKeyFromBytes(bytes []byte) (SigningPubKey, error) {
return &EmptyRecorderVerificationKey{}, nil
}

View File

@ -0,0 +1,133 @@
package symmetric
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
mbase "github.com/multiformats/go-multibase"
)
const (
// NonceBytes is the length of GCM nonce.
NonceBytes = 12
// KeyBytes is the length of GCM key.
KeyBytes = 32
)
type Key struct {
raw []byte
}
func (k *Key) Equals(otherKey *Key) bool {
otherRaw := otherKey.raw
keyRaw := k.raw
if len(keyRaw) != len(otherRaw) {
return false
}
for i := 0; i < len(keyRaw); i++ {
if keyRaw[i] != otherRaw[i] {
return false
}
}
return true
}
func (k *Key) Raw() ([]byte, error) {
return k.raw, nil
}
// NewRandom returns a random key.
func NewRandom() (*Key, error) {
raw := make([]byte, KeyBytes)
if _, err := rand.Read(raw); err != nil {
return nil, err
}
return &Key{raw: raw}, nil
}
// New returns Key if err is nil and panics otherwise.
func New() *Key {
k, err := NewRandom()
if err != nil {
panic(err)
}
return k
}
// FromBytes returns a key by decoding bytes.
func FromBytes(k []byte) (*Key, error) {
if len(k) != KeyBytes {
return nil, fmt.Errorf("invalid key")
}
return &Key{raw: k}, nil
}
// FromString returns a key by decoding a base32-encoded string.
func FromString(k string) (*Key, error) {
_, b, err := mbase.Decode(k)
if err != nil {
return nil, err
}
return FromBytes(b)
}
// Bytes returns raw key bytes.
func (k *Key) Bytes() []byte {
return k.raw
}
// MarshalBinary implements BinaryMarshaler.
func (k *Key) MarshalBinary() ([]byte, error) {
return k.raw, nil
}
// String returns the base32-encoded string representation of raw key bytes.
func (k *Key) String() string {
str, err := mbase.Encode(mbase.Base32, k.raw)
if err != nil {
panic("should not error with hardcoded mbase: " + err.Error())
}
return str
}
// Encrypt performs AES-256 GCM encryption on plaintext.
func (k *Key) Encrypt(plaintext []byte) ([]byte, error) {
block, err := aes.NewCipher(k.raw[:KeyBytes])
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonce := make([]byte, NonceBytes)
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)
ciphertext = append(nonce[:], ciphertext...)
return ciphertext, nil
}
// Decrypt uses key to perform AES-256 GCM decryption on ciphertext.
func (k *Key) Decrypt(ciphertext []byte) ([]byte, error) {
block, err := aes.NewCipher(k.raw[:KeyBytes])
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonce := ciphertext[:NonceBytes]
plain, err := aesgcm.Open(nil, nonce, ciphertext[NonceBytes:], nil)
if err != nil {
return nil, err
}
return plain, nil
}