diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 61fbfeab..8e332630 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -681,6 +681,13 @@ func (st *AclState) applyInviteJoin(ch *aclrecordproto.AclAccountInviteJoin, rec }), } } + for _, rec := range st.requestRecords { + if rec.RequestIdentity.Equals(identity) { + delete(st.pendingRequests, mapKeyFromPubKey(rec.RequestIdentity)) + delete(st.requestRecords, rec.RecordId) + break + } + } if st.pubKey.Equals(identity) { return st.unpackAllKeys(ch.EncryptedReadKey) } diff --git a/commonspace/object/acl/list/acltestsuite.go b/commonspace/object/acl/list/acltestsuite.go index bf61312c..a3b178c8 100644 --- a/commonspace/object/acl/list/acltestsuite.go +++ b/commonspace/object/acl/list/acltestsuite.go @@ -218,7 +218,7 @@ func (a *AclTestExecutor) buildBatchRequest(args []string, acl AclList, getPerm } } if recId == "" { - return nil, fmt.Errorf("no join records for approve") + return nil, fmt.Errorf("no join records to approve") } perms := getPerm(argParts[1]) afterAll = append(afterAll, func() { @@ -461,7 +461,7 @@ func (a *AclTestExecutor) Execute(cmd string) (err error) { } } if recId == "" { - return fmt.Errorf("no join records for approve") + return fmt.Errorf("no join records to approve") } perms := getPerm(argParts[1]) res, err := acl.RecordBuilder().BuildRequestAccept(RequestAcceptPayload{ diff --git a/commonspace/object/acl/list/acltestsuite_test.go b/commonspace/object/acl/list/acltestsuite_test.go index ec06267f..5cefe156 100644 --- a/commonspace/object/acl/list/acltestsuite_test.go +++ b/commonspace/object/acl/list/acltestsuite_test.go @@ -90,7 +90,7 @@ func TestAclExecutor(t *testing.T) { {"g.join::inv1Id", nil}, {"g.cancel::g", nil}, // e cannot approve cancelled request - {"e.approve::g,rw", fmt.Errorf("no join records for approve")}, + {"e.approve::g,rw", fmt.Errorf("no join records to approve")}, {"g.join::inv1Id", nil}, {"e.decline::g", nil}, // g cannot cancel declined request @@ -144,6 +144,12 @@ func TestAclExecutor(t *testing.T) { {"new4.add::super,r,superm", nil}, // check that users can't join using request to join for anyone can join links {"new5.join::someId", ErrNoSuchInvite}, + {"a.invite::requestJoinId", nil}, + {"joiner.join::requestJoinId", nil}, + // check that users can join under a different link even after they created a request to join + {"joiner.invite_join::someId", nil}, + // check that they can't be approved after they joined under a different link + {"a.approve::joiner,rw", fmt.Errorf("no join records to approve")}, } for _, cmd := range cmds { err := a.Execute(cmd.cmd) diff --git a/commonspace/object/tree/objecttree/tree.go b/commonspace/object/tree/objecttree/tree.go index 3d0c783e..3b7222bf 100644 --- a/commonspace/object/tree/objecttree/tree.go +++ b/commonspace/object/tree/objecttree/tree.go @@ -53,6 +53,9 @@ func (t *Tree) Root() *Change { } func (t *Tree) AddFast(changes ...*Change) []*Change { + if len(changes) == 0 { + return nil + } defer t.clearUnattached() t.addedBuf = t.addedBuf[:0] for _, c := range changes { diff --git a/commonspace/object/tree/objecttree/tree_test.go b/commonspace/object/tree/objecttree/tree_test.go index c22d6efd..bfe9c84a 100644 --- a/commonspace/object/tree/objecttree/tree_test.go +++ b/commonspace/object/tree/objecttree/tree_test.go @@ -49,6 +49,10 @@ func TestTree_Add(t *testing.T) { assert.Equal(t, tr.root.Id, "root") assert.Equal(t, []string{"root"}, tr.Heads()) }) + t.Run("empty tree add should not panic", func(t *testing.T) { + tr := &Tree{} + tr.AddFast() + }) t.Run("linear add", func(t *testing.T) { tr := new(Tree) res, _ := tr.Add( diff --git a/commonspace/object/tree/objecttree/treebuilder.go b/commonspace/object/tree/objecttree/treebuilder.go index 4ebb646b..b9e87c34 100644 --- a/commonspace/object/tree/objecttree/treebuilder.go +++ b/commonspace/object/tree/objecttree/treebuilder.go @@ -17,7 +17,7 @@ import ( var ( log = logger.NewNamedSugared("common.commonspace.objecttree") - ErrEmpty = errors.New("logs empty") + ErrEmpty = errors.New("database is empty") ) type treeBuilder struct { @@ -146,6 +146,9 @@ func (tb *treeBuilder) build(opts treeBuilderOpts) (tr *Tree, err error) { if err != nil { return nil, fmt.Errorf("failed to get changes after order: %w", err) } + if len(changes) == 0 { + return nil, ErrEmpty + } tr = &Tree{} changes = append(changes, opts.newChanges...) tr.AddFast(changes...)