Fix objecttree tests
This commit is contained in:
parent
ee0f62410f
commit
0243ec0fca
@ -1,7 +1,9 @@
|
|||||||
package accountdata
|
package accountdata
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
"github.com/anytypeio/any-sync/util/crypto"
|
"github.com/anytypeio/any-sync/util/crypto"
|
||||||
|
"github.com/anytypeio/any-sync/util/peer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AccountKeys struct {
|
type AccountKeys struct {
|
||||||
@ -9,3 +11,23 @@ type AccountKeys struct {
|
|||||||
SignKey crypto.PrivKey
|
SignKey crypto.PrivKey
|
||||||
PeerId string
|
PeerId string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewRandom() (*AccountKeys, error) {
|
||||||
|
peerKey, _, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
signKey, _, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
peerId, err := peer.IdFromSigningPubKey(peerKey.GetPublic())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &AccountKeys{
|
||||||
|
PeerKey: peerKey,
|
||||||
|
SignKey: signKey,
|
||||||
|
PeerId: peerId.String(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/anytypeio/any-sync/app/logger"
|
"github.com/anytypeio/any-sync/app/logger"
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
|
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/keychain"
|
|
||||||
"github.com/anytypeio/any-sync/util/crypto"
|
"github.com/anytypeio/any-sync/util/crypto"
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@ -48,8 +47,6 @@ type AclState struct {
|
|||||||
totalReadKeys int
|
totalReadKeys int
|
||||||
|
|
||||||
lastRecordId string
|
lastRecordId string
|
||||||
|
|
||||||
keychain *keychain.Keychain
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAclStateWithKeys(
|
func newAclStateWithKeys(
|
||||||
|
|||||||
@ -1,87 +1,16 @@
|
|||||||
package list
|
package list
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/anytypeio/any-sync/commonspace/object/accountdata"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAclList_AclState_UserInviteAndJoin(t *testing.T) {
|
func TestAclList_BuildRoot(t *testing.T) {
|
||||||
//st, err := acllistbuilder.NewListStorageWithTestName("userjoinexample.yml")
|
randomKeys, err := accountdata.NewRandom()
|
||||||
//require.NoError(t, err, "building storage should not result in error")
|
require.NoError(t, err)
|
||||||
//
|
randomAcl, err := NewTestDerivedAcl("spaceId", randomKeys)
|
||||||
//keychain := st.(*acllistbuilder.AclListStorageBuilder).GetKeychain()
|
require.NoError(t, err)
|
||||||
//
|
fmt.Println(randomAcl.Id())
|
||||||
//aclList, err := BuildAclList(st)
|
|
||||||
//require.NoError(t, err, "building acl list should be without error")
|
|
||||||
//
|
|
||||||
//idA := keychain.GetIdentity("A")
|
|
||||||
//idB := keychain.GetIdentity("B")
|
|
||||||
//idC := keychain.GetIdentity("C")
|
|
||||||
//
|
|
||||||
//// checking final state
|
|
||||||
//assert.Equal(t, aclrecordproto.AclUserPermissions_Admin, aclList.AclState().UserStates()[idA].Permissions)
|
|
||||||
//assert.Equal(t, aclrecordproto.AclUserPermissions_Writer, aclList.AclState().UserStates()[idB].Permissions)
|
|
||||||
//assert.Equal(t, aclrecordproto.AclUserPermissions_Reader, aclList.AclState().UserStates()[idC].Permissions)
|
|
||||||
//assert.Equal(t, aclList.Head().CurrentReadKeyHash, aclList.AclState().CurrentReadKeyId())
|
|
||||||
//
|
|
||||||
//var records []*AclRecord
|
|
||||||
//aclList.Iterate(func(record *AclRecord) (IsContinue bool) {
|
|
||||||
// records = append(records, record)
|
|
||||||
// return true
|
|
||||||
//})
|
|
||||||
//
|
|
||||||
//// checking permissions at specific records
|
|
||||||
//assert.Equal(t, 3, len(records))
|
|
||||||
//
|
|
||||||
//_, err = aclList.AclState().StateAtRecord(records[1].Id, idB)
|
|
||||||
//assert.Error(t, err, "B should have no permissions at record 1")
|
|
||||||
//
|
|
||||||
//perm, err := aclList.AclState().StateAtRecord(records[2].Id, idB)
|
|
||||||
//assert.NoError(t, err, "should have no error with permissions of B in the record 2")
|
|
||||||
//assert.Equal(t, UserPermissionPair{
|
|
||||||
// Identity: idB,
|
|
||||||
// Permission: aclrecordproto.AclUserPermissions_Writer,
|
|
||||||
//}, perm)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAclList_AclState_UserJoinAndRemove(t *testing.T) {
|
|
||||||
//st, err := acllistbuilder.NewListStorageWithTestName("userremoveexample.yml")
|
|
||||||
//require.NoError(t, err, "building storage should not result in error")
|
|
||||||
//
|
|
||||||
//keychain := st.(*acllistbuilder.AclListStorageBuilder).GetKeychain()
|
|
||||||
//
|
|
||||||
//aclList, err := BuildAclList(st)
|
|
||||||
//require.NoError(t, err, "building acl list should be without error")
|
|
||||||
//
|
|
||||||
//idA := keychain.GetIdentity("A")
|
|
||||||
//idB := keychain.GetIdentity("B")
|
|
||||||
//idC := keychain.GetIdentity("C")
|
|
||||||
//
|
|
||||||
//// checking final state
|
|
||||||
//assert.Equal(t, aclrecordproto.AclUserPermissions_Admin, aclList.AclState().UserStates()[idA].Permissions)
|
|
||||||
//assert.Equal(t, aclrecordproto.AclUserPermissions_Reader, aclList.AclState().UserStates()[idC].Permissions)
|
|
||||||
//assert.Equal(t, aclList.Head().CurrentReadKeyHash, aclList.AclState().CurrentReadKeyId())
|
|
||||||
//
|
|
||||||
//_, exists := aclList.AclState().UserStates()[idB]
|
|
||||||
//assert.Equal(t, false, exists)
|
|
||||||
//
|
|
||||||
//var records []*AclRecord
|
|
||||||
//aclList.Iterate(func(record *AclRecord) (IsContinue bool) {
|
|
||||||
// records = append(records, record)
|
|
||||||
// return true
|
|
||||||
//})
|
|
||||||
//
|
|
||||||
//// checking permissions at specific records
|
|
||||||
//assert.Equal(t, 4, len(records))
|
|
||||||
//
|
|
||||||
//assert.NotEqual(t, records[2].CurrentReadKeyHash, aclList.AclState().CurrentReadKeyId())
|
|
||||||
//
|
|
||||||
//perm, err := aclList.AclState().StateAtRecord(records[2].Id, idB)
|
|
||||||
//assert.NoError(t, err, "should have no error with permissions of B in the record 2")
|
|
||||||
//assert.Equal(t, UserPermissionPair{
|
|
||||||
// Identity: idB,
|
|
||||||
// Permission: aclrecordproto.AclUserPermissions_Writer,
|
|
||||||
//}, perm)
|
|
||||||
//
|
|
||||||
//_, err = aclList.AclState().StateAtRecord(records[3].Id, idB)
|
|
||||||
//assert.Error(t, err, "B should have no permissions at record 3, because user should be removed")
|
|
||||||
}
|
}
|
||||||
|
|||||||
27
commonspace/object/acl/list/listutils.go
Normal file
27
commonspace/object/acl/list/listutils.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package list
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anytypeio/any-sync/commonspace/object/accountdata"
|
||||||
|
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
|
||||||
|
"github.com/anytypeio/any-sync/commonspace/object/acl/liststorage"
|
||||||
|
"github.com/anytypeio/any-sync/util/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewTestDerivedAcl(spaceId string, keys *accountdata.AccountKeys) (AclList, error) {
|
||||||
|
builder := NewAclRecordBuilder("", crypto.NewKeyStorage())
|
||||||
|
root, err := builder.BuildRoot(RootContent{
|
||||||
|
PrivKey: keys.SignKey,
|
||||||
|
SpaceId: spaceId,
|
||||||
|
DerivationPath: crypto.AnytypeAccountPath,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
st, err := liststorage.NewInMemoryAclListStorage(root.Id, []*aclrecordproto.RawAclRecordWithId{
|
||||||
|
root,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return BuildAclListWithIdentity(keys, st)
|
||||||
|
}
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package keychain
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/anytypeio/any-sync/util/crypto"
|
|
||||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Keychain struct {
|
|
||||||
keys map[string]signingkey.PubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewKeychain() *Keychain {
|
|
||||||
return &Keychain{
|
|
||||||
keys: make(map[string]signingkey.PubKey),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Keychain) GetOrAdd(identity string) (signingkey.PubKey, error) {
|
|
||||||
if key, exists := k.keys[identity]; exists {
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
res, err := crypto.NewSigningEd25519PubKeyFromBytes([]byte(identity))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
k.keys[identity] = res.(signingkey.PubKey)
|
|
||||||
return res.(signingkey.PubKey), nil
|
|
||||||
}
|
|
||||||
@ -2,15 +2,30 @@ package objecttree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"github.com/anytypeio/any-sync/commonspace/object/accountdata"
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/acl/list"
|
"github.com/anytypeio/any-sync/commonspace/object/acl/list"
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/acl/testutils/acllistbuilder"
|
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/tree/treechangeproto"
|
"github.com/anytypeio/any-sync/commonspace/object/tree/treechangeproto"
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/tree/treestorage"
|
"github.com/anytypeio/any-sync/commonspace/object/tree/treestorage"
|
||||||
|
"github.com/anytypeio/any-sync/util/crypto"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type mockKeyStorage struct {
|
||||||
|
key crypto.PubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func newKeyStorage() mockKeyStorage {
|
||||||
|
_, pk, _ := crypto.GenerateEd25519Key(rand.Reader)
|
||||||
|
return mockKeyStorage{pk}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockKeyStorage) PubKeyFromProto(protoBytes []byte) (crypto.PubKey, error) {
|
||||||
|
return m.key, nil
|
||||||
|
}
|
||||||
|
|
||||||
type mockChangeCreator struct{}
|
type mockChangeCreator struct{}
|
||||||
|
|
||||||
func (c *mockChangeCreator) createRoot(id, aclId string) *treechangeproto.RawTreeChangeWithId {
|
func (c *mockChangeCreator) createRoot(id, aclId string) *treechangeproto.RawTreeChangeWithId {
|
||||||
@ -68,10 +83,9 @@ type testTreeContext struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func prepareAclList(t *testing.T) list.AclList {
|
func prepareAclList(t *testing.T) list.AclList {
|
||||||
st, err := acllistbuilder.NewListStorageWithTestName("userjoinexample.yml")
|
randKeys, err := accountdata.NewRandom()
|
||||||
require.NoError(t, err, "building storage should not result in error")
|
require.NoError(t, err)
|
||||||
|
aclList, err := list.NewTestDerivedAcl("spaceId", randKeys)
|
||||||
aclList, err := list.BuildAclList(st)
|
|
||||||
require.NoError(t, err, "building acl list should be without error")
|
require.NoError(t, err, "building acl list should be without error")
|
||||||
|
|
||||||
return aclList
|
return aclList
|
||||||
@ -82,7 +96,7 @@ func prepareTreeDeps(aclList list.AclList) (*mockChangeCreator, objectTreeDeps)
|
|||||||
treeStorage := changeCreator.createNewTreeStorage("0", aclList.Head().Id)
|
treeStorage := changeCreator.createNewTreeStorage("0", aclList.Head().Id)
|
||||||
root, _ := treeStorage.Root()
|
root, _ := treeStorage.Root()
|
||||||
changeBuilder := &nonVerifiableChangeBuilder{
|
changeBuilder := &nonVerifiableChangeBuilder{
|
||||||
ChangeBuilder: NewChangeBuilder(nil, root),
|
ChangeBuilder: NewChangeBuilder(newKeyStorage(), root),
|
||||||
}
|
}
|
||||||
deps := objectTreeDeps{
|
deps := objectTreeDeps{
|
||||||
changeBuilder: changeBuilder,
|
changeBuilder: changeBuilder,
|
||||||
@ -100,7 +114,7 @@ func prepareTreeContext(t *testing.T, aclList list.AclList) testTreeContext {
|
|||||||
treeStorage := changeCreator.createNewTreeStorage("0", aclList.Head().Id)
|
treeStorage := changeCreator.createNewTreeStorage("0", aclList.Head().Id)
|
||||||
root, _ := treeStorage.Root()
|
root, _ := treeStorage.Root()
|
||||||
changeBuilder := &nonVerifiableChangeBuilder{
|
changeBuilder := &nonVerifiableChangeBuilder{
|
||||||
ChangeBuilder: NewChangeBuilder(nil, root),
|
ChangeBuilder: NewChangeBuilder(newKeyStorage(), root),
|
||||||
}
|
}
|
||||||
deps := objectTreeDeps{
|
deps := objectTreeDeps{
|
||||||
changeBuilder: changeBuilder,
|
changeBuilder: changeBuilder,
|
||||||
|
|||||||
@ -5,10 +5,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/anytypeio/any-sync/util/crypto"
|
||||||
|
|
||||||
"github.com/anytypeio/any-sync/accountservice"
|
"github.com/anytypeio/any-sync/accountservice"
|
||||||
"github.com/anytypeio/any-sync/app/logger"
|
"github.com/anytypeio/any-sync/app/logger"
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/keychain"
|
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/tree/objecttree"
|
"github.com/anytypeio/any-sync/commonspace/object/tree/objecttree"
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/tree/synctree"
|
"github.com/anytypeio/any-sync/commonspace/object/tree/synctree"
|
||||||
"github.com/anytypeio/any-sync/commonspace/object/tree/synctree/updatelistener"
|
"github.com/anytypeio/any-sync/commonspace/object/tree/synctree/updatelistener"
|
||||||
@ -207,7 +207,6 @@ func (s *settingsObject) SpaceDeleteRawChange() (raw *treechangeproto.RawTreeCha
|
|||||||
return s.PrepareChange(objecttree.SignableChangeContent{
|
return s.PrepareChange(objecttree.SignableChangeContent{
|
||||||
Data: data,
|
Data: data,
|
||||||
Key: accountData.SignKey,
|
Key: accountData.SignKey,
|
||||||
Identity: accountData.Identity,
|
|
||||||
IsSnapshot: false,
|
IsSnapshot: false,
|
||||||
IsEncrypted: false,
|
IsEncrypted: false,
|
||||||
})
|
})
|
||||||
@ -252,7 +251,6 @@ func (s *settingsObject) addContent(data []byte) (err error) {
|
|||||||
_, err = s.AddContent(context.Background(), objecttree.SignableChangeContent{
|
_, err = s.AddContent(context.Background(), objecttree.SignableChangeContent{
|
||||||
Data: data,
|
Data: data,
|
||||||
Key: accountData.SignKey,
|
Key: accountData.SignKey,
|
||||||
Identity: accountData.Identity,
|
|
||||||
IsSnapshot: false,
|
IsSnapshot: false,
|
||||||
IsEncrypted: false,
|
IsEncrypted: false,
|
||||||
})
|
})
|
||||||
@ -264,13 +262,13 @@ func (s *settingsObject) addContent(data []byte) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyDeleteChange(raw *treechangeproto.RawTreeChangeWithId, identity []byte, peerId string) (err error) {
|
func VerifyDeleteChange(raw *treechangeproto.RawTreeChangeWithId, identity crypto.PubKey, peerId string) (err error) {
|
||||||
changeBuilder := objecttree.NewChangeBuilder(keychain.NewKeychain(), nil)
|
changeBuilder := objecttree.NewChangeBuilder(crypto.NewKeyStorage(), nil)
|
||||||
res, err := changeBuilder.Unmarshall(raw, true)
|
res, err := changeBuilder.Unmarshall(raw, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if res.Identity != string(identity) {
|
if !res.Identity.Equals(identity) {
|
||||||
return fmt.Errorf("incorrect identity")
|
return fmt.Errorf("incorrect identity")
|
||||||
}
|
}
|
||||||
return verifyDeleteContent(res.Data, peerId)
|
return verifyDeleteContent(res.Data, peerId)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user