diff --git a/commonspace/acl/aclclient/acjoiningclient.go b/commonspace/acl/aclclient/acjoiningclient.go index de958b31..8beaa91b 100644 --- a/commonspace/acl/aclclient/acjoiningclient.go +++ b/commonspace/acl/aclclient/acjoiningclient.go @@ -21,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) } @@ -107,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 { diff --git a/commonspace/acl/aclclient/aclspaceclient.go b/commonspace/acl/aclclient/aclspaceclient.go index c007fbc0..2c8662bf 100644 --- a/commonspace/acl/aclclient/aclspaceclient.go +++ b/commonspace/acl/aclclient/aclspaceclient.go @@ -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" @@ -27,6 +28,7 @@ type InviteSaveFunc func() type AclSpaceClient interface { app.Component GenerateInvite() (list.InviteResult, error) + GenerateAnyoneCanJoinInvite(permissions list.AclPermissions) (list.InviteResult, 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 @@ -211,11 +213,21 @@ func (c *aclSpaceClient) AcceptRequest(ctx context.Context, payload list.Request } func (c *aclSpaceClient) GenerateInvite() (resp list.InviteResult, err error) { - c.acl.RLock() - defer c.acl.RUnlock() + c.acl.Lock() + defer c.acl.Unlock() return c.acl.RecordBuilder().BuildInvite() } +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) { return c.sendRecordAndUpdate(ctx, c.spaceId, consRec) } diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 3e3fe5a1..3389c70b 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -27,6 +27,7 @@ var ( ErrNoSuchRequest = errors.New("no such request") ErrNoSuchInvite = errors.New("no such invite") ErrInsufficientPermissions = errors.New("insufficient permissions") + ErrDuplicateInvites = errors.New("duplicate invites") ErrIsOwner = errors.New("can't be made by owner") ErrIncorrectNumberOfAccounts = errors.New("incorrect number of accounts") ErrDuplicateAccounts = errors.New("duplicate accounts")