mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-08 05:57:03 +09:00
Add batch invite logic
This commit is contained in:
parent
854823d81e
commit
985a1d7184
4 changed files with 163 additions and 51 deletions
|
@ -19,6 +19,10 @@ type InviteResponse struct {
|
|||
InviteKey crypto.PrivKey
|
||||
}
|
||||
|
||||
type InviteChange struct {
|
||||
Perms list.AclPermissions
|
||||
}
|
||||
|
||||
type GetRecordsResponse struct {
|
||||
Records []*consensusproto.RawRecordWithId
|
||||
}
|
||||
|
@ -27,8 +31,8 @@ type InviteSaveFunc func()
|
|||
|
||||
type AclSpaceClient interface {
|
||||
app.Component
|
||||
GenerateInvite() (list.InviteResult, error)
|
||||
GenerateAnyoneCanJoinInvite(permissions list.AclPermissions) (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
|
||||
|
@ -129,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) {
|
||||
|
@ -166,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) {
|
||||
|
@ -212,10 +216,46 @@ 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) {
|
||||
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()
|
||||
return c.acl.RecordBuilder().BuildInvite()
|
||||
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()
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -66,6 +66,10 @@ type AccountAdd struct {
|
|||
Metadata []byte
|
||||
}
|
||||
|
||||
type NewInvites struct {
|
||||
Permissions AclPermissions
|
||||
}
|
||||
|
||||
type BatchRequestPayload struct {
|
||||
Additions []AccountAdd
|
||||
Changes []PermissionChangePayload
|
||||
|
@ -73,6 +77,8 @@ type BatchRequestPayload struct {
|
|||
Approvals []RequestAcceptPayload
|
||||
Declines []string
|
||||
InviteRevokes []string
|
||||
InviteChanges []InviteChangePayload
|
||||
NewInvites []AclPermissions
|
||||
}
|
||||
|
||||
type AccountRemovePayload struct {
|
||||
|
@ -85,12 +91,17 @@ type InviteResult struct {
|
|||
InviteKey crypto.PrivKey
|
||||
}
|
||||
|
||||
type BatchResult struct {
|
||||
Rec *consensusproto.RawRecord
|
||||
Invites []crypto.PrivKey
|
||||
}
|
||||
|
||||
type AclRecordBuilder interface {
|
||||
UnmarshallWithId(rawIdRecord *consensusproto.RawRecordWithId) (rec *AclRecord, err error)
|
||||
Unmarshall(rawRecord *consensusproto.RawRecord) (rec *AclRecord, err error)
|
||||
|
||||
BuildRoot(content RootContent) (rec *consensusproto.RawRecordWithId, err error)
|
||||
BuildBatchRequest(payload BatchRequestPayload) (rawRecord *consensusproto.RawRecord, err error)
|
||||
BuildBatchRequest(payload BatchRequestPayload) (batchResult BatchResult, err error)
|
||||
BuildInvite() (res InviteResult, err error)
|
||||
BuildInviteAnyone(permissions AclPermissions) (res InviteResult, err error)
|
||||
BuildInviteChange(inviteChange InviteChangePayload) (rawRecord *consensusproto.RawRecord, err error)
|
||||
|
@ -125,51 +136,84 @@ func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage, keys *accountd
|
|||
}
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (rawRec *consensusproto.RawRecord, err error) {
|
||||
var aclContent []*aclrecordproto.AclContentValue
|
||||
func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (batchResult BatchResult, err error) {
|
||||
var (
|
||||
contentList []*aclrecordproto.AclContentValue
|
||||
content *aclrecordproto.AclContentValue
|
||||
)
|
||||
if len(payload.Removals.Identities) > 0 {
|
||||
content, err := a.buildAccountRemove(payload.Removals)
|
||||
content, err = a.buildAccountRemove(payload.Removals)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
aclContent = append(aclContent, content)
|
||||
contentList = append(contentList, content)
|
||||
}
|
||||
if len(payload.Additions) > 0 {
|
||||
content, err := a.buildAccountsAdd(AccountsAddPayload{Additions: payload.Additions}, payload.Removals.Change.MetadataKey.GetPublic(), payload.Removals.Change.ReadKey)
|
||||
content, err = a.buildAccountsAdd(AccountsAddPayload{Additions: payload.Additions}, payload.Removals.Change.MetadataKey.GetPublic(), payload.Removals.Change.ReadKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
aclContent = append(aclContent, content)
|
||||
contentList = append(contentList, content)
|
||||
}
|
||||
if len(payload.Changes) > 0 {
|
||||
content, err := a.buildPermissionChanges(PermissionChangesPayload{Changes: payload.Changes})
|
||||
content, err = a.buildPermissionChanges(PermissionChangesPayload{Changes: payload.Changes})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
aclContent = append(aclContent, content)
|
||||
contentList = append(contentList, content)
|
||||
}
|
||||
for _, acc := range payload.Approvals {
|
||||
content, err := a.buildRequestAccept(acc, payload.Removals.Change.ReadKey)
|
||||
content, err = a.buildRequestAccept(acc, payload.Removals.Change.ReadKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
aclContent = append(aclContent, content)
|
||||
contentList = append(contentList, content)
|
||||
}
|
||||
for _, id := range payload.Declines {
|
||||
content, err := a.buildRequestDecline(id)
|
||||
content, err = a.buildRequestDecline(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
aclContent = append(aclContent, content)
|
||||
contentList = append(contentList, content)
|
||||
}
|
||||
for _, id := range payload.InviteRevokes {
|
||||
content, err := a.buildInviteRevoke(id)
|
||||
content, err = a.buildInviteRevoke(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
aclContent = append(aclContent, content)
|
||||
contentList = append(contentList, content)
|
||||
}
|
||||
return a.buildRecords(aclContent)
|
||||
for _, invite := range payload.InviteChanges {
|
||||
content, err = a.buildInviteChange(invite)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
contentList = append(contentList, content)
|
||||
}
|
||||
for _, perms := range payload.NewInvites {
|
||||
var privKey crypto.PrivKey
|
||||
if perms.NoPermissions() {
|
||||
privKey, content, err = a.buildInvite()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
contentList = append(contentList, content)
|
||||
batchResult.Invites = append(batchResult.Invites, privKey)
|
||||
} else {
|
||||
privKey, content, err = a.buildInviteAnyone(perms)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
contentList = append(contentList, content)
|
||||
batchResult.Invites = append(batchResult.Invites, privKey)
|
||||
}
|
||||
}
|
||||
res, err := a.buildRecords(contentList)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
batchResult.Rec = res
|
||||
return
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValue) (rawRec *consensusproto.RawRecord, err error) {
|
||||
|
@ -316,6 +360,20 @@ func (a *aclRecordBuilder) buildAccountsAdd(payload AccountsAddPayload, mkKey cr
|
|||
}
|
||||
|
||||
func (a *aclRecordBuilder) BuildInvite() (res InviteResult, err error) {
|
||||
privKey, content, err := a.buildInvite()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rawRec, err := a.buildRecord(content)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res.InviteKey = privKey
|
||||
res.InviteRec = rawRec
|
||||
return
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) buildInvite() (invKey crypto.PrivKey, content *aclrecordproto.AclContentValue, err error) {
|
||||
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||
err = ErrInsufficientPermissions
|
||||
return
|
||||
|
@ -329,7 +387,37 @@ func (a *aclRecordBuilder) BuildInvite() (res InviteResult, err error) {
|
|||
return
|
||||
}
|
||||
inviteRec := &aclrecordproto.AclAccountInvite{InviteKey: invitePubKey}
|
||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_Invite{Invite: inviteRec}}
|
||||
content = &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_Invite{Invite: inviteRec}}
|
||||
invKey = privKey
|
||||
return
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) BuildInviteChange(inviteChange InviteChangePayload) (rawRecord *consensusproto.RawRecord, err error) {
|
||||
content, err := a.buildInviteChange(inviteChange)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return a.buildRecord(content)
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) buildInviteChange(inviteChange InviteChangePayload) (content *aclrecordproto.AclContentValue, err error) {
|
||||
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||
err = ErrInsufficientPermissions
|
||||
return
|
||||
}
|
||||
inviteRec := &aclrecordproto.AclAccountInviteChange{
|
||||
InviteRecordId: inviteChange.IniviteRecordId,
|
||||
Permissions: aclrecordproto.AclUserPermissions(inviteChange.Permissions),
|
||||
}
|
||||
content = &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_InviteChange{InviteChange: inviteRec}}
|
||||
return
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) BuildInviteAnyone(permissions AclPermissions) (res InviteResult, err error) {
|
||||
privKey, content, err := a.buildInviteAnyone(permissions)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rawRec, err := a.buildRecord(content)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -339,20 +427,7 @@ func (a *aclRecordBuilder) BuildInvite() (res InviteResult, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) BuildInviteChange(inviteChange InviteChangePayload) (rawRecord *consensusproto.RawRecord, err error) {
|
||||
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||
err = ErrInsufficientPermissions
|
||||
return
|
||||
}
|
||||
inviteRec := &aclrecordproto.AclAccountInviteChange{
|
||||
InviteRecordId: inviteChange.IniviteRecordId,
|
||||
Permissions: aclrecordproto.AclUserPermissions(inviteChange.Permissions),
|
||||
}
|
||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_InviteChange{InviteChange: inviteRec}}
|
||||
return a.buildRecord(content)
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) BuildInviteAnyone(permissions AclPermissions) (res InviteResult, err error) {
|
||||
func (a *aclRecordBuilder) buildInviteAnyone(permissions AclPermissions) (invKey crypto.PrivKey, content *aclrecordproto.AclContentValue, err error) {
|
||||
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||
err = ErrInsufficientPermissions
|
||||
return
|
||||
|
@ -383,13 +458,8 @@ func (a *aclRecordBuilder) BuildInviteAnyone(permissions AclPermissions) (res In
|
|||
Permissions: aclrecordproto.AclUserPermissions_Reader,
|
||||
EncryptedReadKey: encReadKey,
|
||||
}
|
||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_Invite{Invite: inviteRec}}
|
||||
rawRec, err := a.buildRecord(content)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res.InviteKey = privKey
|
||||
res.InviteRec = rawRec
|
||||
content = &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_Invite{Invite: inviteRec}}
|
||||
invKey = privKey
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ type Invite struct {
|
|||
Key crypto.PubKey
|
||||
Type aclrecordproto.AclInviteType
|
||||
Permissions AclPermissions
|
||||
Id string
|
||||
encryptedKey []byte
|
||||
}
|
||||
|
||||
|
@ -507,6 +508,7 @@ func (st *AclState) applyInvite(ch *aclrecordproto.AclAccountInvite, record *Acl
|
|||
}
|
||||
st.invites[record.Id] = Invite{
|
||||
Key: inviteKey,
|
||||
Id: record.Id,
|
||||
Type: ch.InviteType,
|
||||
Permissions: AclPermissions(ch.Permissions),
|
||||
encryptedKey: ch.EncryptedReadKey,
|
||||
|
|
|
@ -217,7 +217,7 @@ func (a *AclTestExecutor) buildBatchRequest(args []string, acl AclList, getPerm
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return afterAll, addRec(WrapAclRecord(res))
|
||||
return afterAll, addRec(WrapAclRecord(res.Rec))
|
||||
}
|
||||
|
||||
func (a *AclTestExecutor) Execute(cmd string) (err error) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue