WIP change package structure
This commit is contained in:
parent
94f53aabe1
commit
ee123efd7d
@ -1,4 +1,4 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -6,8 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/acltree/pb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
"github.com/textileio/go-threads/crypto/symmetric"
|
"github.com/textileio/go-threads/crypto/symmetric"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,22 +17,22 @@ var ErrUserRemoved = errors.New("user was removed from the document")
|
|||||||
var ErrDocumentForbidden = errors.New("your user was forbidden access to the document")
|
var ErrDocumentForbidden = errors.New("your user was forbidden access to the document")
|
||||||
var ErrUserAlreadyExists = errors.New("user already exists")
|
var ErrUserAlreadyExists = errors.New("user already exists")
|
||||||
|
|
||||||
type ACLState struct {
|
type aclState struct {
|
||||||
currentReadKeyHash uint64
|
currentReadKeyHash uint64
|
||||||
userReadKeys map[uint64]*symmetric.Key
|
userReadKeys map[uint64]*symmetric.Key
|
||||||
userStates map[string]*pb.ACLChangeUserState
|
userStates map[string]*pb.ACLChangeUserState
|
||||||
userInvites map[string]*pb.ACLChangeUserInvite
|
userInvites map[string]*pb.ACLChangeUserInvite
|
||||||
signingPubKeyDecoder threadmodels.SigningPubKeyDecoder
|
signingPubKeyDecoder keys.SigningPubKeyDecoder
|
||||||
encryptionKey threadmodels.EncryptionPrivKey
|
encryptionKey keys.EncryptionPrivKey
|
||||||
identity string
|
identity string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewACLStateFromSnapshot(
|
func NewACLStateFromSnapshot(
|
||||||
snapshot *pb.ACLChangeACLSnapshot,
|
snapshot *pb.ACLChangeACLSnapshot,
|
||||||
identity string,
|
identity string,
|
||||||
encryptionKey threadmodels.EncryptionPrivKey,
|
encryptionKey keys.EncryptionPrivKey,
|
||||||
signingPubKeyDecoder threadmodels.SigningPubKeyDecoder) (*ACLState, error) {
|
signingPubKeyDecoder keys.SigningPubKeyDecoder) (*aclState, error) {
|
||||||
st := &ACLState{
|
st := &aclState{
|
||||||
identity: identity,
|
identity: identity,
|
||||||
encryptionKey: encryptionKey,
|
encryptionKey: encryptionKey,
|
||||||
userReadKeys: make(map[uint64]*symmetric.Key),
|
userReadKeys: make(map[uint64]*symmetric.Key),
|
||||||
@ -47,7 +47,7 @@ func NewACLStateFromSnapshot(
|
|||||||
return st, nil
|
return st, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) recreateFromSnapshot(snapshot *pb.ACLChangeACLSnapshot) error {
|
func (st *aclState) recreateFromSnapshot(snapshot *pb.ACLChangeACLSnapshot) error {
|
||||||
state := snapshot.AclState
|
state := snapshot.AclState
|
||||||
for _, userState := range state.UserStates {
|
for _, userState := range state.UserStates {
|
||||||
st.userStates[userState.Identity] = userState
|
st.userStates[userState.Identity] = userState
|
||||||
@ -74,7 +74,7 @@ func (st *ACLState) recreateFromSnapshot(snapshot *pb.ACLChangeACLSnapshot) erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) ApplyChange(changeId string, change *pb.ACLChange) error {
|
func (st *aclState) ApplyChange(changeId string, change *pb.ACLChange) error {
|
||||||
// we can't check this for the user which is joining, because it will not be in our list
|
// we can't check this for the user which is joining, because it will not be in our list
|
||||||
if !st.isUserJoin(change) {
|
if !st.isUserJoin(change) {
|
||||||
// we check signature when we add this to the tree, so no need to do it here
|
// we check signature when we add this to the tree, so no need to do it here
|
||||||
@ -98,7 +98,7 @@ func (st *ACLState) ApplyChange(changeId string, change *pb.ACLChange) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove changeId, because it is not needed
|
// TODO: remove changeId, because it is not needed
|
||||||
func (st *ACLState) applyChange(changeId string, ch *pb.ACLChangeACLContentValue) error {
|
func (st *aclState) applyChange(changeId string, ch *pb.ACLChangeACLContentValue) error {
|
||||||
switch {
|
switch {
|
||||||
case ch.GetUserPermissionChange() != nil:
|
case ch.GetUserPermissionChange() != nil:
|
||||||
return st.applyUserPermissionChange(ch.GetUserPermissionChange())
|
return st.applyUserPermissionChange(ch.GetUserPermissionChange())
|
||||||
@ -117,7 +117,7 @@ func (st *ACLState) applyChange(changeId string, ch *pb.ACLChangeACLContentValue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) applyUserPermissionChange(ch *pb.ACLChangeUserPermissionChange) error {
|
func (st *aclState) applyUserPermissionChange(ch *pb.ACLChangeUserPermissionChange) error {
|
||||||
if _, exists := st.userStates[ch.Identity]; !exists {
|
if _, exists := st.userStates[ch.Identity]; !exists {
|
||||||
return ErrNoSuchUser
|
return ErrNoSuchUser
|
||||||
}
|
}
|
||||||
@ -126,12 +126,12 @@ func (st *ACLState) applyUserPermissionChange(ch *pb.ACLChangeUserPermissionChan
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) applyUserInvite(changeId string, ch *pb.ACLChangeUserInvite) error {
|
func (st *aclState) applyUserInvite(changeId string, ch *pb.ACLChangeUserInvite) error {
|
||||||
st.userInvites[changeId] = ch
|
st.userInvites[changeId] = ch
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) applyUserJoin(ch *pb.ACLChangeUserJoin) error {
|
func (st *aclState) applyUserJoin(ch *pb.ACLChangeUserJoin) error {
|
||||||
invite, exists := st.userInvites[ch.UserInviteChangeId]
|
invite, exists := st.userInvites[ch.UserInviteChangeId]
|
||||||
if !exists {
|
if !exists {
|
||||||
return fmt.Errorf("no such invite with id %s", ch.UserInviteChangeId)
|
return fmt.Errorf("no such invite with id %s", ch.UserInviteChangeId)
|
||||||
@ -188,7 +188,7 @@ func (st *ACLState) applyUserJoin(ch *pb.ACLChangeUserJoin) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) applyUserAdd(ch *pb.ACLChangeUserAdd) error {
|
func (st *aclState) applyUserAdd(ch *pb.ACLChangeUserAdd) error {
|
||||||
if _, exists := st.userStates[ch.Identity]; exists {
|
if _, exists := st.userStates[ch.Identity]; exists {
|
||||||
return ErrUserAlreadyExists
|
return ErrUserAlreadyExists
|
||||||
}
|
}
|
||||||
@ -203,7 +203,7 @@ func (st *ACLState) applyUserAdd(ch *pb.ACLChangeUserAdd) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) applyUserRemove(ch *pb.ACLChangeUserRemove) error {
|
func (st *aclState) applyUserRemove(ch *pb.ACLChangeUserRemove) error {
|
||||||
if ch.Identity == st.identity {
|
if ch.Identity == st.identity {
|
||||||
return ErrDocumentForbidden
|
return ErrDocumentForbidden
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ func (st *ACLState) applyUserRemove(ch *pb.ACLChangeUserRemove) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) applyUserConfirm(ch *pb.ACLChangeUserConfirm) error {
|
func (st *aclState) applyUserConfirm(ch *pb.ACLChangeUserConfirm) error {
|
||||||
if _, exists := st.userStates[ch.Identity]; !exists {
|
if _, exists := st.userStates[ch.Identity]; !exists {
|
||||||
return ErrNoSuchUser
|
return ErrNoSuchUser
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ func (st *ACLState) applyUserConfirm(ch *pb.ACLChangeUserConfirm) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, error) {
|
func (st *aclState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, error) {
|
||||||
decrypted, err := st.encryptionKey.Decrypt(msg)
|
decrypted, err := st.encryptionKey.Decrypt(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, ErrFailedToDecrypt
|
return nil, 0, ErrFailedToDecrypt
|
||||||
@ -261,7 +261,7 @@ func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, e
|
|||||||
return key, hasher.Sum64(), nil
|
return key, hasher.Sum64(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) HasPermission(identity string, permission pb.ACLChangeUserPermissions) bool {
|
func (st *aclState) HasPermission(identity string, permission pb.ACLChangeUserPermissions) bool {
|
||||||
state, exists := st.userStates[identity]
|
state, exists := st.userStates[identity]
|
||||||
if !exists {
|
if !exists {
|
||||||
return false
|
return false
|
||||||
@ -270,12 +270,12 @@ func (st *ACLState) HasPermission(identity string, permission pb.ACLChangeUserPe
|
|||||||
return state.Permissions == permission
|
return state.Permissions == permission
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) isUserJoin(ch *pb.ACLChange) bool {
|
func (st *aclState) isUserJoin(ch *pb.ACLChange) bool {
|
||||||
// if we have a UserJoin, then it should always be the first one applied
|
// if we have a UserJoin, then it should always be the first one applied
|
||||||
return ch.AclData.GetAclContent() != nil && ch.AclData.GetAclContent()[0].GetUserJoin() != nil
|
return ch.AclData.GetAclContent() != nil && ch.AclData.GetAclContent()[0].GetUserJoin() != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) GetPermissionDecreasedUsers(ch *pb.ACLChange) (identities []*pb.ACLChangeUserPermissionChange) {
|
func (st *aclState) GetPermissionDecreasedUsers(ch *pb.ACLChange) (identities []*pb.ACLChangeUserPermissionChange) {
|
||||||
// this should be called after general checks are completed
|
// this should be called after general checks are completed
|
||||||
if ch.GetAclData().GetAclContent() == nil {
|
if ch.GetAclData().GetAclContent() == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -307,7 +307,7 @@ func (st *ACLState) GetPermissionDecreasedUsers(ch *pb.ACLChange) (identities []
|
|||||||
return identities
|
return identities
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ACLState) Equal(other *ACLState) bool {
|
func (st *aclState) Equal(other *aclState) bool {
|
||||||
if st == nil && other == nil {
|
if st == nil && other == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -1,18 +1,18 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/acltree/pb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ACLStateBuilder struct {
|
type ACLStateBuilder struct {
|
||||||
tree *Tree
|
tree *Tree
|
||||||
aclState *ACLState
|
aclState *aclState
|
||||||
identity string
|
identity string
|
||||||
key threadmodels.EncryptionPrivKey
|
key keys.EncryptionPrivKey
|
||||||
decoder threadmodels.SigningPubKeyDecoder
|
decoder keys.SigningPubKeyDecoder
|
||||||
}
|
}
|
||||||
|
|
||||||
type decreasedPermissionsParameters struct {
|
type decreasedPermissionsParameters struct {
|
||||||
@ -20,7 +20,7 @@ type decreasedPermissionsParameters struct {
|
|||||||
startChange string
|
startChange string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewACLStateBuilder(decoder threadmodels.SigningPubKeyDecoder, accountData *AccountData) *ACLStateBuilder {
|
func NewACLStateBuilder(decoder keys.SigningPubKeyDecoder, accountData *AccountData) *ACLStateBuilder {
|
||||||
return &ACLStateBuilder{
|
return &ACLStateBuilder{
|
||||||
decoder: decoder,
|
decoder: decoder,
|
||||||
identity: accountData.Identity,
|
identity: accountData.Identity,
|
||||||
@ -28,7 +28,7 @@ func NewACLStateBuilder(decoder threadmodels.SigningPubKeyDecoder, accountData *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *ACLStateBuilder) Build() (*ACLState, error) {
|
func (sb *ACLStateBuilder) Build() (*aclState, error) {
|
||||||
state, _, err := sb.BuildBefore("")
|
state, _, err := sb.BuildBefore("")
|
||||||
return state, err
|
return state, err
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ func (sb *ACLStateBuilder) Init(tree *Tree) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we can probably have only one state builder, because we can build both at the same time
|
// TODO: we can probably have only one state builder, because we can build both at the same time
|
||||||
func (sb *ACLStateBuilder) BuildBefore(beforeId string) (*ACLState, bool, error) {
|
func (sb *ACLStateBuilder) BuildBefore(beforeId string) (*aclState, bool, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
startChange = sb.tree.root
|
startChange = sb.tree.root
|
||||||
@ -1,11 +1,13 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadbuilder"
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/acltree/pb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/testutils/threadbuilder"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestACLStateBuilder_UserJoinBuild(t *testing.T) {
|
func TestACLStateBuilder_UserJoinBuild(t *testing.T) {
|
||||||
@ -18,7 +20,7 @@ func TestACLStateBuilder_UserJoinBuild(t *testing.T) {
|
|||||||
thread,
|
thread,
|
||||||
keychain.GetIdentity("A"),
|
keychain.GetIdentity("A"),
|
||||||
keychain.EncryptionKeys["A"],
|
keychain.EncryptionKeys["A"],
|
||||||
threadmodels.NewEd25519Decoder(),
|
keys.NewEd25519Decoder(),
|
||||||
NewPlainTextDocumentStateProvider(),
|
NewPlainTextDocumentStateProvider(),
|
||||||
false)
|
false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -53,7 +55,7 @@ func TestACLStateBuilder_UserRemoveBuild(t *testing.T) {
|
|||||||
thread,
|
thread,
|
||||||
keychain.GetIdentity("A"),
|
keychain.GetIdentity("A"),
|
||||||
keychain.EncryptionKeys["A"],
|
keychain.EncryptionKeys["A"],
|
||||||
threadmodels.NewEd25519Decoder(),
|
keys.NewEd25519Decoder(),
|
||||||
NewPlainTextDocumentStateProvider(),
|
NewPlainTextDocumentStateProvider(),
|
||||||
false)
|
false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -84,7 +86,7 @@ func TestACLStateBuilder_UserRemoveBeforeBuild(t *testing.T) {
|
|||||||
thread,
|
thread,
|
||||||
keychain.GetIdentity("A"),
|
keychain.GetIdentity("A"),
|
||||||
keychain.EncryptionKeys["A"],
|
keychain.EncryptionKeys["A"],
|
||||||
threadmodels.NewEd25519Decoder(),
|
keys.NewEd25519Decoder(),
|
||||||
NewPlainTextDocumentStateProvider(),
|
NewPlainTextDocumentStateProvider(),
|
||||||
false)
|
false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -116,7 +118,7 @@ func TestACLStateBuilder_InvalidSnapshotBuild(t *testing.T) {
|
|||||||
thread,
|
thread,
|
||||||
keychain.GetIdentity("A"),
|
keychain.GetIdentity("A"),
|
||||||
keychain.EncryptionKeys["A"],
|
keychain.EncryptionKeys["A"],
|
||||||
threadmodels.NewEd25519Decoder(),
|
keys.NewEd25519Decoder(),
|
||||||
NewPlainTextDocumentStateProvider(),
|
NewPlainTextDocumentStateProvider(),
|
||||||
false)
|
false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -147,7 +149,7 @@ func TestACLStateBuilder_ValidSnapshotBuild(t *testing.T) {
|
|||||||
thread,
|
thread,
|
||||||
keychain.GetIdentity("A"),
|
keychain.GetIdentity("A"),
|
||||||
keychain.EncryptionKeys["A"],
|
keychain.EncryptionKeys["A"],
|
||||||
threadmodels.NewEd25519Decoder(),
|
keys.NewEd25519Decoder(),
|
||||||
NewPlainTextDocumentStateProvider(),
|
NewPlainTextDocumentStateProvider(),
|
||||||
false)
|
false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1,23 +1,25 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
|
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/thread"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
"github.com/textileio/go-threads/core/thread"
|
gothread "github.com/textileio/go-threads/core/thread"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ACLTreeBuilder struct {
|
type ACLTreeBuilder struct {
|
||||||
cache map[string]*Change
|
cache map[string]*Change
|
||||||
identityKeys map[string]threadmodels.SigningPubKey
|
identityKeys map[string]keys.SigningPubKey
|
||||||
signingPubKeyDecoder threadmodels.SigningPubKeyDecoder
|
signingPubKeyDecoder keys.SigningPubKeyDecoder
|
||||||
tree *Tree
|
tree *Tree
|
||||||
thread threadmodels.Thread
|
thread thread.Thread
|
||||||
|
|
||||||
*changeLoader
|
*changeLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewACLTreeBuilder(t threadmodels.Thread, decoder threadmodels.SigningPubKeyDecoder) *ACLTreeBuilder {
|
func NewACLTreeBuilder(t thread.Thread, decoder keys.SigningPubKeyDecoder) *ACLTreeBuilder {
|
||||||
return &ACLTreeBuilder{
|
return &ACLTreeBuilder{
|
||||||
signingPubKeyDecoder: decoder,
|
signingPubKeyDecoder: decoder,
|
||||||
thread: t,
|
thread: t,
|
||||||
@ -30,7 +32,7 @@ func NewACLTreeBuilder(t threadmodels.Thread, decoder threadmodels.SigningPubKey
|
|||||||
|
|
||||||
func (tb *ACLTreeBuilder) Init() {
|
func (tb *ACLTreeBuilder) Init() {
|
||||||
tb.cache = make(map[string]*Change)
|
tb.cache = make(map[string]*Change)
|
||||||
tb.identityKeys = make(map[string]threadmodels.SigningPubKey)
|
tb.identityKeys = make(map[string]keys.SigningPubKey)
|
||||||
tb.tree = &Tree{}
|
tb.tree = &Tree{}
|
||||||
tb.changeLoader.init(tb.cache, tb.identityKeys)
|
tb.changeLoader.init(tb.cache, tb.identityKeys)
|
||||||
}
|
}
|
||||||
@ -97,7 +99,7 @@ func (tb *ACLTreeBuilder) dfsFromStart(heads []string) (buf []*Change, possibleR
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tb *ACLTreeBuilder) getRoot(possibleRoots []*Change) (*Change, error) {
|
func (tb *ACLTreeBuilder) getRoot(possibleRoots []*Change) (*Change, error) {
|
||||||
threadId, err := thread.Decode(tb.thread.ID())
|
threadId, err := gothread.Decode(tb.thread.ID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -109,7 +111,7 @@ func (tb *ACLTreeBuilder) getRoot(possibleRoots []*Change) (*Change, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := threadmodels.VerifyACLThreadID(sk, threadId)
|
res, err := thread.VerifyACLThreadID(sk, threadId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/acltree/pb"
|
||||||
"github.com/textileio/go-threads/crypto/symmetric"
|
"github.com/textileio/go-threads/crypto/symmetric"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1,25 +1,27 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
|
||||||
"github.com/gogo/protobuf/proto"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/acltree/pb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/thread"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type changeLoader struct {
|
type changeLoader struct {
|
||||||
cache map[string]*Change
|
cache map[string]*Change
|
||||||
identityKeys map[string]threadmodels.SigningPubKey
|
identityKeys map[string]keys.SigningPubKey
|
||||||
signingPubKeyDecoder threadmodels.SigningPubKeyDecoder
|
signingPubKeyDecoder keys.SigningPubKeyDecoder
|
||||||
thread threadmodels.Thread
|
thread thread.Thread
|
||||||
changeCreator func(id string, ch *pb.ACLChange) *Change
|
changeCreator func(id string, ch *pb.ACLChange) *Change
|
||||||
}
|
}
|
||||||
|
|
||||||
func newChangeLoader(
|
func newChangeLoader(
|
||||||
thread threadmodels.Thread,
|
thread thread.Thread,
|
||||||
signingPubKeyDecoder threadmodels.SigningPubKeyDecoder,
|
signingPubKeyDecoder keys.SigningPubKeyDecoder,
|
||||||
changeCreator func(id string, ch *pb.ACLChange) *Change) *changeLoader {
|
changeCreator func(id string, ch *pb.ACLChange) *Change) *changeLoader {
|
||||||
return &changeLoader{
|
return &changeLoader{
|
||||||
signingPubKeyDecoder: signingPubKeyDecoder,
|
signingPubKeyDecoder: signingPubKeyDecoder,
|
||||||
@ -29,7 +31,7 @@ func newChangeLoader(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *changeLoader) init(cache map[string]*Change,
|
func (c *changeLoader) init(cache map[string]*Change,
|
||||||
identityKeys map[string]threadmodels.SigningPubKey) {
|
identityKeys map[string]keys.SigningPubKey) {
|
||||||
c.cache = cache
|
c.cache = cache
|
||||||
c.identityKeys = identityKeys
|
c.identityKeys = identityKeys
|
||||||
}
|
}
|
||||||
@ -71,7 +73,7 @@ func (c *changeLoader) verify(identity string, payload, signature []byte) (isVer
|
|||||||
return identityKey.Verify(payload, signature)
|
return identityKey.Verify(payload, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *changeLoader) makeVerifiedACLChange(change *threadmodels.RawChange) (aclChange *pb.ACLChange, err error) {
|
func (c *changeLoader) makeVerifiedACLChange(change *thread.RawChange) (aclChange *pb.ACLChange, err error) {
|
||||||
aclChange = new(pb.ACLChange)
|
aclChange = new(pb.ACLChange)
|
||||||
|
|
||||||
// TODO: think what should we do with such cases, because this can be used by attacker to break our tree
|
// TODO: think what should we do with such cases, because this can be used by attacker to break our tree
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
type DocumentState interface {
|
type DocumentState interface {
|
||||||
ApplyChange(change []byte, id string) (DocumentState, error)
|
ApplyChange(change []byte, id string) (DocumentState, error)
|
||||||
@ -1,9 +1,8 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
)
|
)
|
||||||
@ -64,7 +63,13 @@ func NewDocument(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Document) Create(payload *CreateChangePayload) error {
|
//sync layer -> Object cache -> document -> Update (..raw changes)
|
||||||
|
//client layer -> Object cache -> document -> CreateChange(...)
|
||||||
|
//
|
||||||
|
|
||||||
|
// smartblock -> CreateChange(payload)
|
||||||
|
// SmartTree iterate etc
|
||||||
|
func (d *Document) CreateChange(payload *CreateChangePayload) error {
|
||||||
// TODO: add snapshot creation logic
|
// TODO: add snapshot creation logic
|
||||||
marshalled, err := payload.ChangesData.Marshal()
|
marshalled, err := payload.ChangesData.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -275,6 +280,8 @@ func (d *Document) build(fromStart bool) (DocumentState, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tree should be exposed
|
||||||
|
|
||||||
d.docStateBuilder.init(d.docContext.aclState, d.docContext.fullTree)
|
d.docStateBuilder.init(d.docContext.aclState, d.docContext.fullTree)
|
||||||
d.docContext.docState, err = d.docStateBuilder.build()
|
d.docContext.docState, err = d.docStateBuilder.build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1,10 +1,9 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/testutils/threadbuilder"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadbuilder"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDocument_Build(t *testing.T) {
|
func TestDocument_Build(t *testing.T) {
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
type documentContext struct {
|
type documentContext struct {
|
||||||
aclTree *Tree // TODO: remove it, because we don't use it
|
aclTree *Tree // TODO: remove it, because we don't use it
|
||||||
fullTree *Tree
|
fullTree *Tree
|
||||||
aclState *ACLState
|
aclState *aclState
|
||||||
docState DocumentState
|
docState DocumentState
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
type documentStateBuilder struct {
|
type documentStateBuilder struct {
|
||||||
tree *Tree
|
tree *Tree
|
||||||
aclState *ACLState // TODO: decide if this is needed or not
|
aclState *aclState // TODO: decide if this is needed or not
|
||||||
stateProvider InitialStateProvider
|
stateProvider InitialStateProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ func newDocumentStateBuilder(stateProvider InitialStateProvider) *documentStateB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *documentStateBuilder) init(aclState *ACLState, tree *Tree) {
|
func (d *documentStateBuilder) init(aclState *aclState, tree *Tree) {
|
||||||
d.tree = tree
|
d.tree = tree
|
||||||
d.aclState = aclState
|
d.aclState = aclState
|
||||||
}
|
}
|
||||||
@ -1,8 +1,7 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadbuilder"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/testutils/threadbuilder"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -7,6 +7,10 @@ import (
|
|||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TestDocumentState -> testutils
|
||||||
|
// ThreadBuilder -> testutils
|
||||||
|
// move protos to test utils
|
||||||
|
|
||||||
type PlainTextDocumentState struct {
|
type PlainTextDocumentState struct {
|
||||||
LastChangeId string
|
LastChangeId string
|
||||||
Text string
|
Text string
|
||||||
@ -1,8 +1,7 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SnapshotValidator struct {
|
type SnapshotValidator struct {
|
||||||
@ -1,12 +1,8 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ACLContext struct {
|
type ACLContext struct {
|
||||||
Tree *Tree
|
Tree *Tree
|
||||||
ACLState *ACLState
|
ACLState *aclState
|
||||||
DocState DocumentState
|
DocState DocumentState
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -1,13 +1,15 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
|
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/thread"
|
||||||
//"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/lib/logging"
|
//"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/lib/logging"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
"github.com/prometheus/common/log"
|
"github.com/prometheus/common/log"
|
||||||
"github.com/textileio/go-threads/core/thread"
|
gothread "github.com/textileio/go-threads/core/thread"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -17,15 +19,15 @@ var (
|
|||||||
|
|
||||||
type TreeBuilder struct {
|
type TreeBuilder struct {
|
||||||
cache map[string]*Change
|
cache map[string]*Change
|
||||||
identityKeys map[string]threadmodels.SigningPubKey
|
identityKeys map[string]keys.SigningPubKey
|
||||||
signingPubKeyDecoder threadmodels.SigningPubKeyDecoder
|
signingPubKeyDecoder keys.SigningPubKeyDecoder
|
||||||
tree *Tree
|
tree *Tree
|
||||||
thread threadmodels.Thread
|
thread thread.Thread
|
||||||
|
|
||||||
*changeLoader
|
*changeLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTreeBuilder(t threadmodels.Thread, decoder threadmodels.SigningPubKeyDecoder) *TreeBuilder {
|
func NewTreeBuilder(t thread.Thread, decoder keys.SigningPubKeyDecoder) *TreeBuilder {
|
||||||
return &TreeBuilder{
|
return &TreeBuilder{
|
||||||
signingPubKeyDecoder: decoder,
|
signingPubKeyDecoder: decoder,
|
||||||
thread: t,
|
thread: t,
|
||||||
@ -38,7 +40,7 @@ func NewTreeBuilder(t threadmodels.Thread, decoder threadmodels.SigningPubKeyDec
|
|||||||
|
|
||||||
func (tb *TreeBuilder) Init() {
|
func (tb *TreeBuilder) Init() {
|
||||||
tb.cache = make(map[string]*Change)
|
tb.cache = make(map[string]*Change)
|
||||||
tb.identityKeys = make(map[string]threadmodels.SigningPubKey)
|
tb.identityKeys = make(map[string]keys.SigningPubKey)
|
||||||
tb.tree = &Tree{}
|
tb.tree = &Tree{}
|
||||||
tb.changeLoader.init(tb.cache, tb.identityKeys)
|
tb.changeLoader.init(tb.cache, tb.identityKeys)
|
||||||
}
|
}
|
||||||
@ -285,7 +287,7 @@ func (tb *TreeBuilder) findCommonForTwoSnapshots(s1, s2 string) (s string, err e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tb *TreeBuilder) getRoot(possibleRoots []*Change) (*Change, error) {
|
func (tb *TreeBuilder) getRoot(possibleRoots []*Change) (*Change, error) {
|
||||||
threadId, err := thread.Decode(tb.thread.ID())
|
threadId, err := gothread.Decode(tb.thread.ID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -297,7 +299,7 @@ func (tb *TreeBuilder) getRoot(possibleRoots []*Change) (*Change, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := threadmodels.VerifyACLThreadID(sk, threadId)
|
res, err := thread.VerifyACLThreadID(sk, threadId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
//func TestACLTreeBuilder_UserJoinCorrectHeadsAndLen(t *testing.T) {
|
//func TestACLTreeBuilder_UserJoinCorrectHeadsAndLen(t *testing.T) {
|
||||||
// thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userjoinexample.yml")
|
// thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userjoinexample.yml")
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// +build !linux,!darwin android ios nographviz
|
// +build !linux,!darwin android ios nographviz
|
||||||
// +build !amd64
|
// +build !amd64
|
||||||
|
|
||||||
package data
|
package acltree
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
@ -5,7 +5,7 @@
|
|||||||
// +build !nographviz
|
// +build !nographviz
|
||||||
// +build amd64 arm64
|
// +build amd64 arm64
|
||||||
|
|
||||||
package data
|
package acltree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package data
|
package acltree
|
||||||
|
|
||||||
import "sync"
|
import "sync"
|
||||||
|
|
||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
|
||||||
"github.com/textileio/go-threads/crypto/symmetric"
|
"github.com/textileio/go-threads/crypto/symmetric"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -9,7 +9,6 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const plainTextDocType uint16 = 1
|
const plainTextDocType uint16 = 1
|
||||||
@ -46,7 +45,7 @@ func NewThreadBuilderFromFile(file string) (*ThreadBuilder, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
thread := YMLThread{}
|
thread := YMLThread{Some: &Super{}}
|
||||||
err = yaml.Unmarshal(content, &thread)
|
err = yaml.Unmarshal(content, &thread)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Test_YamlParse(t *testing.T) {
|
func Test_YamlParse(t *testing.T) {
|
||||||
tb, _ := NewThreadBuilderFromFile("validsnapshotexample.yml")
|
tb, _ := NewThreadBuilderFromFile("userjoinexample.yml")
|
||||||
gr, _ := tb.Graph()
|
gr, _ := tb.Graph()
|
||||||
fmt.Println(gr)
|
fmt.Println(gr)
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package threadmodels
|
package thread
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -1,15 +1,16 @@
|
|||||||
package threadmodels
|
package thread
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
|
|
||||||
"github.com/textileio/go-threads/core/thread"
|
"github.com/textileio/go-threads/core/thread"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateACLThreadID(k SigningPubKey, docType uint16) (thread.ID, error) {
|
func CreateACLThreadID(k keys.SigningPubKey, docType uint16) (thread.ID, error) {
|
||||||
rndlen := 32
|
rndlen := 32
|
||||||
buf := make([]byte, 8+rndlen)
|
buf := make([]byte, 8+rndlen)
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ func CreateACLThreadID(k SigningPubKey, docType uint16) (thread.ID, error) {
|
|||||||
return threadIDFromBytes(docType, buf)
|
return threadIDFromBytes(docType, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyACLThreadID(k SigningPubKey, threadId thread.ID) (bool, error) {
|
func VerifyACLThreadID(k keys.SigningPubKey, threadId thread.ID) (bool, error) {
|
||||||
bytes := threadId.Bytes()
|
bytes := threadId.Bytes()
|
||||||
pubKeyBytes := threadId.Bytes()[len(bytes)-40 : len(bytes)-32]
|
pubKeyBytes := threadId.Bytes()[len(bytes)-40 : len(bytes)-32]
|
||||||
hash := binary.LittleEndian.Uint64(pubKeyBytes)
|
hash := binary.LittleEndian.Uint64(pubKeyBytes)
|
||||||
@ -1,11 +1,12 @@
|
|||||||
package threadmodels
|
package thread
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateACLThreadIDVerify(t *testing.T) {
|
func TestCreateACLThreadIDVerify(t *testing.T) {
|
||||||
_, pubKey, err := GenerateRandomEd25519KeyPair()
|
_, pubKey, err := keys.GenerateRandomEd25519KeyPair()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("should not return error after generating key pair: %v", err)
|
t.Fatalf("should not return error after generating key pair: %v", err)
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package threadmodels
|
package keys
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
Loading…
x
Reference in New Issue
Block a user