mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-07 21:47:02 +09:00
131 lines
3.8 KiB
Go
131 lines
3.8 KiB
Go
//go:generate mockgen -destination mock_aclclient/mock_aclclient.go github.com/anyproto/any-sync/commonspace/acl/aclclient AclJoiningClient,AclSpaceClient
|
|
package aclclient
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/anyproto/any-sync/accountservice"
|
|
"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/liststorage"
|
|
"github.com/anyproto/any-sync/consensus/consensusproto"
|
|
"github.com/anyproto/any-sync/node/nodeclient"
|
|
)
|
|
|
|
const CName = "common.acl.aclclient"
|
|
|
|
type AclJoiningClient interface {
|
|
app.Component
|
|
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)
|
|
CancelRemoveSelf(ctx context.Context, spaceId string) (err error)
|
|
}
|
|
|
|
type aclJoiningClient struct {
|
|
nodeClient nodeclient.NodeClient
|
|
keys *accountdata.AccountKeys
|
|
}
|
|
|
|
func NewAclJoiningClient() AclJoiningClient {
|
|
return &aclJoiningClient{}
|
|
}
|
|
|
|
func (c *aclJoiningClient) Name() (name string) {
|
|
return CName
|
|
}
|
|
|
|
func (c *aclJoiningClient) Init(a *app.App) (err error) {
|
|
c.nodeClient = a.MustComponent(nodeclient.CName).(nodeclient.NodeClient)
|
|
c.keys = a.MustComponent(accountservice.CName).(accountservice.Service).Account()
|
|
return nil
|
|
}
|
|
|
|
func (c *aclJoiningClient) AclGetRecords(ctx context.Context, spaceId, aclHead string) (recs []*consensusproto.RawRecordWithId, err error) {
|
|
return c.nodeClient.AclGetRecords(ctx, spaceId, aclHead)
|
|
}
|
|
|
|
func (c *aclJoiningClient) getAcl(ctx context.Context, spaceId string) (l list.AclList, err error) {
|
|
res, err := c.AclGetRecords(ctx, spaceId, "")
|
|
if err != nil {
|
|
return
|
|
}
|
|
if len(res) == 0 {
|
|
err = fmt.Errorf("acl not found")
|
|
return
|
|
}
|
|
storage, err := liststorage.NewInMemoryAclListStorage(res[0].Id, res)
|
|
if err != nil {
|
|
return
|
|
}
|
|
return list.BuildAclListWithIdentity(c.keys, storage, list.NoOpAcceptorVerifier{})
|
|
}
|
|
|
|
func (c *aclJoiningClient) CancelJoin(ctx context.Context, spaceId string) (err error) {
|
|
acl, err := c.getAcl(ctx, spaceId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
pendingReq, err := acl.AclState().JoinRecord(acl.AclState().Identity(), false)
|
|
if err != nil {
|
|
return
|
|
}
|
|
res, err := acl.RecordBuilder().BuildRequestCancel(pendingReq.RecordId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
_, err = c.nodeClient.AclAddRecord(ctx, spaceId, res)
|
|
return
|
|
}
|
|
|
|
func (c *aclJoiningClient) RequestJoin(ctx context.Context, spaceId string, payload list.RequestJoinPayload) (aclHeadId string, err error) {
|
|
acl, err := c.getAcl(ctx, spaceId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
joinRecs, err := acl.AclState().JoinRecords(false)
|
|
if err != nil {
|
|
return
|
|
}
|
|
for _, rec := range joinRecs {
|
|
if rec.RequestIdentity.Equals(c.keys.SignKey.GetPublic()) {
|
|
// that means that we already requested to join
|
|
return
|
|
}
|
|
}
|
|
rec, err := acl.RecordBuilder().BuildRequestJoin(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 {
|
|
return
|
|
}
|
|
pendingReq, err := acl.AclState().Record(acl.AclState().Identity())
|
|
if err != nil {
|
|
if !acl.AclState().Permissions(acl.AclState().Identity()).NoPermissions() {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
if pendingReq.Type != list.RequestTypeRemove {
|
|
return list.ErrInsufficientPermissions
|
|
}
|
|
newRec, err := acl.RecordBuilder().BuildRequestCancel(pendingReq.RecordId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
_, err = c.nodeClient.AclAddRecord(ctx, spaceId, newRec)
|
|
return
|
|
}
|