Skip to content

GO-4400: Add new invite type #449

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion acl/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"go.uber.org/zap"

"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/recordverifier"
"github.com/anyproto/any-sync/consensus/consensusproto"
)

Expand Down Expand Up @@ -58,7 +59,7 @@ func (a *aclObject) AddConsensusRecords(recs []*consensusproto.RawRecordWithId)
if a.store, a.consErr = list.NewInMemoryStorage(a.id, recs); a.consErr != nil {
return
}
if a.AclList, a.consErr = list.BuildAclListWithIdentity(a.aclService.accountService.Account(), a.store, list.NoOpAcceptorVerifier{}); a.consErr != nil {
if a.AclList, a.consErr = list.BuildAclListWithIdentity(a.aclService.accountService.Account(), a.store, recordverifier.New()); a.consErr != nil {
return
}
} else {
Expand Down
21 changes: 20 additions & 1 deletion commonspace/acl/aclclient/acjoiningclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/recordverifier"
"github.com/anyproto/any-sync/consensus/consensusproto"
"github.com/anyproto/any-sync/node/nodeclient"
)
Expand All @@ -20,6 +21,7 @@ type AclJoiningClient interface {
AclGetRecords(ctx context.Context, spaceId, aclHead string) ([]*consensusproto.RawRecordWithId, error)
RequestJoin(ctx context.Context, spaceId string, payload list.RequestJoinPayload) (aclHeadId string, err error)
CancelJoin(ctx context.Context, spaceId string) (err error)
InviteJoin(ctx context.Context, spaceId string, payload list.InviteJoinPayload) (aclHeadId string, err error)
CancelRemoveSelf(ctx context.Context, spaceId string) (err error)
}

Expand Down Expand Up @@ -59,7 +61,7 @@ func (c *aclJoiningClient) getAcl(ctx context.Context, spaceId string) (l list.A
if err != nil {
return
}
return list.BuildAclListWithIdentity(c.keys, storage, list.NoOpAcceptorVerifier{})
return list.BuildAclListWithIdentity(c.keys, storage, recordverifier.New())
}

