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
|
||||
}()
|
||||
|
||||
// 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
|
||||
if _, exists := st.userStates[change.Identity]; !exists {
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
// this should be called after general checks are completed
|
||||
if ch.GetAclData().GetAclContent() == nil {
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/textileio/go-threads/crypto/symmetric"
|
||||
"hash/fnv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MarshalledChange = []byte
|
||||
@ -105,28 +106,16 @@ func (c *changeBuilder) UserAdd(identity string, encryptionKey keys.EncryptionPu
|
||||
}
|
||||
|
||||
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{
|
||||
TreeHeadIds: c.tree.Heads(),
|
||||
AclHeadIds: c.tree.ACLHeads(),
|
||||
SnapshotBaseId: c.tree.RootId(),
|
||||
AclData: c.aclData,
|
||||
ChangesData: encrypted,
|
||||
CurrentReadKeyHash: c.aclState.currentReadKeyHash,
|
||||
Timestamp: 0,
|
||||
CurrentReadKeyHash: c.readKeyHash,
|
||||
Timestamp: int64(time.Now().Nanosecond()),
|
||||
Identity: c.acc.Identity,
|
||||
}
|
||||
err = c.aclState.applyChange(aclChange)
|
||||
err := c.aclState.applyChange(aclChange)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -135,6 +124,21 @@ func (c *changeBuilder) BuildAndApply() (*Change, []byte, error) {
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
||||
@ -31,5 +31,12 @@ func BuildThreadWithACL(
|
||||
Signature: change.Signature(),
|
||||
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