Add test for thread utility
This commit is contained in:
parent
dbfb8cbabc
commit
acc2699b0e
@ -110,8 +110,11 @@ func (st *ACLState) applyChange(change *pb.ACLChange) (err error) {
|
|||||||
}
|
}
|
||||||
st.currentReadKeyHash = change.CurrentReadKeyHash
|
st.currentReadKeyHash = change.CurrentReadKeyHash
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// 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) {
|
// the same is for the first change to be added
|
||||||
|
skipIdentityCheck := st.isUserJoin(change) || (st.currentReadKeyHash == 0 && st.isUserAdd(change))
|
||||||
|
if !skipIdentityCheck {
|
||||||
// we check signature when we add this to the Tree, so no need to do it here
|
// we check signature when we add this to the Tree, so no need to do it here
|
||||||
if _, exists := st.userStates[change.Identity]; !exists {
|
if _, exists := st.userStates[change.Identity]; !exists {
|
||||||
err = ErrNoSuchUser
|
err = ErrNoSuchUser
|
||||||
@ -320,6 +323,12 @@ func (st *ACLState) isUserJoin(ch *pb.ACLChange) bool {
|
|||||||
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) isUserAdd(ch *pb.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 *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 {
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
"github.com/textileio/go-threads/crypto/symmetric"
|
"github.com/textileio/go-threads/crypto/symmetric"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MarshalledChange = []byte
|
type MarshalledChange = []byte
|
||||||
@ -105,28 +106,16 @@ func (c *changeBuilder) UserAdd(identity string, encryptionKey keys.EncryptionPu
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *changeBuilder) BuildAndApply() (*Change, []byte, error) {
|
func (c *changeBuilder) BuildAndApply() (*Change, []byte, error) {
|
||||||
marshalled, err := c.changeContent.Marshal()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
encrypted, err := c.aclState.userReadKeys[c.aclState.currentReadKeyHash].
|
|
||||||
Encrypt(marshalled)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
aclChange := &pb.ACLChange{
|
aclChange := &pb.ACLChange{
|
||||||
TreeHeadIds: c.tree.Heads(),
|
TreeHeadIds: c.tree.Heads(),
|
||||||
AclHeadIds: c.tree.ACLHeads(),
|
AclHeadIds: c.tree.ACLHeads(),
|
||||||
SnapshotBaseId: c.tree.RootId(),
|
SnapshotBaseId: c.tree.RootId(),
|
||||||
AclData: c.aclData,
|
AclData: c.aclData,
|
||||||
ChangesData: encrypted,
|
CurrentReadKeyHash: c.readKeyHash,
|
||||||
CurrentReadKeyHash: c.aclState.currentReadKeyHash,
|
Timestamp: int64(time.Now().Nanosecond()),
|
||||||
Timestamp: 0,
|
|
||||||
Identity: c.acc.Identity,
|
Identity: c.acc.Identity,
|
||||||
}
|
}
|
||||||
err = c.aclState.applyChange(aclChange)
|
err := c.aclState.applyChange(aclChange)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -135,6 +124,21 @@ func (c *changeBuilder) BuildAndApply() (*Change, []byte, error) {
|
|||||||
c.aclData.AclSnapshot = c.aclState.makeSnapshot()
|
c.aclData.AclSnapshot = c.aclState.makeSnapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var marshalled []byte
|
||||||
|
if c.changeContent != nil {
|
||||||
|
marshalled, err = c.changeContent.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypted, err := c.aclState.userReadKeys[c.aclState.currentReadKeyHash].
|
||||||
|
Encrypt(marshalled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
aclChange.ChangesData = encrypted
|
||||||
|
}
|
||||||
|
|
||||||
fullMarshalledChange, err := proto.Marshal(aclChange)
|
fullMarshalledChange, err := proto.Marshal(aclChange)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|||||||
@ -31,5 +31,12 @@ func BuildThreadWithACL(
|
|||||||
Signature: change.Signature(),
|
Signature: change.Signature(),
|
||||||
Id: change.CID(),
|
Id: change.CID(),
|
||||||
}
|
}
|
||||||
return create(rawChange)
|
|
||||||
|
thr, err := create(rawChange)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
thr.SetHeads([]string{change.CID()})
|
||||||
|
return thr, nil
|
||||||
}
|
}
|
||||||
|
|||||||
51
acltree/threadutility_test.go
Normal file
51
acltree/threadutility_test.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package acltree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/account"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges/pb"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/testutils/threadbuilder"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/thread"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuildThreadWithACL(t *testing.T) {
|
||||||
|
keychain := threadbuilder.NewKeychain()
|
||||||
|
keychain.AddSigningKey("A")
|
||||||
|
keychain.AddEncryptionKey("A")
|
||||||
|
data := &account.AccountData{
|
||||||
|
Identity: keychain.GetIdentity("A"),
|
||||||
|
SignKey: keychain.SigningKeys["A"],
|
||||||
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
|
}
|
||||||
|
thr, err := BuildThreadWithACL(
|
||||||
|
data,
|
||||||
|
func(builder ChangeBuilder) error {
|
||||||
|
return builder.UserAdd(
|
||||||
|
keychain.GetIdentity("A"),
|
||||||
|
keychain.EncryptionKeys["A"].GetPublic(),
|
||||||
|
pb.ACLChange_Admin)
|
||||||
|
},
|
||||||
|
thread.NewInMemoryThread)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("build should not return error")
|
||||||
|
}
|
||||||
|
if len(thr.Heads()) == 0 {
|
||||||
|
t.Fatalf("thread should have non-empty heads")
|
||||||
|
}
|
||||||
|
if thr.Header() == nil {
|
||||||
|
t.Fatalf("thread should have non-empty header")
|
||||||
|
}
|
||||||
|
assert.Equal(t, thr.Heads()[0], thr.Header().FirstChangeId)
|
||||||
|
assert.NotEmpty(t, thr.ID())
|
||||||
|
ch, err := thr.GetChange(context.Background(), thr.Header().FirstChangeId)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("get change should not return error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = NewFromRawChange(ch)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("we should be able to unmarshall change: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user