mirror of
https://github.com/anyproto/anytype-heart.git
synced 2025-06-08 05:47:07 +09:00
GO-3174 Major refactoring for tests
This commit is contained in:
parent
8106a7f873
commit
9584bf73bf
28 changed files with 1519 additions and 863 deletions
|
@ -67,9 +67,10 @@ packages:
|
|||
github.com/anyproto/anytype-heart/space/spacecore:
|
||||
interfaces:
|
||||
SpaceCoreService:
|
||||
github.com/anyproto/anytype-heart/space/internal/techspace:
|
||||
github.com/anyproto/anytype-heart/space/techspace:
|
||||
interfaces:
|
||||
TechSpace:
|
||||
SpaceView:
|
||||
github.com/anyproto/anytype-heart/space/spacefactory:
|
||||
interfaces:
|
||||
SpaceFactory:
|
||||
|
|
|
@ -14,24 +14,17 @@ import (
|
|||
"github.com/anyproto/any-sync/coordinator/coordinatorclient"
|
||||
"github.com/anyproto/any-sync/coordinator/coordinatorproto"
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/mr-tron/base58/base58"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/anytype/account"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/getblock"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/files/fileacl"
|
||||
"github.com/anyproto/anytype-heart/core/invitestore"
|
||||
"github.com/anyproto/anytype-heart/core/inviteservice"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/logging"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
|
@ -65,10 +58,10 @@ type aclSpaceView interface {
|
|||
|
||||
type AclService interface {
|
||||
app.Component
|
||||
GenerateInvite(ctx context.Context, spaceId string) (*InviteInfo, error)
|
||||
GenerateInvite(ctx context.Context, spaceId string) (inviteservice.InviteInfo, error)
|
||||
RevokeInvite(ctx context.Context, spaceId string) error
|
||||
GetCurrentInvite(spaceId string) (*InviteInfo, error)
|
||||
ViewInvite(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (*InviteView, error)
|
||||
GetCurrentInvite(ctx context.Context, spaceId string) (inviteservice.InviteInfo, error)
|
||||
ViewInvite(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (inviteservice.InviteView, error)
|
||||
Join(ctx context.Context, spaceId string, inviteCid cid.Cid, inviteFileKey crypto.SymKey) error
|
||||
ApproveLeave(ctx context.Context, spaceId string, identities []crypto.PubKey) error
|
||||
MakeShareable(ctx context.Context, spaceId string) error
|
||||
|
@ -88,20 +81,15 @@ func New() AclService {
|
|||
type aclService struct {
|
||||
joiningClient aclclient.AclJoiningClient
|
||||
spaceService space.Service
|
||||
inviteService inviteservice.InviteService
|
||||
accountService account.Service
|
||||
coordClient coordinatorclient.CoordinatorClient
|
||||
inviteStore invitestore.Service
|
||||
fileAcl fileacl.Service
|
||||
objectGetter getblock.ObjectGetter
|
||||
}
|
||||
|
||||
func (a *aclService) Init(ap *app.App) (err error) {
|
||||
a.joiningClient = app.MustComponent[aclclient.AclJoiningClient](ap)
|
||||
a.spaceService = app.MustComponent[space.Service](ap)
|
||||
a.accountService = app.MustComponent[account.Service](ap)
|
||||
a.inviteStore = app.MustComponent[invitestore.Service](ap)
|
||||
a.fileAcl = app.MustComponent[fileacl.Service](ap)
|
||||
a.objectGetter = app.MustComponent[getblock.ObjectGetter](ap)
|
||||
a.coordClient = app.MustComponent[coordinatorclient.CoordinatorClient](ap)
|
||||
return nil
|
||||
}
|
||||
|
@ -178,11 +166,7 @@ func (a *aclService) RevokeInvite(ctx context.Context, spaceId string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("%w, %w", ErrAclRequestFailed, err)
|
||||
}
|
||||
spaceView, err := a.spaceService.TechSpace().GetSpaceView(ctx, spaceId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get space view id: %w", err)
|
||||
}
|
||||
return a.removeExistingInviteFileInfo(ctx, spaceView)
|
||||
return a.inviteService.RemoveExisting(ctx, spaceId)
|
||||
}
|
||||
|
||||
func (a *aclService) ChangePermissions(ctx context.Context, spaceId string, perms []AccountPermissions) error {
|
||||
|
@ -277,42 +261,34 @@ func (a *aclService) StopSharing(ctx context.Context, spaceId string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spaceView, err := a.spaceService.TechSpace().GetSpaceView(ctx, spaceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spaceView.Lock()
|
||||
localInfo := spaceView.GetLocalInfo()
|
||||
spaceView.Unlock()
|
||||
acl := removeSpace.CommonSpace().Acl()
|
||||
acl.RLock()
|
||||
isEmpty := aclIsEmpty(acl)
|
||||
head := acl.Head().Id
|
||||
acl.RUnlock()
|
||||
if isEmpty && localInfo.GetShareableStatus() != spaceinfo.ShareableStatusShareable {
|
||||
var localInfo spaceinfo.SpaceLocalInfo
|
||||
err = a.spaceService.TechSpace().DoSpaceView(ctx, spaceId, func(spaceView techspace.SpaceView) error {
|
||||
localInfo = spaceView.GetLocalInfo()
|
||||
return nil
|
||||
}
|
||||
})
|
||||
acl := removeSpace.CommonSpace().Acl()
|
||||
newPrivKey, _, err := crypto.GenerateRandomEd25519KeyPair()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isEmpty {
|
||||
cl := removeSpace.CommonSpace().AclClient()
|
||||
err = cl.StopSharing(ctx, list.ReadKeyChangePayload{
|
||||
MetadataKey: newPrivKey,
|
||||
ReadKey: crypto.NewAES(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w, %w", ErrAclRequestFailed, err)
|
||||
}
|
||||
acl.RLock()
|
||||
head = acl.Head().Id
|
||||
acl.RUnlock()
|
||||
cl := removeSpace.CommonSpace().AclClient()
|
||||
err = cl.StopSharing(ctx, list.ReadKeyChangePayload{
|
||||
MetadataKey: newPrivKey,
|
||||
ReadKey: crypto.NewAES(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w, %w", ErrAclRequestFailed, err)
|
||||
}
|
||||
err = a.removeExistingInviteFileInfo(ctx, spaceView)
|
||||
acl.RLock()
|
||||
head := acl.Head().Id
|
||||
acl.RUnlock()
|
||||
err = a.inviteService.RemoveExisting(ctx, spaceId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("remove existing invite file info: %w", err)
|
||||
}
|
||||
if localInfo.GetShareableStatus() != spaceinfo.ShareableStatusShareable {
|
||||
return nil
|
||||
}
|
||||
for {
|
||||
err = a.coordClient.SpaceMakeUnshareable(ctx, spaceId, head)
|
||||
if errors.Is(err, coordinatorproto.ErrAclHeadIsMissing) {
|
||||
|
@ -330,7 +306,7 @@ func (a *aclService) StopSharing(ctx context.Context, spaceId string) error {
|
|||
}
|
||||
|
||||
func (a *aclService) Join(ctx context.Context, spaceId string, inviteCid cid.Cid, inviteFileKey crypto.SymKey) error {
|
||||
invitePayload, err := a.getInvitePayload(ctx, inviteCid, inviteFileKey)
|
||||
invitePayload, err := a.inviteService.GetPayload(ctx, inviteCid, inviteFileKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get invite payload: %w", err)
|
||||
}
|
||||
|
@ -363,55 +339,8 @@ func (a *aclService) Join(ctx context.Context, spaceId string, inviteCid cid.Cid
|
|||
}})
|
||||
}
|
||||
|
||||
type InviteView struct {
|
||||
SpaceId string
|
||||
SpaceName string
|
||||
SpaceIconCid string
|
||||
CreatorName string
|
||||
}
|
||||
|
||||
func (a *aclService) ViewInvite(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (*InviteView, error) {
|
||||
invitePayload, err := a.getInvitePayload(ctx, inviteCid, inviteFileKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get invite payload: %w", err)
|
||||
}
|
||||
return &InviteView{
|
||||
SpaceId: invitePayload.SpaceId,
|
||||
SpaceName: invitePayload.SpaceName,
|
||||
SpaceIconCid: invitePayload.SpaceIconCid,
|
||||
CreatorName: invitePayload.CreatorName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *aclService) getInvitePayload(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (*model.InvitePayload, error) {
|
||||
invite, err := a.inviteStore.GetInvite(ctx, inviteCid, inviteFileKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get invite: %w", err)
|
||||
}
|
||||
var invitePayload model.InvitePayload
|
||||
err = proto.Unmarshal(invite.Payload, &invitePayload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unmarshal invite payload: %w", err)
|
||||
}
|
||||
creatorIdentity, err := crypto.DecodeAccountAddress(invitePayload.CreatorIdentity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode creator identity: %w", err)
|
||||
}
|
||||
|
||||
ok, err := creatorIdentity.Verify(invite.Payload, invite.Signature)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("verify invite signature: %w", err)
|
||||
}
|
||||
if !ok {
|
||||
return nil, ErrInviteBadSignature
|
||||
}
|
||||
|
||||
err = a.fileAcl.StoreFileKeys(domain.FileId(invitePayload.SpaceIconCid), invitePayload.SpaceIconEncryptionKeys)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("store icon keys: %w", err)
|
||||
}
|
||||
|
||||
return &invitePayload, nil
|
||||
func (a *aclService) ViewInvite(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (inviteservice.InviteView, error) {
|
||||
return a.inviteService.View(ctx, inviteCid, inviteFileKey)
|
||||
}
|
||||
|
||||
func (a *aclService) Accept(ctx context.Context, spaceId string, identity crypto.PubKey, permissions model.ParticipantPermissions) error {
|
||||
|
@ -459,209 +388,29 @@ func (a *aclService) Accept(ctx context.Context, spaceId string, identity crypto
|
|||
return nil
|
||||
}
|
||||
|
||||
type InviteInfo struct {
|
||||
InviteFileCid string
|
||||
InviteFileKey string
|
||||
func (a *aclService) GetCurrentInvite(ctx context.Context, spaceId string) (inviteservice.InviteInfo, error) {
|
||||
return a.inviteService.GetCurrent(ctx, spaceId)
|
||||
}
|
||||
|
||||
func (a *aclService) buildInvite(ctx context.Context, space clientspace.Space, inviteKey crypto.PrivKey) (*model.Invite, error) {
|
||||
invitePayload, err := a.buildInvitePayload(ctx, space, inviteKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("build invite payload: %w", err)
|
||||
}
|
||||
invitePayloadRaw, err := proto.Marshal(invitePayload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal invite payload: %w", err)
|
||||
}
|
||||
invitePayloadSignature, err := a.accountService.SignData(invitePayloadRaw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sign invite payload: %w", err)
|
||||
}
|
||||
return &model.Invite{
|
||||
Payload: invitePayloadRaw,
|
||||
Signature: invitePayloadSignature,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *aclService) buildInvitePayload(ctx context.Context, space clientspace.Space, inviteKey crypto.PrivKey) (*model.InvitePayload, error) {
|
||||
profile, err := a.accountService.ProfileInfo()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get profile info: %w", err)
|
||||
}
|
||||
rawInviteKey, err := inviteKey.Marshall()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal invite priv key: %w", err)
|
||||
}
|
||||
invitePayload := &model.InvitePayload{
|
||||
SpaceId: space.Id(),
|
||||
CreatorIdentity: a.accountService.AccountID(),
|
||||
CreatorName: profile.Name,
|
||||
InviteKey: rawInviteKey,
|
||||
}
|
||||
err = space.Do(space.DerivedIDs().Workspace, func(sb smartblock.SmartBlock) error {
|
||||
details := sb.Details()
|
||||
invitePayload.SpaceName = pbtypes.GetString(details, bundle.RelationKeyName.String())
|
||||
iconObjectId := pbtypes.GetString(details, bundle.RelationKeyIconImage.String())
|
||||
if iconObjectId != "" {
|
||||
iconCid, iconEncryptionKeys, err := a.fileAcl.GetInfoForFileSharing(ctx, iconObjectId)
|
||||
if err == nil {
|
||||
invitePayload.SpaceIconCid = iconCid
|
||||
invitePayload.SpaceIconEncryptionKeys = iconEncryptionKeys
|
||||
} else {
|
||||
log.Error("get space icon info", zap.Error(err))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return invitePayload, nil
|
||||
}
|
||||
|
||||
type spaceViewObject interface {
|
||||
SetInviteFileInfo(fileCid string, fileKey string) (err error)
|
||||
}
|
||||
|
||||
func (a *aclService) getExistingInviteFileInfo(spaceViewId string) (fileCid string, fileKey string, err error) {
|
||||
err = getblock.Do(a.objectGetter, spaceViewId, func(sb smartblock.SmartBlock) error {
|
||||
details := sb.Details()
|
||||
fileCid = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileCid.String())
|
||||
fileKey = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileKey.String())
|
||||
return nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (a *aclService) removeExistingInviteFileInfo(ctx context.Context, spaceView aclSpaceView) (err error) {
|
||||
fileCid, err := spaceView.RemoveExistingInvite()
|
||||
if err != nil {
|
||||
return fmt.Errorf("remove existing invite: %w", err)
|
||||
}
|
||||
cId, err := cid.Decode(fileCid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decode file cid: %w", err)
|
||||
}
|
||||
return a.inviteStore.RemoveInvite(ctx, cId)
|
||||
}
|
||||
|
||||
func (a *aclService) GetCurrentInvite(spaceId string) (*InviteInfo, error) {
|
||||
spaceViewId, err := a.spaceService.SpaceViewId(spaceId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get space view id: %w", err)
|
||||
}
|
||||
fileCid, fileKey, err := a.getExistingInviteFileInfo(spaceViewId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get existing invite file info: %w", err)
|
||||
}
|
||||
if fileCid == "" {
|
||||
return nil, ErrInviteNotExists
|
||||
}
|
||||
return &InviteInfo{
|
||||
InviteFileCid: fileCid,
|
||||
InviteFileKey: fileKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *aclService) GenerateInvite(ctx context.Context, spaceId string) (result *InviteInfo, err error) {
|
||||
func (a *aclService) GenerateInvite(ctx context.Context, spaceId string) (result inviteservice.InviteInfo, err error) {
|
||||
if spaceId == a.accountService.PersonalSpaceID() {
|
||||
return nil, ErrPersonalSpace
|
||||
err = ErrPersonalSpace
|
||||
return
|
||||
}
|
||||
spaceViewId, err := a.spaceService.SpaceViewId(spaceId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get space view id: %w", err)
|
||||
current, err := a.inviteService.GetCurrent(ctx, spaceId)
|
||||
if err == nil {
|
||||
return current, nil
|
||||
}
|
||||
fileCid, fileKey, err := a.getExistingInviteFileInfo(spaceViewId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get existing invite file info: %w", err)
|
||||
}
|
||||
if fileCid != "" {
|
||||
return &InviteInfo{
|
||||
InviteFileCid: fileCid,
|
||||
InviteFileKey: fileKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
acceptSpace, err := a.spaceService.Get(ctx, spaceId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
aclClient := acceptSpace.CommonSpace().AclClient()
|
||||
res, err := aclClient.GenerateInvite()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return
|
||||
}
|
||||
|
||||
invite, err := a.buildInvite(ctx, acceptSpace, res.InviteKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("build invite: %w", err)
|
||||
}
|
||||
inviteFileCid, inviteFileKey, err := a.inviteStore.StoreInvite(ctx, invite)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("store invite in ipfs: %w", err)
|
||||
}
|
||||
removeInviteFile := func() {
|
||||
err := a.inviteStore.RemoveInvite(ctx, inviteFileCid)
|
||||
if err != nil {
|
||||
log.Error("remove invite file", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
inviteFileKeyRaw, err := EncodeKeyToBase58(inviteFileKey)
|
||||
if err != nil {
|
||||
removeInviteFile()
|
||||
return nil, fmt.Errorf("encode invite file key: %w", err)
|
||||
}
|
||||
err = getblock.Do(a.objectGetter, spaceViewId, func(sb smartblock.SmartBlock) error {
|
||||
view, ok := sb.(spaceViewObject)
|
||||
if !ok {
|
||||
return fmt.Errorf("space view object is not implemented")
|
||||
}
|
||||
return view.SetInviteFileInfo(inviteFileCid.String(), inviteFileKeyRaw)
|
||||
return a.inviteService.Generate(ctx, spaceId, res.InviteKey, func() error {
|
||||
return aclClient.AddRecord(ctx, res.InviteRec)
|
||||
})
|
||||
if err != nil {
|
||||
removeInviteFile()
|
||||
return nil, fmt.Errorf("set invite file info: %w", err)
|
||||
}
|
||||
|
||||
err = aclClient.AddRecord(ctx, res.InviteRec)
|
||||
if err != nil {
|
||||
removeInviteFile()
|
||||
return nil, fmt.Errorf("%w, %w", ErrAclRequestFailed, err)
|
||||
}
|
||||
|
||||
return &InviteInfo{
|
||||
InviteFileCid: inviteFileCid.String(),
|
||||
InviteFileKey: inviteFileKeyRaw,
|
||||
}, err
|
||||
}
|
||||
|
||||
func EncodeKeyToBase58(key crypto.SymKey) (string, error) {
|
||||
raw, err := key.Raw()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base58.Encode(raw), nil
|
||||
}
|
||||
|
||||
func DecodeKeyFromBase58(rawString string) (crypto.SymKey, error) {
|
||||
raw, err := base58.Decode(rawString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return crypto.UnmarshallAESKey(raw)
|
||||
}
|
||||
|
||||
func aclIsEmpty(acl list.AclList) bool {
|
||||
isEmpty := len(acl.AclState().Invites()) == 0
|
||||
if !isEmpty {
|
||||
return false
|
||||
}
|
||||
users := 0
|
||||
for _, acc := range acl.AclState().CurrentAccounts() {
|
||||
if !acc.Permissions.NoPermissions() {
|
||||
users++
|
||||
}
|
||||
}
|
||||
return users == 1
|
||||
}
|
||||
|
|
|
@ -3,10 +3,13 @@ package editor
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/types"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/template"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
|
@ -45,6 +48,53 @@ func (p *participant) Init(ctx *smartblock.InitContext) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *participant) ModifyOwnerDetails(profileDetails *types.Struct, aclInfo spaceinfo.ParticipantAclInfo) (err error) {
|
||||
details := buildParticipantDetails(aclInfo.Id, aclInfo.SpaceId, aclInfo.Identity, aclInfo.Permissions, aclInfo.Status)
|
||||
details.Fields[bundle.RelationKeyName.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyName.String()))
|
||||
details.Fields[bundle.RelationKeyDescription.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyDescription.String()))
|
||||
details.Fields[bundle.RelationKeyIconImage.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyIconImage.String()))
|
||||
details.Fields[bundle.RelationKeyIdentityProfileLink.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyId.String()))
|
||||
details.Fields[bundle.RelationKeyGlobalName.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyGlobalName.String()))
|
||||
return p.modifyDetails(details)
|
||||
}
|
||||
|
||||
func (p *participant) ModifyIdentityDetails(profile *model.IdentityProfile) (err error) {
|
||||
details := &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String(profile.Name),
|
||||
bundle.RelationKeyDescription.String(): pbtypes.String(profile.Description),
|
||||
bundle.RelationKeyIconImage.String(): pbtypes.String(profile.IconCid),
|
||||
bundle.RelationKeyGlobalName.String(): pbtypes.String(profile.GlobalName),
|
||||
}}
|
||||
return p.modifyDetails(details)
|
||||
}
|
||||
|
||||
func (p *participant) ModifyParticipantAclState(accState spaceinfo.ParticipantAclInfo) (err error) {
|
||||
details := buildParticipantDetails(accState.Id, accState.SpaceId, accState.Identity, accState.Permissions, accState.Status)
|
||||
return p.modifyDetails(details)
|
||||
}
|
||||
|
||||
func (p *participant) TryClose(objectTTL time.Duration) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (p *participant) modifyDetails(newDetails *types.Struct) (err error) {
|
||||
return p.Apply(p.NewState().SetDetails(pbtypes.StructMerge(p.CombinedDetails(), newDetails, false)))
|
||||
}
|
||||
|
||||
func buildParticipantDetails(
|
||||
id string,
|
||||
spaceId string,
|
||||
identity string,
|
||||
permissions model.ParticipantPermissions,
|
||||
status model.ParticipantStatus,
|
||||
) *types.Struct {
|
||||
return &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyId.String(): pbtypes.String(id),
|
||||
bundle.RelationKeyIdentity.String(): pbtypes.String(identity),
|
||||
bundle.RelationKeySpaceId.String(): pbtypes.String(spaceId),
|
||||
bundle.RelationKeyLastModifiedBy.String(): pbtypes.String(id),
|
||||
bundle.RelationKeyParticipantPermissions.String(): pbtypes.Int64(int64(permissions)),
|
||||
bundle.RelationKeyParticipantStatus.String(): pbtypes.Int64(int64(status)),
|
||||
bundle.RelationKeyIsHiddenDiscovery.String(): pbtypes.Bool(status != model.ParticipantStatus_Active),
|
||||
}}
|
||||
}
|
||||
|
|
|
@ -103,6 +103,21 @@ func (s *SpaceView) initTemplate(st *state.State) {
|
|||
)
|
||||
}
|
||||
|
||||
func (s *SpaceView) GetExistingInviteInfo() (fileCid string, fileKey string) {
|
||||
details := s.CombinedDetails()
|
||||
fileCid = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileCid.String())
|
||||
fileKey = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileKey.String())
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SpaceView) RemoveExistingInviteInfo() (fileCid string, err error) {
|
||||
details := s.Details()
|
||||
fileCid = pbtypes.GetString(details, bundle.RelationKeySpaceInviteFileCid.String())
|
||||
newState := s.NewState()
|
||||
newState.RemoveDetail(bundle.RelationKeySpaceInviteFileCid.String(), bundle.RelationKeySpaceInviteFileKey.String())
|
||||
return fileCid, s.Apply(newState)
|
||||
}
|
||||
|
||||
func (s *SpaceView) TryClose(objectTTL time.Duration) (res bool, err error) {
|
||||
return false, nil
|
||||
}
|
||||
|
@ -162,7 +177,7 @@ func (s *SpaceView) SetInviteFileInfo(fileCid string, fileKey string) (err error
|
|||
}
|
||||
|
||||
func (s *SpaceView) afterApply(info smartblock.ApplyInfo) (err error) {
|
||||
s.spaceService.OnViewUpdated(s.getStatePersistentInfo(info.State))
|
||||
s.spaceService.OnViewUpdated(s.getSpacePersistentInfo(info.State))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -196,7 +211,7 @@ func (s *SpaceView) targetSpaceID() (id string, err error) {
|
|||
return changePayload.Key, nil
|
||||
}
|
||||
|
||||
func (s *SpaceView) getStatePersistentInfo(st *state.State) (info spaceinfo.SpacePersistentInfo) {
|
||||
func (s *SpaceView) getSpacePersistentInfo(st *state.State) (info spaceinfo.SpacePersistentInfo) {
|
||||
details := st.CombinedDetails()
|
||||
spaceInfo := spaceinfo.NewSpacePersistentInfo(pbtypes.GetString(details, bundle.RelationKeyTargetSpaceId.String()))
|
||||
spaceInfo.SetAccountStatus(spaceinfo.AccountStatus(pbtypes.GetInt64(details, bundle.RelationKeySpaceAccountStatus.String()))).
|
||||
|
@ -213,6 +228,13 @@ var workspaceKeysToCopy = []string{
|
|||
bundle.RelationKeyCreatedDate.String(),
|
||||
}
|
||||
|
||||
func (s *SpaceView) GetSpaceDescription() (data spaceinfo.SpaceDescription) {
|
||||
details := s.CombinedDetails()
|
||||
data.Name = pbtypes.GetString(details, bundle.RelationKeyName.String())
|
||||
data.IconImage = pbtypes.GetString(details, bundle.RelationKeyIconImage.String())
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SpaceView) SetSpaceData(details *types.Struct) error {
|
||||
st := s.NewState()
|
||||
var changed bool
|
||||
|
|
275
core/inviteservice/inviteservice.go
Normal file
275
core/inviteservice/inviteservice.go
Normal file
|
@ -0,0 +1,275 @@
|
|||
package inviteservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/logger"
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/ipfs/go-cid"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/anytype/account"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/files/fileacl"
|
||||
"github.com/anyproto/anytype-heart/core/invitestore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
"github.com/anyproto/anytype-heart/util/encode"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInviteNotExists = errors.New("invite not exists")
|
||||
ErrInviteBadSignature = errors.New("invite bad signature")
|
||||
ErrPersonalSpace = errors.New("personal space")
|
||||
)
|
||||
|
||||
type InviteInfo struct {
|
||||
InviteFileCid string
|
||||
InviteFileKey string
|
||||
}
|
||||
|
||||
const CName = "common.core.inviteservice"
|
||||
|
||||
var log = logger.NewNamed(CName)
|
||||
|
||||
type InviteView struct {
|
||||
SpaceId string
|
||||
SpaceName string
|
||||
SpaceIconCid string
|
||||
CreatorName string
|
||||
}
|
||||
|
||||
type InviteService interface {
|
||||
app.ComponentRunnable
|
||||
GetPayload(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (*model.InvitePayload, error)
|
||||
View(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (InviteView, error)
|
||||
RemoveExisting(ctx context.Context, spaceId string) error
|
||||
Generate(ctx context.Context, spaceId string, inviteKey crypto.PrivKey, sendInvite func() error) (InviteInfo, error)
|
||||
GetCurrent(ctx context.Context, spaceId string) (InviteInfo, error)
|
||||
}
|
||||
|
||||
var _ InviteService = (*inviteService)(nil)
|
||||
|
||||
type inviteService struct {
|
||||
inviteStore invitestore.Service
|
||||
fileAcl fileacl.Service
|
||||
accountService account.Service
|
||||
spaceService space.Service
|
||||
}
|
||||
|
||||
func New() InviteService {
|
||||
return &inviteService{}
|
||||
}
|
||||
|
||||
func (i *inviteService) Init(a *app.App) (err error) {
|
||||
i.inviteStore = app.MustComponent[invitestore.Service](a)
|
||||
i.fileAcl = app.MustComponent[fileacl.Service](a)
|
||||
i.accountService = app.MustComponent[account.Service](a)
|
||||
i.spaceService = app.MustComponent[space.Service](a)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *inviteService) Name() (name string) {
|
||||
return CName
|
||||
}
|
||||
|
||||
func (i *inviteService) Run(ctx context.Context) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (i *inviteService) Close(ctx context.Context) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (i *inviteService) View(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (InviteView, error) {
|
||||
invitePayload, err := i.GetPayload(ctx, inviteCid, inviteFileKey)
|
||||
if err != nil {
|
||||
return InviteView{}, fmt.Errorf("get invite payload: %w", err)
|
||||
}
|
||||
return InviteView{
|
||||
SpaceId: invitePayload.SpaceId,
|
||||
SpaceName: invitePayload.SpaceName,
|
||||
SpaceIconCid: invitePayload.SpaceIconCid,
|
||||
CreatorName: invitePayload.CreatorName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *inviteService) GetCurrent(ctx context.Context, spaceId string) (info InviteInfo, err error) {
|
||||
var (
|
||||
fileCid, fileKey string
|
||||
)
|
||||
err = i.spaceService.TechSpace().DoSpaceView(ctx, spaceId, func(spaceView techspace.SpaceView) error {
|
||||
fileCid, fileKey = spaceView.GetExistingInviteInfo()
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
err = fmt.Errorf("get existing invite file info: %w", err)
|
||||
return
|
||||
}
|
||||
if fileCid == "" {
|
||||
err = ErrInviteNotExists
|
||||
return
|
||||
}
|
||||
info.InviteFileCid = fileCid
|
||||
info.InviteFileKey = fileKey
|
||||
return
|
||||
}
|
||||
|
||||
func (i *inviteService) RemoveExisting(ctx context.Context, spaceId string) (err error) {
|
||||
var fileCid string
|
||||
err = i.spaceService.TechSpace().DoSpaceView(ctx, spaceId, func(spaceView techspace.SpaceView) error {
|
||||
fileCid, err = spaceView.RemoveExistingInviteInfo()
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("remove existing invite: %w", err)
|
||||
}
|
||||
invCid, err := cid.Decode(fileCid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decode file cid: %w", err)
|
||||
}
|
||||
return i.inviteStore.RemoveInvite(ctx, invCid)
|
||||
}
|
||||
|
||||
func (i *inviteService) Generate(ctx context.Context, spaceId string, inviteKey crypto.PrivKey, sendInvite func() error) (result InviteInfo, err error) {
|
||||
if spaceId == i.accountService.PersonalSpaceID() {
|
||||
return InviteInfo{}, ErrPersonalSpace
|
||||
}
|
||||
var fileCid, fileKey string
|
||||
err = i.spaceService.TechSpace().DoSpaceView(ctx, spaceId, func(spaceView techspace.SpaceView) error {
|
||||
fileCid, fileKey = spaceView.GetExistingInviteInfo()
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return InviteInfo{}, fmt.Errorf("get space view id: %w", err)
|
||||
}
|
||||
if fileCid != "" {
|
||||
return InviteInfo{
|
||||
InviteFileCid: fileCid,
|
||||
InviteFileKey: fileKey,
|
||||
}, nil
|
||||
}
|
||||
invite, err := i.buildInvite(ctx, spaceId, inviteKey)
|
||||
if err != nil {
|
||||
return InviteInfo{}, fmt.Errorf("build invite: %w", err)
|
||||
}
|
||||
inviteFileCid, inviteFileKey, err := i.inviteStore.StoreInvite(ctx, invite)
|
||||
if err != nil {
|
||||
return InviteInfo{}, fmt.Errorf("store invite in ipfs: %w", err)
|
||||
}
|
||||
removeInviteFile := func() {
|
||||
err := i.inviteStore.RemoveInvite(ctx, inviteFileCid)
|
||||
if err != nil {
|
||||
log.Error("remove invite file", zap.Error(err))
|
||||
}
|
||||
}
|
||||
inviteFileKeyRaw, err := encode.EncodeKeyToBase58(inviteFileKey)
|
||||
if err != nil {
|
||||
removeInviteFile()
|
||||
return InviteInfo{}, fmt.Errorf("encode invite file key: %w", err)
|
||||
}
|
||||
err = i.spaceService.TechSpace().DoSpaceView(ctx, spaceId, func(spaceView techspace.SpaceView) error {
|
||||
return spaceView.SetInviteFileInfo(inviteFileCid.String(), inviteFileKeyRaw)
|
||||
})
|
||||
if err != nil {
|
||||
removeInviteFile()
|
||||
return InviteInfo{}, fmt.Errorf("set invite file info: %w", err)
|
||||
}
|
||||
err = sendInvite()
|
||||
if err != nil {
|
||||
_ = i.RemoveExisting(ctx, spaceId)
|
||||
return InviteInfo{}, fmt.Errorf("failed to send invite: %w", err)
|
||||
}
|
||||
return InviteInfo{
|
||||
InviteFileCid: inviteFileCid.String(),
|
||||
InviteFileKey: inviteFileKeyRaw,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (i *inviteService) buildInvite(ctx context.Context, spaceId string, inviteKey crypto.PrivKey) (*model.Invite, error) {
|
||||
invitePayload, err := i.buildInvitePayload(ctx, spaceId, inviteKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("build invite payload: %w", err)
|
||||
}
|
||||
invitePayloadRaw, err := proto.Marshal(invitePayload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal invite payload: %w", err)
|
||||
}
|
||||
invitePayloadSignature, err := i.accountService.SignData(invitePayloadRaw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sign invite payload: %w", err)
|
||||
}
|
||||
return &model.Invite{
|
||||
Payload: invitePayloadRaw,
|
||||
Signature: invitePayloadSignature,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *inviteService) buildInvitePayload(ctx context.Context, spaceId string, inviteKey crypto.PrivKey) (*model.InvitePayload, error) {
|
||||
profile, err := i.accountService.ProfileInfo()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get profile info: %w", err)
|
||||
}
|
||||
rawInviteKey, err := inviteKey.Marshall()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal invite priv key: %w", err)
|
||||
}
|
||||
invitePayload := &model.InvitePayload{
|
||||
SpaceId: spaceId,
|
||||
CreatorIdentity: i.accountService.AccountID(),
|
||||
CreatorName: profile.Name,
|
||||
InviteKey: rawInviteKey,
|
||||
}
|
||||
var description spaceinfo.SpaceDescription
|
||||
err = i.spaceService.TechSpace().DoSpaceView(ctx, spaceId, func(spaceView techspace.SpaceView) error {
|
||||
description = spaceView.GetSpaceDescription()
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get space description: %w", err)
|
||||
}
|
||||
if description.IconImage != "" {
|
||||
iconCid, iconEncryptionKeys, err := i.fileAcl.GetInfoForFileSharing(ctx, description.IconImage)
|
||||
if err == nil {
|
||||
invitePayload.SpaceIconCid = iconCid
|
||||
invitePayload.SpaceIconEncryptionKeys = iconEncryptionKeys
|
||||
} else {
|
||||
log.Error("get space icon info", zap.Error(err))
|
||||
}
|
||||
}
|
||||
return invitePayload, nil
|
||||
}
|
||||
|
||||
func (i *inviteService) GetPayload(ctx context.Context, inviteCid cid.Cid, inviteFileKey crypto.SymKey) (*model.InvitePayload, error) {
|
||||
invite, err := i.inviteStore.GetInvite(ctx, inviteCid, inviteFileKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get invite: %w", err)
|
||||
}
|
||||
var invitePayload model.InvitePayload
|
||||
err = proto.Unmarshal(invite.Payload, &invitePayload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unmarshal invite payload: %w", err)
|
||||
}
|
||||
creatorIdentity, err := crypto.DecodeAccountAddress(invitePayload.CreatorIdentity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode creator identity: %w", err)
|
||||
}
|
||||
ok, err := creatorIdentity.Verify(invite.Payload, invite.Signature)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("verify invite signature: %w", err)
|
||||
}
|
||||
if !ok {
|
||||
return nil, ErrInviteBadSignature
|
||||
}
|
||||
err = i.fileAcl.StoreFileKeys(domain.FileId(invitePayload.SpaceIconCid), invitePayload.SpaceIconEncryptionKeys)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("store icon keys: %w", err)
|
||||
}
|
||||
return &invitePayload, nil
|
||||
}
|
|
@ -11,9 +11,11 @@ import (
|
|||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/acl"
|
||||
"github.com/anyproto/anytype-heart/core/inviteservice"
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space"
|
||||
"github.com/anyproto/anytype-heart/util/encode"
|
||||
)
|
||||
|
||||
func (mw *Middleware) SpaceDelete(cctx context.Context, req *pb.RpcSpaceDeleteRequest) *pb.RpcSpaceDeleteResponse {
|
||||
|
@ -39,6 +41,26 @@ func (mw *Middleware) SpaceDelete(cctx context.Context, req *pb.RpcSpaceDeleteRe
|
|||
}
|
||||
}
|
||||
|
||||
func (mw *Middleware) SpaceMakeShareable(cctx context.Context, req *pb.RpcSpaceMakeShareableRequest) *pb.RpcSpaceMakeShareableResponse {
|
||||
aclService := getService[acl.AclService](mw)
|
||||
err := aclService.MakeShareable(cctx, req.SpaceId)
|
||||
if err != nil {
|
||||
code := mapErrorCode(err,
|
||||
errToCode(space.ErrSpaceDeleted, pb.RpcSpaceMakeShareableResponseError_SPACE_IS_DELETED),
|
||||
errToCode(space.ErrSpaceNotExists, pb.RpcSpaceMakeShareableResponseError_NO_SUCH_SPACE),
|
||||
errToCode(acl.ErrPersonalSpace, pb.RpcSpaceMakeShareableResponseError_BAD_INPUT),
|
||||
errToCode(acl.ErrAclRequestFailed, pb.RpcSpaceMakeShareableResponseError_REQUEST_FAILED),
|
||||
)
|
||||
return &pb.RpcSpaceMakeShareableResponse{
|
||||
Error: &pb.RpcSpaceMakeShareableResponseError{
|
||||
Code: code,
|
||||
Description: getErrorDescription(err),
|
||||
},
|
||||
}
|
||||
}
|
||||
return &pb.RpcSpaceMakeShareableResponse{}
|
||||
}
|
||||
|
||||
func (mw *Middleware) SpaceInviteGenerate(cctx context.Context, req *pb.RpcSpaceInviteGenerateRequest) *pb.RpcSpaceInviteGenerateResponse {
|
||||
aclService := getService[acl.AclService](mw)
|
||||
inviteInfo, err := aclService.GenerateInvite(cctx, req.SpaceId)
|
||||
|
@ -64,7 +86,7 @@ func (mw *Middleware) SpaceInviteGenerate(cctx context.Context, req *pb.RpcSpace
|
|||
|
||||
func (mw *Middleware) SpaceInviteGetCurrent(cctx context.Context, req *pb.RpcSpaceInviteGetCurrentRequest) *pb.RpcSpaceInviteGetCurrentResponse {
|
||||
aclService := getService[acl.AclService](mw)
|
||||
inviteInfo, err := aclService.GetCurrentInvite(req.SpaceId)
|
||||
inviteInfo, err := aclService.GetCurrentInvite(cctx, req.SpaceId)
|
||||
if err != nil {
|
||||
code := mapErrorCode(err,
|
||||
errToCode(acl.ErrInviteNotExists, pb.RpcSpaceInviteGetCurrentResponseError_NO_ACTIVE_INVITE),
|
||||
|
@ -120,14 +142,14 @@ func (mw *Middleware) SpaceInviteView(cctx context.Context, req *pb.RpcSpaceInvi
|
|||
}
|
||||
}
|
||||
|
||||
func viewInvite(ctx context.Context, aclService acl.AclService, req *pb.RpcSpaceInviteViewRequest) (*acl.InviteView, error) {
|
||||
inviteFileKey, err := acl.DecodeKeyFromBase58(req.InviteFileKey)
|
||||
func viewInvite(ctx context.Context, aclService acl.AclService, req *pb.RpcSpaceInviteViewRequest) (inviteservice.InviteView, error) {
|
||||
inviteFileKey, err := encode.DecodeKeyFromBase58(req.InviteFileKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode key: %w", err)
|
||||
return inviteservice.InviteView{}, fmt.Errorf("decode key: %w", err)
|
||||
}
|
||||
inviteCid, err := cid.Decode(req.InviteCid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return inviteservice.InviteView{}, err
|
||||
}
|
||||
return aclService.ViewInvite(ctx, inviteCid, inviteFileKey)
|
||||
}
|
||||
|
@ -281,7 +303,7 @@ func (mw *Middleware) SpaceLeaveApprove(cctx context.Context, req *pb.RpcSpaceLe
|
|||
}
|
||||
|
||||
func join(ctx context.Context, aclService acl.AclService, req *pb.RpcSpaceJoinRequest) (err error) {
|
||||
inviteFileKey, err := acl.DecodeKeyFromBase58(req.InviteFileKey)
|
||||
inviteFileKey, err := encode.DecodeKeyFromBase58(req.InviteFileKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -7,7 +7,7 @@ require (
|
|||
github.com/PuerkitoBio/goquery v1.9.1
|
||||
github.com/VividCortex/ewma v1.2.0
|
||||
github.com/adrium/goheif v0.0.0-20230113233934-ca402e77a786
|
||||
github.com/anyproto/any-sync v0.4.0
|
||||
github.com/anyproto/any-sync v0.4.1-0.20240407113735-3d52c4c395f5
|
||||
github.com/anyproto/go-naturaldate/v2 v2.0.2-0.20230524105841-9829cfd13438
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
|
||||
github.com/avast/retry-go/v4 v4.5.1
|
||||
|
|
19
go.sum
19
go.sum
|
@ -89,10 +89,8 @@ github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxB
|
|||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
|
||||
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
|
||||
github.com/anyproto/any-sync v0.3.36-0.20240402120641-e2866e9340d6 h1:6no9+otZ5lT0gZ5zz+3Rh42FeqTR+YZx6ZY8I8sbQKs=
|
||||
github.com/anyproto/any-sync v0.3.36-0.20240402120641-e2866e9340d6/go.mod h1:rIv4hBJm1vHm2UdnWdBCYQzTtVK5utN7KkuKeMkLJnc=
|
||||
github.com/anyproto/any-sync v0.4.0 h1:EF9tjSd6er3zpuoO5gJhKuF65sx7YSSJjEvrWqVUZdI=
|
||||
github.com/anyproto/any-sync v0.4.0/go.mod h1:LclTfV2oKjwGqeMzWkRglivCg8+NmcDHZXeozyHho6w=
|
||||
github.com/anyproto/any-sync v0.4.1-0.20240407113735-3d52c4c395f5 h1:soaU7D5l7acQE0Z/xfjDshxPAXjeQtOaR7ZyM6XH8Q8=
|
||||
github.com/anyproto/any-sync v0.4.1-0.20240407113735-3d52c4c395f5/go.mod h1:LclTfV2oKjwGqeMzWkRglivCg8+NmcDHZXeozyHho6w=
|
||||
github.com/anyproto/badger/v4 v4.2.1-0.20240110160636-80743fa3d580 h1:Ba80IlCCxkZ9H1GF+7vFu/TSpPvbpDCxXJ5ogc4euYc=
|
||||
github.com/anyproto/badger/v4 v4.2.1-0.20240110160636-80743fa3d580/go.mod h1:T/uWAYxrXdaXw64ihI++9RMbKTCpKd/yE9+saARew7k=
|
||||
github.com/anyproto/go-chash v0.1.0 h1:I9meTPjXFRfXZHRJzjOHC/XF7Q5vzysKkiT/grsogXY=
|
||||
|
@ -385,8 +383,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
|||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
|
@ -522,8 +518,6 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
|
|||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo=
|
||||
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f h1:f00RU+zOX+B3rLAmMMkzHUF2h1z4DeYR9tTCvEq2REY=
|
||||
github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
|
@ -1165,8 +1159,6 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
|||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
|
@ -1552,8 +1544,6 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
|
||||
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
|
@ -1588,8 +1578,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -1868,8 +1856,7 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
|||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/object/objectcache"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/space/internal/techspace"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
)
|
||||
|
||||
type TechSpace struct {
|
||||
|
|
|
@ -2,29 +2,21 @@ package aclobjectmanager
|
|||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/debugstat"
|
||||
"github.com/anyproto/any-sync/app/logger"
|
||||
"github.com/anyproto/any-sync/commonspace"
|
||||
"github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto"
|
||||
"github.com/anyproto/any-sync/commonspace/object/acl/list"
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
"github.com/anyproto/any-sync/util/crypto/cryptoproto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/aclnotifications"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/dependencies"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/participantwatcher"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/spaceloader"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/spacestatus"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
||||
const CName = "common.components.aclobjectmanager"
|
||||
|
@ -51,15 +43,13 @@ type aclObjectManager struct {
|
|||
loadErr error
|
||||
spaceLoader spaceloader.SpaceLoader
|
||||
status spacestatus.SpaceStatus
|
||||
modifier dependencies.DetailsModifier
|
||||
identityService dependencies.IdentityService
|
||||
indexer dependencies.SpaceIndexer
|
||||
statService debugstat.StatService
|
||||
started bool
|
||||
notificationService aclnotifications.AclNotification
|
||||
participantWatcher participantwatcher.ParticipantWatcher
|
||||
|
||||
ownerMetadata []byte
|
||||
mx sync.Mutex
|
||||
lastIndexed string
|
||||
addedParticipants map[string]struct{}
|
||||
}
|
||||
|
@ -93,10 +83,9 @@ func (a *aclObjectManager) UpdateAcl(aclList list.AclList) {
|
|||
|
||||
func (a *aclObjectManager) Init(ap *app.App) (err error) {
|
||||
a.spaceLoader = ap.MustComponent(spaceloader.CName).(spaceloader.SpaceLoader)
|
||||
a.modifier = app.MustComponent[dependencies.DetailsModifier](ap)
|
||||
a.identityService = app.MustComponent[dependencies.IdentityService](ap)
|
||||
a.indexer = app.MustComponent[dependencies.SpaceIndexer](ap)
|
||||
a.status = app.MustComponent[spacestatus.SpaceStatus](ap)
|
||||
a.participantWatcher = app.MustComponent[participantwatcher.ParticipantWatcher](ap)
|
||||
a.notificationService = app.MustComponent[aclnotifications.AclNotification](ap)
|
||||
a.statService, _ = ap.Component(debugstat.CName).(debugstat.StatService)
|
||||
if a.statService == nil {
|
||||
|
@ -113,7 +102,7 @@ func (a *aclObjectManager) Name() (name string) {
|
|||
}
|
||||
|
||||
func (a *aclObjectManager) Run(ctx context.Context) (err error) {
|
||||
err = a.clearAclIndexes()
|
||||
err = a.indexer.RemoveAclIndexes(a.status.SpaceId())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -130,7 +119,6 @@ func (a *aclObjectManager) Close(ctx context.Context) (err error) {
|
|||
}
|
||||
a.cancel()
|
||||
<-a.wait
|
||||
a.identityService.UnregisterIdentitiesInSpace(a.status.SpaceId())
|
||||
a.statService.RemoveProvider(a)
|
||||
return
|
||||
}
|
||||
|
@ -152,7 +140,7 @@ func (a *aclObjectManager) process() {
|
|||
break
|
||||
}
|
||||
|
||||
err := a.initAndRegisterMyIdentity(a.ctx)
|
||||
err := a.participantWatcher.RegisterOwnerIdentity(a.ctx, a.sp)
|
||||
if err != nil {
|
||||
log.Error("init my identity", zap.Error(err))
|
||||
}
|
||||
|
@ -167,195 +155,63 @@ func (a *aclObjectManager) process() {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *aclObjectManager) sendNotifications(common commonspace.Space) {
|
||||
permissions := common.Acl().AclState().Permissions(common.Acl().AclState().AccountKey().GetPublic())
|
||||
a.notificationService.AddRecords(common.Acl().(list.AclList), permissions, a.sp.Id(), spaceinfo.AccountStatusActive)
|
||||
}
|
||||
|
||||
func (a *aclObjectManager) initAndRegisterMyIdentity(ctx context.Context) error {
|
||||
myIdentity, metadataKey, profileDetails := a.identityService.GetMyProfileDetails()
|
||||
id := domain.NewParticipantId(a.sp.Id(), myIdentity)
|
||||
_, err := a.sp.GetObject(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
details := buildParticipantDetails(id, a.sp.Id(), myIdentity, model.ParticipantPermissions_Owner, model.ParticipantStatus_Active)
|
||||
details.Fields[bundle.RelationKeyName.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyName.String()))
|
||||
details.Fields[bundle.RelationKeyDescription.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyDescription.String()))
|
||||
details.Fields[bundle.RelationKeyIconImage.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyIconImage.String()))
|
||||
details.Fields[bundle.RelationKeyIdentityProfileLink.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyId.String()))
|
||||
details.Fields[bundle.RelationKeyGlobalName.String()] = pbtypes.String(pbtypes.GetString(profileDetails, bundle.RelationKeyGlobalName.String()))
|
||||
err = a.modifier.ModifyDetails(id, func(current *types.Struct) (*types.Struct, error) {
|
||||
return pbtypes.StructMerge(current, details, false), nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.identityService.RegisterIdentity(a.sp.Id(), myIdentity, metadataKey,
|
||||
func(identity string, profile *model.IdentityProfile) {
|
||||
err := a.updateParticipantFromIdentity(a.ctx, identity, profile)
|
||||
if err != nil {
|
||||
log.Error("error updating participant from identity", zap.Error(err))
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.mx.Lock()
|
||||
a.addedParticipants[myIdentity] = struct{}{}
|
||||
a.mx.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *aclObjectManager) clearAclIndexes() (err error) {
|
||||
return a.indexer.RemoveAclIndexes(a.status.SpaceId())
|
||||
}
|
||||
|
||||
func (a *aclObjectManager) processAcl() (err error) {
|
||||
common := a.sp.CommonSpace()
|
||||
a.mx.Lock()
|
||||
var (
|
||||
common = a.sp.CommonSpace()
|
||||
acl = common.Acl()
|
||||
aclState = acl.AclState()
|
||||
)
|
||||
defer func() {
|
||||
if err == nil {
|
||||
permissions := aclState.Permissions(aclState.AccountKey().GetPublic())
|
||||
a.notificationService.AddRecords(acl, permissions, common.Id(), spaceinfo.AccountStatusActive)
|
||||
}
|
||||
}()
|
||||
lastIndexed := a.lastIndexed
|
||||
a.mx.Unlock()
|
||||
if lastIndexed == common.Acl().Head().Id {
|
||||
a.mx.Lock()
|
||||
a.sendNotifications(common)
|
||||
a.mx.Unlock()
|
||||
return nil
|
||||
if lastIndexed == acl.Head().Id {
|
||||
return
|
||||
}
|
||||
decrypt := func(key crypto.PubKey) ([]byte, error) {
|
||||
if a.ownerMetadata != nil {
|
||||
return a.ownerMetadata, nil
|
||||
}
|
||||
return common.Acl().AclState().GetMetadata(key, true)
|
||||
return aclState.GetMetadata(key, true)
|
||||
}
|
||||
states := common.Acl().AclState().CurrentAccounts()
|
||||
states := aclState.CurrentAccounts()
|
||||
// decrypt all metadata
|
||||
states, err = decryptAll(states, decrypt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
a.mx.Lock()
|
||||
defer a.mx.Unlock()
|
||||
aclHeadId := a.status.GetLatestAclHeadId()
|
||||
var upToDate bool
|
||||
if aclHeadId != "" {
|
||||
_, err := common.Acl().Get(aclHeadId)
|
||||
if err == nil {
|
||||
upToDate = true
|
||||
}
|
||||
} else {
|
||||
upToDate = true
|
||||
}
|
||||
err = a.processStates(states, upToDate, common.Acl().AclState().Identity())
|
||||
statusAclHeadId := a.status.GetLatestAclHeadId()
|
||||
upToDate := statusAclHeadId == "" || acl.HasHead(statusAclHeadId)
|
||||
err = a.processStates(states, upToDate, aclState.Identity())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
a.lastIndexed = common.Acl().Head().Id
|
||||
a.sendNotifications(common)
|
||||
err = a.status.SetAclIsEmpty(aclState.IsEmpty())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
a.lastIndexed = acl.Head().Id
|
||||
return
|
||||
}
|
||||
|
||||
func (a *aclObjectManager) processStates(states []list.AccountState, upToDate bool, myIdentity crypto.PubKey) (err error) {
|
||||
var numActiveUsers int
|
||||
for _, state := range states {
|
||||
if state.Permissions.NoPermissions() && state.PubKey.Equals(myIdentity) && upToDate {
|
||||
return a.status.SetPersistentStatus(spaceinfo.AccountStatusRemoving)
|
||||
}
|
||||
if !state.Permissions.NoPermissions() {
|
||||
numActiveUsers++
|
||||
}
|
||||
err := a.updateParticipantFromAclState(a.ctx, state)
|
||||
err := a.participantWatcher.UpdateParticipantFromAclState(a.ctx, a.sp, state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, err := getSymKey(state.RequestMetadata)
|
||||
err = a.participantWatcher.RegisterIdentity(a.ctx, a.sp, state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accKey := state.PubKey.Account()
|
||||
if _, exists := a.addedParticipants[state.PubKey.Account()]; exists {
|
||||
continue
|
||||
}
|
||||
err = a.identityService.RegisterIdentity(a.sp.Id(), state.PubKey.Account(), key,
|
||||
func(identity string, profile *model.IdentityProfile) {
|
||||
err := a.updateParticipantFromIdentity(a.ctx, identity, profile)
|
||||
if err != nil {
|
||||
log.Error("error updating participant from identity", zap.Error(err))
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.addedParticipants[accKey] = struct{}{}
|
||||
}
|
||||
isEmpty := len(a.sp.CommonSpace().Acl().AclState().Invites()) == 0 && numActiveUsers == 1
|
||||
return a.status.SetAclIsEmpty(isEmpty)
|
||||
}
|
||||
|
||||
func (a *aclObjectManager) updateParticipantFromAclState(ctx context.Context, accState list.AccountState) (err error) {
|
||||
id := domain.NewParticipantId(a.sp.Id(), accState.PubKey.Account())
|
||||
_, err = a.sp.GetObject(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
details := buildParticipantDetails(
|
||||
id,
|
||||
a.sp.Id(),
|
||||
accState.PubKey.Account(),
|
||||
convertPermissions(accState.Permissions),
|
||||
convertStatus(accState.Status))
|
||||
return a.modifier.ModifyDetails(id, func(current *types.Struct) (*types.Struct, error) {
|
||||
return pbtypes.StructMerge(current, details, false), nil
|
||||
})
|
||||
}
|
||||
|
||||
func (a *aclObjectManager) updateParticipantFromIdentity(ctx context.Context, identity string, profile *model.IdentityProfile) (err error) {
|
||||
id := domain.NewParticipantId(a.sp.Id(), identity)
|
||||
_, err = a.sp.GetObject(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
details := &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyName.String(): pbtypes.String(profile.Name),
|
||||
bundle.RelationKeyDescription.String(): pbtypes.String(profile.Description),
|
||||
bundle.RelationKeyIconImage.String(): pbtypes.String(profile.IconCid),
|
||||
bundle.RelationKeyGlobalName.String(): pbtypes.String(profile.GlobalName),
|
||||
}}
|
||||
return a.modifier.ModifyDetails(id, func(current *types.Struct) (*types.Struct, error) {
|
||||
return pbtypes.StructMerge(current, details, false), nil
|
||||
})
|
||||
}
|
||||
|
||||
func convertPermissions(permissions list.AclPermissions) model.ParticipantPermissions {
|
||||
switch aclrecordproto.AclUserPermissions(permissions) {
|
||||
case aclrecordproto.AclUserPermissions_Writer:
|
||||
return model.ParticipantPermissions_Writer
|
||||
case aclrecordproto.AclUserPermissions_Reader:
|
||||
return model.ParticipantPermissions_Reader
|
||||
case aclrecordproto.AclUserPermissions_Owner:
|
||||
return model.ParticipantPermissions_Owner
|
||||
}
|
||||
return model.ParticipantPermissions_NoPermissions
|
||||
}
|
||||
|
||||
func convertStatus(status list.AclStatus) model.ParticipantStatus {
|
||||
switch status {
|
||||
case list.StatusJoining:
|
||||
return model.ParticipantStatus_Joining
|
||||
case list.StatusActive:
|
||||
return model.ParticipantStatus_Active
|
||||
case list.StatusRemoved:
|
||||
return model.ParticipantStatus_Removed
|
||||
case list.StatusDeclined:
|
||||
return model.ParticipantStatus_Declined
|
||||
case list.StatusRemoving:
|
||||
return model.ParticipantStatus_Removing
|
||||
case list.StatusCanceled:
|
||||
return model.ParticipantStatus_Canceled
|
||||
}
|
||||
return model.ParticipantStatus_Active
|
||||
return nil
|
||||
}
|
||||
|
||||
func decryptAll(states []list.AccountState, decrypt func(key crypto.PubKey) ([]byte, error)) (decrypted []list.AccountState, err error) {
|
||||
|
@ -369,35 +225,3 @@ func decryptAll(states []list.AccountState, decrypt func(key crypto.PubKey) ([]b
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getSymKey(metadata []byte) (crypto.SymKey, error) {
|
||||
md := &model.Metadata{}
|
||||
err := md.Unmarshal(metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyProto := &cryptoproto.Key{}
|
||||
err = keyProto.Unmarshal(md.GetIdentity().GetProfileSymKey())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return crypto.UnmarshallAESKey(keyProto.Data)
|
||||
}
|
||||
|
||||
func buildParticipantDetails(
|
||||
id string,
|
||||
spaceId string,
|
||||
identity string,
|
||||
permissions model.ParticipantPermissions,
|
||||
status model.ParticipantStatus,
|
||||
) *types.Struct {
|
||||
return &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyId.String(): pbtypes.String(id),
|
||||
bundle.RelationKeyIdentity.String(): pbtypes.String(identity),
|
||||
bundle.RelationKeySpaceId.String(): pbtypes.String(spaceId),
|
||||
bundle.RelationKeyLastModifiedBy.String(): pbtypes.String(id),
|
||||
bundle.RelationKeyParticipantPermissions.String(): pbtypes.Int64(int64(permissions)),
|
||||
bundle.RelationKeyParticipantStatus.String(): pbtypes.Int64(int64(status)),
|
||||
bundle.RelationKeyIsHiddenDiscovery.String(): pbtypes.Bool(status != model.ParticipantStatus_Active),
|
||||
}}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space/clientspace"
|
||||
dependencies2 "github.com/anyproto/anytype-heart/space/internal/components/dependencies"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/spacestatus"
|
||||
"github.com/anyproto/anytype-heart/space/internal/techspace"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore/storage"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
)
|
||||
|
||||
const CName = "client.components.builder"
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
package participantwatcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/logger"
|
||||
"github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto"
|
||||
"github.com/anyproto/any-sync/commonspace/object/acl/list"
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
"github.com/anyproto/any-sync/util/crypto/cryptoproto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/dependencies"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/spacestatus"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
)
|
||||
|
||||
const CName = "common.components.participantwatcher"
|
||||
|
||||
var log = logger.NewNamed(CName)
|
||||
|
||||
type ParticipantWatcher interface {
|
||||
app.ComponentRunnable
|
||||
RegisterIdentity(ctx context.Context, space clientspace.Space, accState list.AccountState) error
|
||||
RegisterOwnerIdentity(ctx context.Context, space clientspace.Space) error
|
||||
UpdateParticipantFromAclState(ctx context.Context, space clientspace.Space, accState list.AccountState) error
|
||||
}
|
||||
|
||||
type participant interface {
|
||||
ModifyIdentityDetails(profile *model.IdentityProfile) (err error)
|
||||
ModifyOwnerDetails(profileDetails *types.Struct, aclInfo spaceinfo.ParticipantAclInfo) (err error)
|
||||
ModifyParticipantAclState(accState spaceinfo.ParticipantAclInfo) (err error)
|
||||
}
|
||||
|
||||
var _ ParticipantWatcher = (*participantWatcher)(nil)
|
||||
|
||||
type participantWatcher struct {
|
||||
identityService dependencies.IdentityService
|
||||
modifier dependencies.DetailsModifier
|
||||
status spacestatus.SpaceStatus
|
||||
mx sync.Mutex
|
||||
addedParticipants map[string]struct{}
|
||||
}
|
||||
|
||||
func New() ParticipantWatcher {
|
||||
return &participantWatcher{
|
||||
addedParticipants: map[string]struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *participantWatcher) RegisterIdentity(ctx context.Context, space clientspace.Space, state list.AccountState) (err error) {
|
||||
p.mx.Lock()
|
||||
defer p.mx.Unlock()
|
||||
key, err := getSymKey(state.RequestMetadata)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
accKey := state.PubKey.Account()
|
||||
if _, exists := p.addedParticipants[state.PubKey.Account()]; exists {
|
||||
return
|
||||
}
|
||||
err = p.identityService.RegisterIdentity(space.Id(), state.PubKey.Account(), key, func(identity string, profile *model.IdentityProfile) {
|
||||
err := p.updateParticipantFromIdentity(ctx, space, identity, profile)
|
||||
if err != nil {
|
||||
log.Error("error updating participant from identity", zap.Error(err))
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.addedParticipants[accKey] = struct{}{}
|
||||
return
|
||||
}
|
||||
|
||||
func (p *participantWatcher) Init(a *app.App) (err error) {
|
||||
p.identityService = app.MustComponent[dependencies.IdentityService](a)
|
||||
p.modifier = app.MustComponent[dependencies.DetailsModifier](a)
|
||||
p.status = app.MustComponent[spacestatus.SpaceStatus](a)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *participantWatcher) Name() (name string) {
|
||||
return CName
|
||||
}
|
||||
|
||||
func (p *participantWatcher) Close(ctx context.Context) (err error) {
|
||||
p.identityService.UnregisterIdentitiesInSpace(p.status.SpaceId())
|
||||
return
|
||||
}
|
||||
|
||||
func (p *participantWatcher) RegisterOwnerIdentity(ctx context.Context, space clientspace.Space) error {
|
||||
p.mx.Lock()
|
||||
defer p.mx.Unlock()
|
||||
myIdentity, metadataKey, profileDetails := p.identityService.GetMyProfileDetails()
|
||||
id := domain.NewParticipantId(space.Id(), myIdentity)
|
||||
err := space.Do(id, func(sb smartblock.SmartBlock) error {
|
||||
return sb.(participant).ModifyOwnerDetails(profileDetails, spaceinfo.ParticipantAclInfo{
|
||||
Id: id,
|
||||
SpaceId: space.Id(),
|
||||
Identity: myIdentity,
|
||||
Permissions: model.ParticipantPermissions_Owner,
|
||||
Status: model.ParticipantStatus_Active,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = p.identityService.RegisterIdentity(space.Id(), myIdentity, metadataKey, func(identity string, profile *model.IdentityProfile) {
|
||||
err := p.updateParticipantFromIdentity(ctx, space, identity, profile)
|
||||
if err != nil {
|
||||
log.Error("error updating participant from identity", zap.Error(err))
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.addedParticipants[myIdentity] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *participantWatcher) UpdateParticipantFromAclState(ctx context.Context, space clientspace.Space, accState list.AccountState) error {
|
||||
id := domain.NewParticipantId(space.Id(), accState.PubKey.Account())
|
||||
return space.Do(id, func(sb smartblock.SmartBlock) error {
|
||||
return sb.(participant).ModifyParticipantAclState(spaceinfo.ParticipantAclInfo{
|
||||
Id: id,
|
||||
SpaceId: space.Id(),
|
||||
Identity: accState.PubKey.Account(),
|
||||
Permissions: convertPermissions(accState.Permissions),
|
||||
Status: convertStatus(accState.Status),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (p *participantWatcher) updateParticipantFromIdentity(ctx context.Context, space clientspace.Space, identity string, profile *model.IdentityProfile) (err error) {
|
||||
id := domain.NewParticipantId(space.Id(), identity)
|
||||
return space.Do(id, func(sb smartblock.SmartBlock) error {
|
||||
return sb.(participant).ModifyIdentityDetails(profile)
|
||||
})
|
||||
}
|
||||
|
||||
func (p *participantWatcher) Run(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getSymKey(metadata []byte) (crypto.SymKey, error) {
|
||||
md := &model.Metadata{}
|
||||
err := md.Unmarshal(metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyProto := &cryptoproto.Key{}
|
||||
err = keyProto.Unmarshal(md.GetIdentity().GetProfileSymKey())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return crypto.UnmarshallAESKey(keyProto.Data)
|
||||
}
|
||||
|
||||
func convertPermissions(permissions list.AclPermissions) model.ParticipantPermissions {
|
||||
switch aclrecordproto.AclUserPermissions(permissions) {
|
||||
case aclrecordproto.AclUserPermissions_Writer:
|
||||
return model.ParticipantPermissions_Writer
|
||||
case aclrecordproto.AclUserPermissions_Reader:
|
||||
return model.ParticipantPermissions_Reader
|
||||
case aclrecordproto.AclUserPermissions_Owner:
|
||||
return model.ParticipantPermissions_Owner
|
||||
}
|
||||
return model.ParticipantPermissions_NoPermissions
|
||||
}
|
||||
|
||||
func convertStatus(status list.AclStatus) model.ParticipantStatus {
|
||||
switch status {
|
||||
case list.StatusJoining:
|
||||
return model.ParticipantStatus_Joining
|
||||
case list.StatusActive:
|
||||
return model.ParticipantStatus_Active
|
||||
case list.StatusRemoved:
|
||||
return model.ParticipantStatus_Removed
|
||||
case list.StatusDeclined:
|
||||
return model.ParticipantStatus_Declined
|
||||
case list.StatusRemoving:
|
||||
return model.ParticipantStatus_Removing
|
||||
case list.StatusCanceled:
|
||||
return model.ParticipantStatus_Canceled
|
||||
}
|
||||
return model.ParticipantStatus_Active
|
||||
}
|
|
@ -11,9 +11,9 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space/clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/builder"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/spacestatus"
|
||||
"github.com/anyproto/anytype-heart/space/internal/techspace"
|
||||
spaceservice "github.com/anyproto/anytype-heart/space/spacecore"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
)
|
||||
|
||||
const CName = "client.components.spaceloader"
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/debugstat"
|
||||
|
||||
"github.com/anyproto/anytype-heart/space/internal/techspace"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
)
|
||||
|
||||
const CName = "client.components.spacestatus"
|
||||
|
|
|
@ -11,9 +11,9 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space/internal/spacecontroller"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/loader"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/mode"
|
||||
"github.com/anyproto/anytype-heart/space/internal/techspace"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
)
|
||||
|
||||
func NewSpaceController(spaceId string, metadata []byte, a *app.App) spacecontroller.SpaceController {
|
||||
|
|
|
@ -207,12 +207,59 @@ func (_c *MockSpaceController_Mode_Call) RunAndReturn(run func() mode.Mode) *Moc
|
|||
return _c
|
||||
}
|
||||
|
||||
// SetInfo provides a mock function with given fields: ctx, info
|
||||
func (_m *MockSpaceController) SetInfo(ctx context.Context, info spaceinfo.SpacePersistentInfo) error {
|
||||
// SetLocalInfo provides a mock function with given fields: ctx, status
|
||||
func (_m *MockSpaceController) SetLocalInfo(ctx context.Context, status spaceinfo.SpaceLocalInfo) error {
|
||||
ret := _m.Called(ctx, status)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetLocalInfo")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, spaceinfo.SpaceLocalInfo) error); ok {
|
||||
r0 = rf(ctx, status)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceController_SetLocalInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetLocalInfo'
|
||||
type MockSpaceController_SetLocalInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetLocalInfo is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - status spaceinfo.SpaceLocalInfo
|
||||
func (_e *MockSpaceController_Expecter) SetLocalInfo(ctx interface{}, status interface{}) *MockSpaceController_SetLocalInfo_Call {
|
||||
return &MockSpaceController_SetLocalInfo_Call{Call: _e.mock.On("SetLocalInfo", ctx, status)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_SetLocalInfo_Call) Run(run func(ctx context.Context, status spaceinfo.SpaceLocalInfo)) *MockSpaceController_SetLocalInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(spaceinfo.SpaceLocalInfo))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_SetLocalInfo_Call) Return(_a0 error) *MockSpaceController_SetLocalInfo_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_SetLocalInfo_Call) RunAndReturn(run func(context.Context, spaceinfo.SpaceLocalInfo) error) *MockSpaceController_SetLocalInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetPersistentInfo provides a mock function with given fields: ctx, info
|
||||
func (_m *MockSpaceController) SetPersistentInfo(ctx context.Context, info spaceinfo.SpacePersistentInfo) error {
|
||||
ret := _m.Called(ctx, info)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetInfo")
|
||||
panic("no return value specified for SetPersistentInfo")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
|
@ -225,31 +272,31 @@ func (_m *MockSpaceController) SetInfo(ctx context.Context, info spaceinfo.Space
|
|||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceController_SetInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetInfo'
|
||||
type MockSpaceController_SetInfo_Call struct {
|
||||
// MockSpaceController_SetPersistentInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPersistentInfo'
|
||||
type MockSpaceController_SetPersistentInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetInfo is a helper method to define mock.On call
|
||||
// SetPersistentInfo is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - info spaceinfo.SpacePersistentInfo
|
||||
func (_e *MockSpaceController_Expecter) SetInfo(ctx interface{}, info interface{}) *MockSpaceController_SetInfo_Call {
|
||||
return &MockSpaceController_SetInfo_Call{Call: _e.mock.On("SetInfo", ctx, info)}
|
||||
func (_e *MockSpaceController_Expecter) SetPersistentInfo(ctx interface{}, info interface{}) *MockSpaceController_SetPersistentInfo_Call {
|
||||
return &MockSpaceController_SetPersistentInfo_Call{Call: _e.mock.On("SetPersistentInfo", ctx, info)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_SetInfo_Call) Run(run func(ctx context.Context, info spaceinfo.SpacePersistentInfo)) *MockSpaceController_SetInfo_Call {
|
||||
func (_c *MockSpaceController_SetPersistentInfo_Call) Run(run func(ctx context.Context, info spaceinfo.SpacePersistentInfo)) *MockSpaceController_SetPersistentInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(spaceinfo.SpacePersistentInfo))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_SetInfo_Call) Return(_a0 error) *MockSpaceController_SetInfo_Call {
|
||||
func (_c *MockSpaceController_SetPersistentInfo_Call) Return(_a0 error) *MockSpaceController_SetPersistentInfo_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_SetInfo_Call) RunAndReturn(run func(context.Context, spaceinfo.SpacePersistentInfo) error) *MockSpaceController_SetInfo_Call {
|
||||
func (_c *MockSpaceController_SetPersistentInfo_Call) RunAndReturn(run func(context.Context, spaceinfo.SpacePersistentInfo) error) *MockSpaceController_SetPersistentInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
@ -345,17 +392,17 @@ func (_c *MockSpaceController_Start_Call) RunAndReturn(run func(context.Context)
|
|||
return _c
|
||||
}
|
||||
|
||||
// UpdateInfo provides a mock function with given fields: ctx, info
|
||||
func (_m *MockSpaceController) UpdateInfo(ctx context.Context, info spaceinfo.SpacePersistentInfo) error {
|
||||
ret := _m.Called(ctx, info)
|
||||
// Update provides a mock function with given fields:
|
||||
func (_m *MockSpaceController) Update() error {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for UpdateInfo")
|
||||
panic("no return value specified for Update")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, spaceinfo.SpacePersistentInfo) error); ok {
|
||||
r0 = rf(ctx, info)
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
@ -363,78 +410,29 @@ func (_m *MockSpaceController) UpdateInfo(ctx context.Context, info spaceinfo.Sp
|
|||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceController_UpdateInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateInfo'
|
||||
type MockSpaceController_UpdateInfo_Call struct {
|
||||
// MockSpaceController_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update'
|
||||
type MockSpaceController_Update_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// UpdateInfo is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - info spaceinfo.SpacePersistentInfo
|
||||
func (_e *MockSpaceController_Expecter) UpdateInfo(ctx interface{}, info interface{}) *MockSpaceController_UpdateInfo_Call {
|
||||
return &MockSpaceController_UpdateInfo_Call{Call: _e.mock.On("UpdateInfo", ctx, info)}
|
||||
// Update is a helper method to define mock.On call
|
||||
func (_e *MockSpaceController_Expecter) Update() *MockSpaceController_Update_Call {
|
||||
return &MockSpaceController_Update_Call{Call: _e.mock.On("Update")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_UpdateInfo_Call) Run(run func(ctx context.Context, info spaceinfo.SpacePersistentInfo)) *MockSpaceController_UpdateInfo_Call {
|
||||
func (_c *MockSpaceController_Update_Call) Run(run func()) *MockSpaceController_Update_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(spaceinfo.SpacePersistentInfo))
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_UpdateInfo_Call) Return(_a0 error) *MockSpaceController_UpdateInfo_Call {
|
||||
func (_c *MockSpaceController_Update_Call) Return(_a0 error) *MockSpaceController_Update_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_UpdateInfo_Call) RunAndReturn(run func(context.Context, spaceinfo.SpacePersistentInfo) error) *MockSpaceController_UpdateInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// UpdateRemoteStatus provides a mock function with given fields: ctx, status
|
||||
func (_m *MockSpaceController) SetRemoteStatus(ctx context.Context, status spaceinfo.SpaceRemoteStatusInfo) error {
|
||||
ret := _m.Called(ctx, status)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for UpdateRemoteStatus")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, spaceinfo.SpaceRemoteStatusInfo) error); ok {
|
||||
r0 = rf(ctx, status)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceController_UpdateRemoteStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateRemoteStatus'
|
||||
type MockSpaceController_UpdateRemoteStatus_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// UpdateRemoteStatus is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - status spaceinfo.SpaceRemoteStatusInfo
|
||||
func (_e *MockSpaceController_Expecter) UpdateRemoteStatus(ctx interface{}, status interface{}) *MockSpaceController_UpdateRemoteStatus_Call {
|
||||
return &MockSpaceController_UpdateRemoteStatus_Call{Call: _e.mock.On("UpdateRemoteStatus", ctx, status)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_UpdateRemoteStatus_Call) Run(run func(ctx context.Context, status spaceinfo.SpaceRemoteStatusInfo)) *MockSpaceController_UpdateRemoteStatus_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(spaceinfo.SpaceRemoteStatusInfo))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_UpdateRemoteStatus_Call) Return(_a0 error) *MockSpaceController_UpdateRemoteStatus_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceController_UpdateRemoteStatus_Call) RunAndReturn(run func(context.Context, spaceinfo.SpaceRemoteStatusInfo) error) *MockSpaceController_UpdateRemoteStatus_Call {
|
||||
func (_c *MockSpaceController_Update_Call) RunAndReturn(run func() error) *MockSpaceController_Update_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space/internal/components/aclnotifications"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/aclobjectmanager"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/builder"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/participantwatcher"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/spaceloader"
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/spacestatus"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/mode"
|
||||
|
@ -40,7 +41,8 @@ func New(app *app.App, params Params) Loader {
|
|||
Register(builder.New()).
|
||||
Register(spaceloader.New(params.IsPersonal, false)).
|
||||
Register(aclnotifications.NewAclNotificationSender()).
|
||||
Register(aclobjectmanager.New(params.OwnerMetadata))
|
||||
Register(aclobjectmanager.New(params.OwnerMetadata)).
|
||||
Register(participantwatcher.New())
|
||||
return &loader{
|
||||
app: child,
|
||||
}
|
||||
|
|
|
@ -1,239 +0,0 @@
|
|||
// Code generated by mockery. DO NOT EDIT.
|
||||
|
||||
package mock_techspace
|
||||
|
||||
import (
|
||||
spaceinfo "github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
types "github.com/gogo/protobuf/types"
|
||||
)
|
||||
|
||||
// MockSpaceView is an autogenerated mock type for the SpaceView type
|
||||
type MockSpaceView struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockSpaceView_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockSpaceView) EXPECT() *MockSpaceView_Expecter {
|
||||
return &MockSpaceView_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// Lock provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) Lock() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// MockSpaceView_Lock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Lock'
|
||||
type MockSpaceView_Lock_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Lock is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) Lock() *MockSpaceView_Lock_Call {
|
||||
return &MockSpaceView_Lock_Call{Call: _e.mock.On("Lock")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Lock_Call) Run(run func()) *MockSpaceView_Lock_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Lock_Call) Return() *MockSpaceView_Lock_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Lock_Call) RunAndReturn(run func()) *MockSpaceView_Lock_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetSpaceData provides a mock function with given fields: details
|
||||
func (_m *MockSpaceView) SetSpaceData(details *types.Struct) error {
|
||||
ret := _m.Called(details)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetSpaceData")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(*types.Struct) error); ok {
|
||||
r0 = rf(details)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetSpaceData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetSpaceData'
|
||||
type MockSpaceView_SetSpaceData_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetSpaceData is a helper method to define mock.On call
|
||||
// - details *types.Struct
|
||||
func (_e *MockSpaceView_Expecter) SetSpaceData(details interface{}) *MockSpaceView_SetSpaceData_Call {
|
||||
return &MockSpaceView_SetSpaceData_Call{Call: _e.mock.On("SetSpaceData", details)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceData_Call) Run(run func(details *types.Struct)) *MockSpaceView_SetSpaceData_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(*types.Struct))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceData_Call) Return(_a0 error) *MockSpaceView_SetSpaceData_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceData_Call) RunAndReturn(run func(*types.Struct) error) *MockSpaceView_SetSpaceData_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetSpaceLocalInfo provides a mock function with given fields: info
|
||||
func (_m *MockSpaceView) SetSpaceLocalInfo(info spaceinfo.SpaceLocalInfo) error {
|
||||
ret := _m.Called(info)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetSpaceLocalInfo")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(spaceinfo.SpaceLocalInfo) error); ok {
|
||||
r0 = rf(info)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetSpaceLocalInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetSpaceLocalInfo'
|
||||
type MockSpaceView_SetSpaceLocalInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetSpaceLocalInfo is a helper method to define mock.On call
|
||||
// - info spaceinfo.SpaceLocalInfo
|
||||
func (_e *MockSpaceView_Expecter) SetSpaceLocalInfo(info interface{}) *MockSpaceView_SetSpaceLocalInfo_Call {
|
||||
return &MockSpaceView_SetSpaceLocalInfo_Call{Call: _e.mock.On("SetSpaceLocalInfo", info)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceLocalInfo_Call) Run(run func(info spaceinfo.SpaceLocalInfo)) *MockSpaceView_SetSpaceLocalInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(spaceinfo.SpaceLocalInfo))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceLocalInfo_Call) Return(_a0 error) *MockSpaceView_SetSpaceLocalInfo_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceLocalInfo_Call) RunAndReturn(run func(spaceinfo.SpaceLocalInfo) error) *MockSpaceView_SetSpaceLocalInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetSpacePersistentInfo provides a mock function with given fields: info
|
||||
func (_m *MockSpaceView) SetSpacePersistentInfo(info spaceinfo.SpacePersistentInfo) error {
|
||||
ret := _m.Called(info)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetSpacePersistentInfo")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(spaceinfo.SpacePersistentInfo) error); ok {
|
||||
r0 = rf(info)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetSpacePersistentInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetSpacePersistentInfo'
|
||||
type MockSpaceView_SetSpacePersistentInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetSpacePersistentInfo is a helper method to define mock.On call
|
||||
// - info spaceinfo.SpacePersistentInfo
|
||||
func (_e *MockSpaceView_Expecter) SetSpacePersistentInfo(info interface{}) *MockSpaceView_SetSpacePersistentInfo_Call {
|
||||
return &MockSpaceView_SetSpacePersistentInfo_Call{Call: _e.mock.On("SetSpacePersistentInfo", info)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpacePersistentInfo_Call) Run(run func(info spaceinfo.SpacePersistentInfo)) *MockSpaceView_SetSpacePersistentInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(spaceinfo.SpacePersistentInfo))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpacePersistentInfo_Call) Return(_a0 error) *MockSpaceView_SetSpacePersistentInfo_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpacePersistentInfo_Call) RunAndReturn(run func(spaceinfo.SpacePersistentInfo) error) *MockSpaceView_SetSpacePersistentInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Unlock provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) Unlock() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// MockSpaceView_Unlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unlock'
|
||||
type MockSpaceView_Unlock_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Unlock is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) Unlock() *MockSpaceView_Unlock_Call {
|
||||
return &MockSpaceView_Unlock_Call{Call: _e.mock.On("Unlock")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Unlock_Call) Run(run func()) *MockSpaceView_Unlock_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Unlock_Call) Return() *MockSpaceView_Unlock_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Unlock_Call) RunAndReturn(run func()) *MockSpaceView_Unlock_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockSpaceView creates a new instance of MockSpaceView. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockSpaceView(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockSpaceView {
|
||||
mock := &MockSpaceView{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
|
@ -20,11 +20,9 @@ func (s *service) Join(ctx context.Context, id, aclHeadId string) error {
|
|||
ctrl := s.spaceControllers[id]
|
||||
s.mu.Unlock()
|
||||
if ctrl.Mode() != mode.ModeJoining {
|
||||
return ctrl.SetPersistentInfo(ctx, spaceinfo.SpacePersistentInfo{
|
||||
SpaceID: id,
|
||||
AccountStatus: spaceinfo.AccountStatusJoining,
|
||||
AclHeadId: aclHeadId,
|
||||
})
|
||||
info := spaceinfo.NewSpacePersistentInfo(id)
|
||||
info.SetAclHeadId(aclHeadId).SetAccountStatus(spaceinfo.AccountStatusJoining)
|
||||
return ctrl.SetPersistentInfo(ctx, info)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -52,8 +50,7 @@ func (s *service) Join(ctx context.Context, id, aclHeadId string) error {
|
|||
}
|
||||
|
||||
func (s *service) CancelLeave(ctx context.Context, id string) error {
|
||||
return s.techSpace.SetPersistentInfo(ctx, spaceinfo.SpacePersistentInfo{
|
||||
SpaceID: id,
|
||||
AccountStatus: spaceinfo.AccountStatusActive,
|
||||
})
|
||||
info := spaceinfo.NewSpacePersistentInfo(id)
|
||||
info.SetAccountStatus(spaceinfo.AccountStatusActive)
|
||||
return s.techSpace.SetPersistentInfo(ctx, info)
|
||||
}
|
||||
|
|
|
@ -29,10 +29,10 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space/internal/spacecontroller"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spacecontroller/mock_spacecontroller"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/mode"
|
||||
"github.com/anyproto/anytype-heart/space/internal/techspace/mock_techspace"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore/mock_spacecore"
|
||||
"github.com/anyproto/anytype-heart/space/spacefactory/mock_spacefactory"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace/mock_techspace"
|
||||
"github.com/anyproto/anytype-heart/tests/testutil"
|
||||
"github.com/anyproto/anytype-heart/util/pbtypes"
|
||||
)
|
||||
|
|
|
@ -15,10 +15,10 @@ import (
|
|||
"github.com/anyproto/anytype-heart/space/internal/personalspace"
|
||||
"github.com/anyproto/anytype-heart/space/internal/shareablespace"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spacecontroller"
|
||||
"github.com/anyproto/anytype-heart/space/internal/techspace"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore/storage"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
)
|
||||
|
||||
type SpaceFactory interface {
|
||||
|
|
11
space/spaceinfo/participantinfo.go
Normal file
11
space/spaceinfo/participantinfo.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package spaceinfo
|
||||
|
||||
import "github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
|
||||
type ParticipantAclInfo struct {
|
||||
Id string
|
||||
SpaceId string
|
||||
Identity string
|
||||
Permissions model.ParticipantPermissions
|
||||
Status model.ParticipantStatus
|
||||
}
|
|
@ -115,3 +115,8 @@ const (
|
|||
AccessTypePersonal = AccessType(model.SpaceAccessType_Personal)
|
||||
AccessTypeShared = AccessType(model.SpaceAccessType_Shared)
|
||||
)
|
||||
|
||||
type SpaceDescription struct {
|
||||
Name string
|
||||
IconImage string
|
||||
}
|
||||
|
|
623
space/techspace/mock_techspace/mock_SpaceView.go
Normal file
623
space/techspace/mock_techspace/mock_SpaceView.go
Normal file
|
@ -0,0 +1,623 @@
|
|||
// Code generated by mockery. DO NOT EDIT.
|
||||
|
||||
package mock_techspace
|
||||
|
||||
import (
|
||||
spaceinfo "github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
types "github.com/gogo/protobuf/types"
|
||||
)
|
||||
|
||||
// MockSpaceView is an autogenerated mock type for the SpaceView type
|
||||
type MockSpaceView struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type MockSpaceView_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *MockSpaceView) EXPECT() *MockSpaceView_Expecter {
|
||||
return &MockSpaceView_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// GetExistingInviteInfo provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) GetExistingInviteInfo() (string, string) {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetExistingInviteInfo")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
var r1 string
|
||||
if rf, ok := ret.Get(0).(func() (string, string)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func() string); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Get(1).(string)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockSpaceView_GetExistingInviteInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExistingInviteInfo'
|
||||
type MockSpaceView_GetExistingInviteInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetExistingInviteInfo is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) GetExistingInviteInfo() *MockSpaceView_GetExistingInviteInfo_Call {
|
||||
return &MockSpaceView_GetExistingInviteInfo_Call{Call: _e.mock.On("GetExistingInviteInfo")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetExistingInviteInfo_Call) Run(run func()) *MockSpaceView_GetExistingInviteInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetExistingInviteInfo_Call) Return(fileCid string, fileKey string) *MockSpaceView_GetExistingInviteInfo_Call {
|
||||
_c.Call.Return(fileCid, fileKey)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetExistingInviteInfo_Call) RunAndReturn(run func() (string, string)) *MockSpaceView_GetExistingInviteInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetLocalInfo provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) GetLocalInfo() spaceinfo.SpaceLocalInfo {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetLocalInfo")
|
||||
}
|
||||
|
||||
var r0 spaceinfo.SpaceLocalInfo
|
||||
if rf, ok := ret.Get(0).(func() spaceinfo.SpaceLocalInfo); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(spaceinfo.SpaceLocalInfo)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_GetLocalInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLocalInfo'
|
||||
type MockSpaceView_GetLocalInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetLocalInfo is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) GetLocalInfo() *MockSpaceView_GetLocalInfo_Call {
|
||||
return &MockSpaceView_GetLocalInfo_Call{Call: _e.mock.On("GetLocalInfo")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetLocalInfo_Call) Run(run func()) *MockSpaceView_GetLocalInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetLocalInfo_Call) Return(_a0 spaceinfo.SpaceLocalInfo) *MockSpaceView_GetLocalInfo_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetLocalInfo_Call) RunAndReturn(run func() spaceinfo.SpaceLocalInfo) *MockSpaceView_GetLocalInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetPersistentInfo provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) GetPersistentInfo() spaceinfo.SpacePersistentInfo {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetPersistentInfo")
|
||||
}
|
||||
|
||||
var r0 spaceinfo.SpacePersistentInfo
|
||||
if rf, ok := ret.Get(0).(func() spaceinfo.SpacePersistentInfo); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(spaceinfo.SpacePersistentInfo)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_GetPersistentInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPersistentInfo'
|
||||
type MockSpaceView_GetPersistentInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetPersistentInfo is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) GetPersistentInfo() *MockSpaceView_GetPersistentInfo_Call {
|
||||
return &MockSpaceView_GetPersistentInfo_Call{Call: _e.mock.On("GetPersistentInfo")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetPersistentInfo_Call) Run(run func()) *MockSpaceView_GetPersistentInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetPersistentInfo_Call) Return(_a0 spaceinfo.SpacePersistentInfo) *MockSpaceView_GetPersistentInfo_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetPersistentInfo_Call) RunAndReturn(run func() spaceinfo.SpacePersistentInfo) *MockSpaceView_GetPersistentInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetSpaceDescription provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) GetSpaceDescription() spaceinfo.SpaceDescription {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetSpaceDescription")
|
||||
}
|
||||
|
||||
var r0 spaceinfo.SpaceDescription
|
||||
if rf, ok := ret.Get(0).(func() spaceinfo.SpaceDescription); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(spaceinfo.SpaceDescription)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_GetSpaceDescription_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSpaceDescription'
|
||||
type MockSpaceView_GetSpaceDescription_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetSpaceDescription is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) GetSpaceDescription() *MockSpaceView_GetSpaceDescription_Call {
|
||||
return &MockSpaceView_GetSpaceDescription_Call{Call: _e.mock.On("GetSpaceDescription")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetSpaceDescription_Call) Run(run func()) *MockSpaceView_GetSpaceDescription_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetSpaceDescription_Call) Return(data spaceinfo.SpaceDescription) *MockSpaceView_GetSpaceDescription_Call {
|
||||
_c.Call.Return(data)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_GetSpaceDescription_Call) RunAndReturn(run func() spaceinfo.SpaceDescription) *MockSpaceView_GetSpaceDescription_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Lock provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) Lock() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// MockSpaceView_Lock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Lock'
|
||||
type MockSpaceView_Lock_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Lock is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) Lock() *MockSpaceView_Lock_Call {
|
||||
return &MockSpaceView_Lock_Call{Call: _e.mock.On("Lock")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Lock_Call) Run(run func()) *MockSpaceView_Lock_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Lock_Call) Return() *MockSpaceView_Lock_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Lock_Call) RunAndReturn(run func()) *MockSpaceView_Lock_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// RemoveExistingInviteInfo provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) RemoveExistingInviteInfo() (string, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for RemoveExistingInviteInfo")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func() (string, error)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockSpaceView_RemoveExistingInviteInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveExistingInviteInfo'
|
||||
type MockSpaceView_RemoveExistingInviteInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// RemoveExistingInviteInfo is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) RemoveExistingInviteInfo() *MockSpaceView_RemoveExistingInviteInfo_Call {
|
||||
return &MockSpaceView_RemoveExistingInviteInfo_Call{Call: _e.mock.On("RemoveExistingInviteInfo")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_RemoveExistingInviteInfo_Call) Run(run func()) *MockSpaceView_RemoveExistingInviteInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_RemoveExistingInviteInfo_Call) Return(fileCid string, err error) *MockSpaceView_RemoveExistingInviteInfo_Call {
|
||||
_c.Call.Return(fileCid, err)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_RemoveExistingInviteInfo_Call) RunAndReturn(run func() (string, error)) *MockSpaceView_RemoveExistingInviteInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetAccessType provides a mock function with given fields: acc
|
||||
func (_m *MockSpaceView) SetAccessType(acc spaceinfo.AccessType) error {
|
||||
ret := _m.Called(acc)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetAccessType")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(spaceinfo.AccessType) error); ok {
|
||||
r0 = rf(acc)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetAccessType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAccessType'
|
||||
type MockSpaceView_SetAccessType_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetAccessType is a helper method to define mock.On call
|
||||
// - acc spaceinfo.AccessType
|
||||
func (_e *MockSpaceView_Expecter) SetAccessType(acc interface{}) *MockSpaceView_SetAccessType_Call {
|
||||
return &MockSpaceView_SetAccessType_Call{Call: _e.mock.On("SetAccessType", acc)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetAccessType_Call) Run(run func(acc spaceinfo.AccessType)) *MockSpaceView_SetAccessType_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(spaceinfo.AccessType))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetAccessType_Call) Return(_a0 error) *MockSpaceView_SetAccessType_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetAccessType_Call) RunAndReturn(run func(spaceinfo.AccessType) error) *MockSpaceView_SetAccessType_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetAclIsEmpty provides a mock function with given fields: isEmpty
|
||||
func (_m *MockSpaceView) SetAclIsEmpty(isEmpty bool) error {
|
||||
ret := _m.Called(isEmpty)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetAclIsEmpty")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(bool) error); ok {
|
||||
r0 = rf(isEmpty)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetAclIsEmpty_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAclIsEmpty'
|
||||
type MockSpaceView_SetAclIsEmpty_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetAclIsEmpty is a helper method to define mock.On call
|
||||
// - isEmpty bool
|
||||
func (_e *MockSpaceView_Expecter) SetAclIsEmpty(isEmpty interface{}) *MockSpaceView_SetAclIsEmpty_Call {
|
||||
return &MockSpaceView_SetAclIsEmpty_Call{Call: _e.mock.On("SetAclIsEmpty", isEmpty)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetAclIsEmpty_Call) Run(run func(isEmpty bool)) *MockSpaceView_SetAclIsEmpty_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(bool))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetAclIsEmpty_Call) Return(err error) *MockSpaceView_SetAclIsEmpty_Call {
|
||||
_c.Call.Return(err)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetAclIsEmpty_Call) RunAndReturn(run func(bool) error) *MockSpaceView_SetAclIsEmpty_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetInviteFileInfo provides a mock function with given fields: fileCid, fileKey
|
||||
func (_m *MockSpaceView) SetInviteFileInfo(fileCid string, fileKey string) error {
|
||||
ret := _m.Called(fileCid, fileKey)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetInviteFileInfo")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(fileCid, fileKey)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetInviteFileInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetInviteFileInfo'
|
||||
type MockSpaceView_SetInviteFileInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetInviteFileInfo is a helper method to define mock.On call
|
||||
// - fileCid string
|
||||
// - fileKey string
|
||||
func (_e *MockSpaceView_Expecter) SetInviteFileInfo(fileCid interface{}, fileKey interface{}) *MockSpaceView_SetInviteFileInfo_Call {
|
||||
return &MockSpaceView_SetInviteFileInfo_Call{Call: _e.mock.On("SetInviteFileInfo", fileCid, fileKey)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetInviteFileInfo_Call) Run(run func(fileCid string, fileKey string)) *MockSpaceView_SetInviteFileInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(string), args[1].(string))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetInviteFileInfo_Call) Return(err error) *MockSpaceView_SetInviteFileInfo_Call {
|
||||
_c.Call.Return(err)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetInviteFileInfo_Call) RunAndReturn(run func(string, string) error) *MockSpaceView_SetInviteFileInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetSpaceData provides a mock function with given fields: details
|
||||
func (_m *MockSpaceView) SetSpaceData(details *types.Struct) error {
|
||||
ret := _m.Called(details)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetSpaceData")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(*types.Struct) error); ok {
|
||||
r0 = rf(details)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetSpaceData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetSpaceData'
|
||||
type MockSpaceView_SetSpaceData_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetSpaceData is a helper method to define mock.On call
|
||||
// - details *types.Struct
|
||||
func (_e *MockSpaceView_Expecter) SetSpaceData(details interface{}) *MockSpaceView_SetSpaceData_Call {
|
||||
return &MockSpaceView_SetSpaceData_Call{Call: _e.mock.On("SetSpaceData", details)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceData_Call) Run(run func(details *types.Struct)) *MockSpaceView_SetSpaceData_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(*types.Struct))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceData_Call) Return(_a0 error) *MockSpaceView_SetSpaceData_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceData_Call) RunAndReturn(run func(*types.Struct) error) *MockSpaceView_SetSpaceData_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetSpaceLocalInfo provides a mock function with given fields: info
|
||||
func (_m *MockSpaceView) SetSpaceLocalInfo(info spaceinfo.SpaceLocalInfo) error {
|
||||
ret := _m.Called(info)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetSpaceLocalInfo")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(spaceinfo.SpaceLocalInfo) error); ok {
|
||||
r0 = rf(info)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetSpaceLocalInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetSpaceLocalInfo'
|
||||
type MockSpaceView_SetSpaceLocalInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetSpaceLocalInfo is a helper method to define mock.On call
|
||||
// - info spaceinfo.SpaceLocalInfo
|
||||
func (_e *MockSpaceView_Expecter) SetSpaceLocalInfo(info interface{}) *MockSpaceView_SetSpaceLocalInfo_Call {
|
||||
return &MockSpaceView_SetSpaceLocalInfo_Call{Call: _e.mock.On("SetSpaceLocalInfo", info)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceLocalInfo_Call) Run(run func(info spaceinfo.SpaceLocalInfo)) *MockSpaceView_SetSpaceLocalInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(spaceinfo.SpaceLocalInfo))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceLocalInfo_Call) Return(_a0 error) *MockSpaceView_SetSpaceLocalInfo_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpaceLocalInfo_Call) RunAndReturn(run func(spaceinfo.SpaceLocalInfo) error) *MockSpaceView_SetSpaceLocalInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetSpacePersistentInfo provides a mock function with given fields: info
|
||||
func (_m *MockSpaceView) SetSpacePersistentInfo(info spaceinfo.SpacePersistentInfo) error {
|
||||
ret := _m.Called(info)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SetSpacePersistentInfo")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(spaceinfo.SpacePersistentInfo) error); ok {
|
||||
r0 = rf(info)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceView_SetSpacePersistentInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetSpacePersistentInfo'
|
||||
type MockSpaceView_SetSpacePersistentInfo_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// SetSpacePersistentInfo is a helper method to define mock.On call
|
||||
// - info spaceinfo.SpacePersistentInfo
|
||||
func (_e *MockSpaceView_Expecter) SetSpacePersistentInfo(info interface{}) *MockSpaceView_SetSpacePersistentInfo_Call {
|
||||
return &MockSpaceView_SetSpacePersistentInfo_Call{Call: _e.mock.On("SetSpacePersistentInfo", info)}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpacePersistentInfo_Call) Run(run func(info spaceinfo.SpacePersistentInfo)) *MockSpaceView_SetSpacePersistentInfo_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(spaceinfo.SpacePersistentInfo))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpacePersistentInfo_Call) Return(_a0 error) *MockSpaceView_SetSpacePersistentInfo_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_SetSpacePersistentInfo_Call) RunAndReturn(run func(spaceinfo.SpacePersistentInfo) error) *MockSpaceView_SetSpacePersistentInfo_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Unlock provides a mock function with given fields:
|
||||
func (_m *MockSpaceView) Unlock() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// MockSpaceView_Unlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unlock'
|
||||
type MockSpaceView_Unlock_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Unlock is a helper method to define mock.On call
|
||||
func (_e *MockSpaceView_Expecter) Unlock() *MockSpaceView_Unlock_Call {
|
||||
return &MockSpaceView_Unlock_Call{Call: _e.mock.On("Unlock")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Unlock_Call) Run(run func()) *MockSpaceView_Unlock_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Unlock_Call) Return() *MockSpaceView_Unlock_Call {
|
||||
_c.Call.Return()
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceView_Unlock_Call) RunAndReturn(run func()) *MockSpaceView_Unlock_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewMockSpaceView creates a new instance of MockSpaceView. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockSpaceView(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockSpaceView {
|
||||
mock := &MockSpaceView{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
|
@ -14,6 +14,8 @@ import (
|
|||
|
||||
spaceinfo "github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
|
||||
techspace "github.com/anyproto/anytype-heart/space/techspace"
|
||||
|
||||
types "github.com/gogo/protobuf/types"
|
||||
)
|
||||
|
||||
|
@ -76,6 +78,113 @@ func (_c *MockTechSpace_Close_Call) RunAndReturn(run func(context.Context) error
|
|||
return _c
|
||||
}
|
||||
|
||||
// DoSpaceView provides a mock function with given fields: ctx, spaceID, apply
|
||||
func (_m *MockTechSpace) DoSpaceView(ctx context.Context, spaceID string, apply func(techspace.SpaceView) error) error {
|
||||
ret := _m.Called(ctx, spaceID, apply)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DoSpaceView")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, func(techspace.SpaceView) error) error); ok {
|
||||
r0 = rf(ctx, spaceID, apply)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockTechSpace_DoSpaceView_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DoSpaceView'
|
||||
type MockTechSpace_DoSpaceView_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// DoSpaceView is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - spaceID string
|
||||
// - apply func(techspace.SpaceView) error
|
||||
func (_e *MockTechSpace_Expecter) DoSpaceView(ctx interface{}, spaceID interface{}, apply interface{}) *MockTechSpace_DoSpaceView_Call {
|
||||
return &MockTechSpace_DoSpaceView_Call{Call: _e.mock.On("DoSpaceView", ctx, spaceID, apply)}
|
||||
}
|
||||
|
||||
func (_c *MockTechSpace_DoSpaceView_Call) Run(run func(ctx context.Context, spaceID string, apply func(techspace.SpaceView) error)) *MockTechSpace_DoSpaceView_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string), args[2].(func(techspace.SpaceView) error))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockTechSpace_DoSpaceView_Call) Return(err error) *MockTechSpace_DoSpaceView_Call {
|
||||
_c.Call.Return(err)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockTechSpace_DoSpaceView_Call) RunAndReturn(run func(context.Context, string, func(techspace.SpaceView) error) error) *MockTechSpace_DoSpaceView_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// GetSpaceView provides a mock function with given fields: ctx, spaceId
|
||||
func (_m *MockTechSpace) GetSpaceView(ctx context.Context, spaceId string) (techspace.SpaceView, error) {
|
||||
ret := _m.Called(ctx, spaceId)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetSpaceView")
|
||||
}
|
||||
|
||||
var r0 techspace.SpaceView
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (techspace.SpaceView, error)); ok {
|
||||
return rf(ctx, spaceId)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) techspace.SpaceView); ok {
|
||||
r0 = rf(ctx, spaceId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(techspace.SpaceView)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, spaceId)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockTechSpace_GetSpaceView_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSpaceView'
|
||||
type MockTechSpace_GetSpaceView_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// GetSpaceView is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - spaceId string
|
||||
func (_e *MockTechSpace_Expecter) GetSpaceView(ctx interface{}, spaceId interface{}) *MockTechSpace_GetSpaceView_Call {
|
||||
return &MockTechSpace_GetSpaceView_Call{Call: _e.mock.On("GetSpaceView", ctx, spaceId)}
|
||||
}
|
||||
|
||||
func (_c *MockTechSpace_GetSpaceView_Call) Run(run func(ctx context.Context, spaceId string)) *MockTechSpace_GetSpaceView_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(string))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockTechSpace_GetSpaceView_Call) Return(_a0 techspace.SpaceView, _a1 error) *MockTechSpace_GetSpaceView_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockTechSpace_GetSpaceView_Call) RunAndReturn(run func(context.Context, string) (techspace.SpaceView, error)) *MockTechSpace_GetSpaceView_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Init provides a mock function with given fields: a
|
||||
func (_m *MockTechSpace) Init(a *app.App) error {
|
||||
ret := _m.Called(a)
|
|
@ -40,6 +40,7 @@ type TechSpace interface {
|
|||
Close(ctx context.Context) (err error)
|
||||
|
||||
TechSpaceId() string
|
||||
DoSpaceView(ctx context.Context, spaceID string, apply func(spaceView SpaceView) error) (err error)
|
||||
SpaceViewCreate(ctx context.Context, spaceId string, force bool, info spaceinfo.SpacePersistentInfo) (err error)
|
||||
GetSpaceView(ctx context.Context, spaceId string) (SpaceView, error)
|
||||
SpaceViewExists(ctx context.Context, spaceId string) (exists bool, err error)
|
||||
|
@ -56,11 +57,13 @@ type SpaceView interface {
|
|||
GetLocalInfo() spaceinfo.SpaceLocalInfo
|
||||
SetSpaceData(details *types.Struct) error
|
||||
SetSpaceLocalInfo(info spaceinfo.SpaceLocalInfo) error
|
||||
SetInviteFileInfo(fileCid string, fileKey string) (err error)
|
||||
SetAccessType(acc spaceinfo.AccessType) error
|
||||
SetAclIsEmpty(isEmpty bool) (err error)
|
||||
SetSpacePersistentInfo(info spaceinfo.SpacePersistentInfo) error
|
||||
RemoveExistingInvite() (cid string, err error)
|
||||
ExistingFileInfo() (cid, key string, err error)
|
||||
RemoveExistingInviteInfo() (fileCid string, err error)
|
||||
GetSpaceDescription() (data spaceinfo.SpaceDescription)
|
||||
GetExistingInviteInfo() (fileCid string, fileKey string)
|
||||
}
|
||||
|
||||
func New() TechSpace {
|
||||
|
@ -123,19 +126,19 @@ func (s *techSpace) TechSpaceId() string {
|
|||
}
|
||||
|
||||
func (s *techSpace) SetLocalInfo(ctx context.Context, info spaceinfo.SpaceLocalInfo) (err error) {
|
||||
return s.doSpaceView(ctx, info.SpaceId, func(spaceView SpaceView) error {
|
||||
return s.DoSpaceView(ctx, info.SpaceId, func(spaceView SpaceView) error {
|
||||
return spaceView.SetSpaceLocalInfo(info)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *techSpace) SetAccessType(ctx context.Context, spaceId string, acc spaceinfo.AccessType) (err error) {
|
||||
return s.doSpaceView(ctx, spaceId, func(spaceView SpaceView) error {
|
||||
return s.DoSpaceView(ctx, spaceId, func(spaceView SpaceView) error {
|
||||
return spaceView.SetAccessType(acc)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *techSpace) SetPersistentInfo(ctx context.Context, info spaceinfo.SpacePersistentInfo) (err error) {
|
||||
return s.doSpaceView(ctx, info.SpaceID, func(spaceView SpaceView) error {
|
||||
return s.DoSpaceView(ctx, info.SpaceID, func(spaceView SpaceView) error {
|
||||
return spaceView.SetSpacePersistentInfo(info)
|
||||
})
|
||||
}
|
||||
|
@ -184,7 +187,7 @@ func (s *techSpace) GetSpaceView(ctx context.Context, spaceId string) (SpaceView
|
|||
}
|
||||
|
||||
func (s *techSpace) SpaceViewSetData(ctx context.Context, spaceId string, details *types.Struct) (err error) {
|
||||
return s.doSpaceView(ctx, spaceId, func(spaceView SpaceView) error {
|
||||
return s.DoSpaceView(ctx, spaceId, func(spaceView SpaceView) error {
|
||||
return spaceView.SetSpaceData(details)
|
||||
})
|
||||
}
|
||||
|
@ -227,7 +230,7 @@ func (s *techSpace) deriveSpaceViewID(ctx context.Context, spaceID string) (stri
|
|||
return payload.RootRawChange.Id, nil
|
||||
}
|
||||
|
||||
func (s *techSpace) doSpaceView(ctx context.Context, spaceID string, apply func(spaceView SpaceView) error) (err error) {
|
||||
func (s *techSpace) DoSpaceView(ctx context.Context, spaceID string, apply func(spaceView SpaceView) error) (err error) {
|
||||
viewId, err := s.getViewIdLocked(ctx, spaceID)
|
||||
if err != nil {
|
||||
return
|
22
util/encode/base58.go
Normal file
22
util/encode/base58.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package encode
|
||||
|
||||
import (
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
"github.com/mr-tron/base58/base58"
|
||||
)
|
||||
|
||||
func EncodeKeyToBase58(key crypto.SymKey) (string, error) {
|
||||
raw, err := key.Raw()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base58.Encode(raw), nil
|
||||
}
|
||||
|
||||
func DecodeKeyFromBase58(rawString string) (crypto.SymKey, error) {
|
||||
raw, err := base58.Decode(rawString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return crypto.UnmarshallAESKey(raw)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue