diff options
| author | 2023-09-12 14:00:35 +0100 | |
|---|---|---|
| committer | 2023-09-12 14:00:35 +0100 | |
| commit | 7293d6029b43db693fd170c0c087394339da0677 (patch) | |
| tree | 09063243faf1b178fde35973486e311f66b1ca33 /internal/processing/account/follow.go | |
| parent | [feature] Allow admins to expire remote public keys; refetch expired keys on ... (diff) | |
| download | gotosocial-7293d6029b43db693fd170c0c087394339da0677.tar.xz | |
[feature] add paging to account follows, followers and follow requests endpoints (#2186)
Diffstat (limited to 'internal/processing/account/follow.go')
| -rw-r--r-- | internal/processing/account/follow.go | 63 |
1 files changed, 23 insertions, 40 deletions
diff --git a/internal/processing/account/follow.go b/internal/processing/account/follow.go index 1aed92e75..8006f8d79 100644 --- a/internal/processing/account/follow.go +++ b/internal/processing/account/follow.go @@ -20,7 +20,6 @@ package account import ( "context" "errors" - "fmt" "github.com/superseriousbusiness/gotosocial/internal/ap" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" @@ -35,7 +34,7 @@ import ( // FollowCreate handles a follow request to an account, either remote or local. func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmodel.Account, form *apimodel.AccountFollowRequest) (*apimodel.Relationship, gtserror.WithCode) { - targetAccount, errWithCode := p.getFollowTarget(ctx, requestingAccount.ID, form.ID) + targetAccount, errWithCode := p.getFollowTarget(ctx, requestingAccount, form.ID) if errWithCode != nil { return nil, errWithCode } @@ -46,7 +45,7 @@ func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode requestingAccount.ID, targetAccount.ID, ); err != nil && !errors.Is(err, db.ErrNoEntries) { - err = fmt.Errorf("FollowCreate: db error checking existing follow: %w", err) + err = gtserror.Newf("db error checking existing follow: %w", err) return nil, gtserror.NewErrorInternalError(err) } else if follow != nil { // Already follows, update if necessary + return relationship. @@ -66,7 +65,7 @@ func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode requestingAccount.ID, targetAccount.ID, ); err != nil && !errors.Is(err, db.ErrNoEntries) { - err = fmt.Errorf("FollowCreate: db error checking existing follow request: %w", err) + err = gtserror.Newf("db error checking existing follow request: %w", err) return nil, gtserror.NewErrorInternalError(err) } else if followRequest != nil { // Already requested, update if necessary + return relationship. @@ -100,7 +99,7 @@ func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode } if err := p.state.DB.PutFollowRequest(ctx, fr); err != nil { - err = fmt.Errorf("FollowCreate: error creating follow request in db: %s", err) + err = gtserror.Newf("error creating follow request in db: %s", err) return nil, gtserror.NewErrorInternalError(err) } @@ -112,7 +111,7 @@ func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode // Because we know the requestingAccount is also // local, we don't need to federate the accept out. if _, err := p.state.DB.AcceptFollowRequest(ctx, requestingAccount.ID, form.ID); err != nil { - err = fmt.Errorf("FollowCreate: error accepting follow request for local unlocked account: %w", err) + err = gtserror.Newf("error accepting follow request for local unlocked account: %w", err) return nil, gtserror.NewErrorInternalError(err) } } else if targetAccount.IsRemote() { @@ -132,7 +131,7 @@ func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode // FollowRemove handles the removal of a follow/follow request to an account, either remote or local. func (p *Processor) FollowRemove(ctx context.Context, requestingAccount *gtsmodel.Account, targetAccountID string) (*apimodel.Relationship, gtserror.WithCode) { - targetAccount, errWithCode := p.getFollowTarget(ctx, requestingAccount.ID, targetAccountID) + targetAccount, errWithCode := p.getFollowTarget(ctx, requestingAccount, targetAccountID) if errWithCode != nil { return nil, errWithCode } @@ -140,7 +139,7 @@ func (p *Processor) FollowRemove(ctx context.Context, requestingAccount *gtsmode // Unfollow and deal with side effects. msgs, err := p.unfollow(ctx, requestingAccount, targetAccount) if err != nil { - return nil, gtserror.NewErrorNotFound(fmt.Errorf("FollowRemove: account %s not found in the db: %s", targetAccountID, err)) + return nil, gtserror.NewErrorNotFound(gtserror.Newf("account %s not found in the db: %s", targetAccountID, err)) } // Batch queue accreted client api messages. @@ -166,7 +165,6 @@ func (p *Processor) updateFollow( currentNotify *bool, update func(...string) error, ) (*apimodel.Relationship, gtserror.WithCode) { - if form.Reblogs == nil && form.Notify == nil { // There's nothing to update. return p.RelationshipGet(ctx, requestingAccount, form.ID) @@ -192,7 +190,7 @@ func (p *Processor) updateFollow( } if err := update(columns...); err != nil { - err = fmt.Errorf("updateFollow: error updating existing follow (request): %w", err) + err = gtserror.Newf("error updating existing follow (request): %w", err) return nil, gtserror.NewErrorInternalError(err) } @@ -201,38 +199,23 @@ func (p *Processor) updateFollow( // getFollowTarget is a convenience function which: // - Checks if account is trying to follow/unfollow itself. -// - Returns not found if there's a block in place between accounts. +// - Returns not found if target should not be visible to requester. // - Returns target account according to its id. -func (p *Processor) getFollowTarget(ctx context.Context, requestingAccountID string, targetAccountID string) (*gtsmodel.Account, gtserror.WithCode) { +func (p *Processor) getFollowTarget(ctx context.Context, requester *gtsmodel.Account, targetID string) (*gtsmodel.Account, gtserror.WithCode) { + // Check for requester. + if requester == nil { + err := errors.New("no authorized user") + return nil, gtserror.NewErrorUnauthorized(err) + } + // Account can't follow or unfollow itself. - if requestingAccountID == targetAccountID { + if requester.ID == targetID { err := errors.New("account can't follow or unfollow itself") return nil, gtserror.NewErrorNotAcceptable(err) } - // Do nothing if a block exists in either direction between accounts. - if blocked, err := p.state.DB.IsEitherBlocked(ctx, requestingAccountID, targetAccountID); err != nil { - err = fmt.Errorf("db error checking block between accounts: %w", err) - return nil, gtserror.NewErrorInternalError(err) - } else if blocked { - err = errors.New("block exists between accounts") - return nil, gtserror.NewErrorNotFound(err) - } - - // Ensure target account retrievable. - targetAccount, err := p.state.DB.GetAccountByID(ctx, targetAccountID) - if err != nil { - if !errors.Is(err, db.ErrNoEntries) { - // Real db error. - err = fmt.Errorf("db error looking for target account %s: %w", targetAccountID, err) - return nil, gtserror.NewErrorInternalError(err) - } - // Account not found. - err = fmt.Errorf("target account %s not found in the db", targetAccountID) - return nil, gtserror.NewErrorNotFound(err, err.Error()) - } - - return targetAccount, nil + // Fetch the target account for requesting user account. + return p.c.GetVisibleTargetAccount(ctx, requester, targetID) } // unfollow is a convenience function for having requesting account @@ -248,7 +231,7 @@ func (p *Processor) unfollow(ctx context.Context, requestingAccount *gtsmodel.Ac // Get follow from requesting account to target account. follow, err := p.state.DB.GetFollow(ctx, requestingAccount.ID, targetAccount.ID) if err != nil && !errors.Is(err, db.ErrNoEntries) { - err = fmt.Errorf("unfollow: error getting follow from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) + err = gtserror.Newf("error getting follow from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) return nil, err } @@ -257,7 +240,7 @@ func (p *Processor) unfollow(ctx context.Context, requestingAccount *gtsmodel.Ac err = p.state.DB.DeleteFollowByID(ctx, follow.ID) if err != nil { if !errors.Is(err, db.ErrNoEntries) { - err = fmt.Errorf("unfollow: error deleting request from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) + err = gtserror.Newf("error deleting request from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) return nil, err } @@ -284,7 +267,7 @@ func (p *Processor) unfollow(ctx context.Context, requestingAccount *gtsmodel.Ac // Get follow request from requesting account to target account. followReq, err := p.state.DB.GetFollowRequest(ctx, requestingAccount.ID, targetAccount.ID) if err != nil && !errors.Is(err, db.ErrNoEntries) { - err = fmt.Errorf("unfollow: error getting follow request from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) + err = gtserror.Newf("error getting follow request from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) return nil, err } @@ -293,7 +276,7 @@ func (p *Processor) unfollow(ctx context.Context, requestingAccount *gtsmodel.Ac err = p.state.DB.DeleteFollowRequestByID(ctx, followReq.ID) if err != nil { if !errors.Is(err, db.ErrNoEntries) { - err = fmt.Errorf("unfollow: error deleting follow request from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) + err = gtserror.Newf("error deleting follow request from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) return nil, err } |