func (c *aclJoiningClient) CancelJoin(ctx context.Context, spaceId string) (err error) {
Expand Down Expand Up @@ -106,6 +108,23 @@ func (c *aclJoiningClient) RequestJoin(ctx context.Context, spaceId string, payl
return
}

func (c *aclJoiningClient) InviteJoin(ctx context.Context, spaceId string, payload list.InviteJoinPayload) (aclHeadId string, err error) {
acl, err := c.getAcl(ctx, spaceId)
if err != nil {
return
}
rec, err := acl.RecordBuilder().BuildInviteJoin(payload)
if err != nil {
return
}
recWithId, err := c.nodeClient.AclAddRecord(ctx, spaceId, rec)
if err != nil {
return
}
aclHeadId = recWithId.Id
return
}

func (c *aclJoiningClient) CancelRemoveSelf(ctx context.Context, spaceId string) (err error) {
acl, err := c.getAcl(ctx, spaceId)
if err != nil {
Expand Down
74 changes: 67 additions & 7 deletions commonspace/acl/aclclient/aclspaceclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"

"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/syncacl"
"github.com/anyproto/any-sync/commonspace/spacestate"
Expand All @@ -18,6 +19,10 @@ type InviteResponse struct {
InviteKey crypto.PrivKey
}

type InviteChange struct {
Perms list.AclPermissions
}

type GetRecordsResponse struct {
Records []*consensusproto.RawRecordWithId
}
Expand All @@ -26,7 +31,8 @@ type InviteSaveFunc func()

type AclSpaceClient interface {
app.Component
GenerateInvite() (list.InviteResult, error)
GenerateInvite(shouldRevokeAll, isRequestToJoin bool, permissions list.AclPermissions) (list.InviteResult, error)
ChangeInvite(ctx context.Context, inviteId string, permissions list.AclPermissions) error
StopSharing(ctx context.Context, readKeyChange list.ReadKeyChangePayload) (err error)
AddRecord(ctx context.Context, consRec *consensusproto.RawRecord) error
RemoveAccounts(ctx context.Context, payload list.AccountRemovePayload) error
Expand Down Expand Up @@ -127,7 +133,7 @@ func (c *aclSpaceClient) RevokeAllInvites(ctx context.Context) (err error) {
return
}
c.acl.Unlock()
return c.sendRecordAndUpdate(ctx, c.spaceId, res)
return c.sendRecordAndUpdate(ctx, c.spaceId, res.Rec)
}

func (c *aclSpaceClient) StopSharing(ctx context.Context, readKeyChange list.ReadKeyChangePayload) (err error) {
Expand Down Expand Up @@ -164,7 +170,7 @@ func (c *aclSpaceClient) StopSharing(ctx context.Context, readKeyChange list.Rea
return
}
c.acl.Unlock()
return c.sendRecordAndUpdate(ctx, c.spaceId, res)
return c.sendRecordAndUpdate(ctx, c.spaceId, res.Rec)
}

func (c *aclSpaceClient) DeclineRequest(ctx context.Context, identity crypto.PubKey) (err error) {
Expand Down Expand Up @@ -210,10 +216,64 @@ func (c *aclSpaceClient) AcceptRequest(ctx context.Context, payload list.Request
return c.sendRecordAndUpdate(ctx, c.spaceId, res)
}

func (c *aclSpaceClient) GenerateInvite() (resp list.InviteResult, err error) {
c.acl.RLock()
defer c.acl.RUnlock()
return c.acl.RecordBuilder().BuildInvite()
func (c *aclSpaceClient) ChangeInvite(ctx context.Context, inviteId string, permissions list.AclPermissions) error {
c.acl.Lock()
res, err := c.acl.RecordBuilder().BuildInviteChange(list.InviteChangePayload{
IniviteRecordId: inviteId,
Permissions: permissions,
})
if err != nil {
c.acl.Unlock()
return err
}
c.acl.Unlock()
return c.sendRecordAndUpdate(ctx, c.spaceId, res)
}

func (c *aclSpaceClient) GenerateInvite(isRevoke, isRequestToJoin bool, permissions list.AclPermissions) (list.InviteResult, error) {
c.acl.Lock()
defer c.acl.Unlock()
var inviteIds []string
if isRevoke {
for _, invite := range c.acl.AclState().Invites() {
if isRequestToJoin && invite.Type == aclrecordproto.AclInviteType_RequestToJoin {
return list.InviteResult{}, list.ErrDuplicateInvites
} else if invite.Permissions == permissions {
return list.InviteResult{}, list.ErrDuplicateInvites
}
}
inviteIds = c.acl.AclState().InviteIds()
}
var payload list.BatchRequestPayload
if isRequestToJoin {
payload = list.BatchRequestPayload{
InviteRevokes: inviteIds,
NewInvites: []list.AclPermissions{list.AclPermissionsNone},
}
} else {
payload = list.BatchRequestPayload{
InviteRevokes: inviteIds,
NewInvites: []list.AclPermissions{permissions},
}
}
res, err := c.acl.RecordBuilder().BuildBatchRequest(payload)
if err != nil {
return list.InviteResult{}, err
}
return list.InviteResult{
InviteRec: res.Rec,
InviteKey: res.Invites[0],
}, nil
}

func (c *aclSpaceClient) GenerateAnyoneCanJoinInvite(permissions list.AclPermissions) (resp list.InviteResult, err error) {
c.acl.Lock()
defer c.acl.Unlock()
anyoneInvites := c.acl.AclState().Invites(aclrecordproto.AclInviteType_AnyoneCanJoin)
if len(anyoneInvites) > 0 {
return list.InviteResult{}, list.ErrDuplicateInvites
}
return c.acl.RecordBuilder().BuildInviteAnyone(permissions)
}

func (c *aclSpaceClient) AddRecord(ctx context.Context, consRec *consensusproto.RawRecord) (err error) {
Expand Down
37 changes: 33 additions & 4 deletions commonspace/acl/aclclient/mock_aclclient/mock_aclclient.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion commonspace/acl/aclwaiter/aclwaiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/anyproto/any-sync/commonspace/acl/aclclient"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/recordverifier"
"github.com/anyproto/any-sync/util/periodicsync"
)

Expand Down Expand Up @@ -82,7 +83,7 @@ func (a *aclWaiter) loop(ctx context.Context) error {
if err != nil {
return err
}
acl, err := list.BuildAclListWithIdentity(a.keys, storage, list.NoOpAcceptorVerifier{})
acl, err := list.BuildAclListWithIdentity(a.keys, storage, recordverifier.New())
if err != nil {
return err
}
Expand Down
17 changes: 13 additions & 4 deletions commonspace/deletion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,22 @@ import (
"github.com/stretchr/testify/require"

"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/object/acl/recordverifier"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
"github.com/anyproto/any-sync/commonspace/spacepayloads"
"github.com/anyproto/any-sync/commonspace/spacestorage"
"github.com/anyproto/any-sync/commonspace/syncstatus"
"github.com/anyproto/any-sync/util/crypto"
)

func mockDeps() Deps {
return Deps{
TreeSyncer: mockTreeSyncer{},
SyncStatus: syncstatus.NewNoOpSyncStatus(),
recordVerifier: recordverifier.NewValidateFull(),
}
}

func createTree(t *testing.T, ctx context.Context, spc Space, acc *accountdata.AccountKeys) string {
bytes := make([]byte, 32)
rand.Read(bytes)
Expand Down Expand Up @@ -60,7 +69,7 @@ func TestSpaceDeleteIdsMarkDeleted(t *testing.T) {
require.NotNil(t, sp)

// initializing space
spc, err := fx.spaceService.NewSpace(ctx, sp, Deps{TreeSyncer: mockTreeSyncer{}, SyncStatus: syncstatus.NewNoOpSyncStatus()})
spc, err := fx.spaceService.NewSpace(ctx, sp, mockDeps())
require.NoError(t, err)
require.NotNil(t, spc)
// adding space to tree manager
Expand Down Expand Up @@ -109,7 +118,7 @@ func TestSpaceDeleteIdsMarkDeleted(t *testing.T) {
time.Sleep(100 * time.Millisecond)
storeSetter := fx.storageProvider.(storeSetter)
storeSetter.SetStore(sp, newStore)
spc, err = fx.spaceService.NewSpace(ctx, sp, Deps{TreeSyncer: mockTreeSyncer{}, SyncStatus: syncstatus.NewNoOpSyncStatus()})
spc, err = fx.spaceService.NewSpace(ctx, sp, mockDeps())
require.NoError(t, err)
require.NotNil(t, spc)
waitTest := make(chan struct{})
Expand Down Expand Up @@ -153,7 +162,7 @@ func TestSpaceDeleteIds(t *testing.T) {
require.NotNil(t, sp)

// initializing space
spc, err := fx.spaceService.NewSpace(ctx, sp, Deps{TreeSyncer: mockTreeSyncer{}, SyncStatus: syncstatus.NewNoOpSyncStatus()})
spc, err := fx.spaceService.NewSpace(ctx, sp, mockDeps())
require.NoError(t, err)
require.NotNil(t, spc)
// adding space to tree manager
Expand Down Expand Up @@ -202,7 +211,7 @@ func TestSpaceDeleteIds(t *testing.T) {
time.Sleep(100 * time.Millisecond)
storeSetter := fx.storageProvider.(storeSetter)
storeSetter.SetStore(sp, newStore)
spc, err = fx.spaceService.NewSpace(ctx, sp, Deps{TreeSyncer: mockTreeSyncer{}, SyncStatus: syncstatus.NewNoOpSyncStatus()})
spc, err = fx.spaceService.NewSpace(ctx, sp, mockDeps())
require.NoError(t, err)
require.NotNil(t, spc)
waitTest := make(chan struct{})
Expand Down
3 changes: 2 additions & 1 deletion commonspace/deletionmanager/deleter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/commonspace/deletionstate"
"github.com/anyproto/any-sync/commonspace/object/tree/synctree"
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
"github.com/anyproto/any-sync/commonspace/object/treemanager"
"github.com/anyproto/any-sync/commonspace/spacestorage"
Expand Down Expand Up @@ -43,7 +44,7 @@ func (d *deleter) Delete(ctx context.Context) {
}
} else {
err = d.getter.DeleteTree(ctx, spaceId, id)
if err != nil && !errors.Is(err, spacestorage.ErrTreeStorageAlreadyDeleted) {
if err != nil && !errors.Is(err, spacestorage.ErrTreeStorageAlreadyDeleted) && !errors.Is(err, synctree.ErrSyncTreeDeleted) {
log.Error("failed to delete object", zap.Error(err))
continue
}
Expand Down
Loading
Loading