diff options
author | 2023-03-28 14:03:14 +0100 | |
---|---|---|
committer | 2023-03-28 14:03:14 +0100 | |
commit | de6e3e5f2a8ea639d76e310a11cb9bc093fef3a9 (patch) | |
tree | e2b7044e22c943425a4d351a02f862fbde783657 /internal/processing/account | |
parent | [feature] Add list command to admin account (#1648) (diff) | |
download | gotosocial-de6e3e5f2a8ea639d76e310a11cb9bc093fef3a9.tar.xz |
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
Diffstat (limited to 'internal/processing/account')
-rw-r--r-- | internal/processing/account/account.go | 5 | ||||
-rw-r--r-- | internal/processing/account/account_test.go | 5 | ||||
-rw-r--r-- | internal/processing/account/bookmarks.go | 2 | ||||
-rw-r--r-- | internal/processing/account/delete.go | 53 | ||||
-rw-r--r-- | internal/processing/account/follow.go | 64 | ||||
-rw-r--r-- | internal/processing/account/get.go | 2 | ||||
-rw-r--r-- | internal/processing/account/relationships.go | 39 | ||||
-rw-r--r-- | internal/processing/account/statuses.go | 18 |
8 files changed, 116 insertions, 72 deletions
diff --git a/internal/processing/account/account.go b/internal/processing/account/account.go index ef6bc0477..328b682ac 100644 --- a/internal/processing/account/account.go +++ b/internal/processing/account/account.go @@ -36,7 +36,7 @@ type Processor struct { tc typeutils.TypeConverter mediaManager media.Manager oauthServer oauth.Server - filter visibility.Filter + filter *visibility.Filter formatter text.Formatter federator federation.Federator parseMention gtsmodel.ParseMentionFunc @@ -49,6 +49,7 @@ func New( mediaManager media.Manager, oauthServer oauth.Server, federator federation.Federator, + filter *visibility.Filter, parseMention gtsmodel.ParseMentionFunc, ) Processor { return Processor{ @@ -56,7 +57,7 @@ func New( tc: tc, mediaManager: mediaManager, oauthServer: oauthServer, - filter: visibility.NewFilter(state.DB), + filter: filter, formatter: text.NewFormatter(state.DB), federator: federator, parseMention: parseMention, diff --git a/internal/processing/account/account_test.go b/internal/processing/account/account_test.go index 0898e707b..eed6ad7e3 100644 --- a/internal/processing/account/account_test.go +++ b/internal/processing/account/account_test.go @@ -34,6 +34,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/storage" "github.com/superseriousbusiness/gotosocial/internal/transport" "github.com/superseriousbusiness/gotosocial/internal/typeutils" + "github.com/superseriousbusiness/gotosocial/internal/visibility" "github.com/superseriousbusiness/gotosocial/testrig" ) @@ -101,7 +102,9 @@ func (suite *AccountStandardTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, suite.transportController, suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../web/template/", suite.sentEmails) - suite.accountProcessor = account.New(&suite.state, suite.tc, suite.mediaManager, suite.oauthServer, suite.federator, processing.GetParseMentionFunc(suite.db, suite.federator)) + + filter := visibility.NewFilter(&suite.state) + suite.accountProcessor = account.New(&suite.state, suite.tc, suite.mediaManager, suite.oauthServer, suite.federator, filter, processing.GetParseMentionFunc(suite.db, suite.federator)) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../testrig/media") } diff --git a/internal/processing/account/bookmarks.go b/internal/processing/account/bookmarks.go index 56f0fc9e0..32075f592 100644 --- a/internal/processing/account/bookmarks.go +++ b/internal/processing/account/bookmarks.go @@ -56,7 +56,7 @@ func (p *Processor) BookmarksGet(ctx context.Context, requestingAccount *gtsmode return nil, gtserror.NewErrorInternalError(err) // A real error has occurred. } - visible, err := p.filter.StatusVisible(ctx, status, requestingAccount) + visible, err := p.filter.StatusVisible(ctx, requestingAccount, status) if err != nil { log.Errorf(ctx, "error checking bookmarked status visibility: %s", err) continue diff --git a/internal/processing/account/delete.go b/internal/processing/account/delete.go index 9c59e1b99..f3dfecc7b 100644 --- a/internal/processing/account/delete.go +++ b/internal/processing/account/delete.go @@ -150,25 +150,25 @@ func (p *Processor) deleteUserAndTokensForAccount(ctx context.Context, account * // - Follow requests created by account. func (p *Processor) deleteAccountFollows(ctx context.Context, account *gtsmodel.Account) error { // Delete follows targeting this account. - followedBy, err := p.state.DB.GetFollows(ctx, "", account.ID) + followedBy, err := p.state.DB.GetAccountFollowers(ctx, account.ID) if err != nil && !errors.Is(err, db.ErrNoEntries) { return fmt.Errorf("deleteAccountFollows: db error getting follows targeting account %s: %w", account.ID, err) } for _, follow := range followedBy { - if _, err := p.state.DB.Unfollow(ctx, follow.AccountID, account.ID); err != nil { + if err := p.state.DB.DeleteFollowByID(ctx, follow.ID); err != nil { return fmt.Errorf("deleteAccountFollows: db error unfollowing account followedBy: %w", err) } } // Delete follow requests targeting this account. - followRequestedBy, err := p.state.DB.GetFollowRequests(ctx, "", account.ID) + followRequestedBy, err := p.state.DB.GetAccountFollowRequests(ctx, account.ID) if err != nil && !errors.Is(err, db.ErrNoEntries) { return fmt.Errorf("deleteAccountFollows: db error getting follow requests targeting account %s: %w", account.ID, err) } for _, followRequest := range followRequestedBy { - if _, err := p.state.DB.UnfollowRequest(ctx, followRequest.AccountID, account.ID); err != nil { + if err := p.state.DB.DeleteFollowRequestByID(ctx, followRequest.ID); err != nil { return fmt.Errorf("deleteAccountFollows: db error unfollowing account followRequestedBy: %w", err) } } @@ -183,7 +183,7 @@ func (p *Processor) deleteAccountFollows(ctx context.Context, account *gtsmodel. ) // Delete follows originating from this account. - following, err := p.state.DB.GetFollows(ctx, account.ID, "") + following, err := p.state.DB.GetAccountFollows(ctx, account.ID) if err != nil && !errors.Is(err, db.ErrNoEntries) { return fmt.Errorf("deleteAccountFollows: db error getting follows owned by account %s: %w", account.ID, err) } @@ -191,15 +191,9 @@ func (p *Processor) deleteAccountFollows(ctx context.Context, account *gtsmodel. // For each follow owned by this account, unfollow // and process side effects (noop if remote account). for _, follow := range following { - if uri, err := p.state.DB.Unfollow(ctx, account.ID, follow.TargetAccountID); err != nil { + if err := p.state.DB.DeleteFollowByID(ctx, follow.ID); err != nil { return fmt.Errorf("deleteAccountFollows: db error unfollowing account: %w", err) - } else if uri == "" { - // There was no follow after all. - // Some race condition? Skip. - log.WithContext(ctx).WithField("follow", follow).Warn("Unfollow did not return uri, likely race condition") - continue } - if msg := unfollowSideEffects(ctx, account, follow); msg != nil { // There was a side effect to process. msgs = append(msgs, *msg) @@ -207,7 +201,7 @@ func (p *Processor) deleteAccountFollows(ctx context.Context, account *gtsmodel. } // Delete follow requests originating from this account. - followRequesting, err := p.state.DB.GetFollowRequests(ctx, account.ID, "") + followRequesting, err := p.state.DB.GetAccountFollowRequesting(ctx, account.ID) if err != nil && !errors.Is(err, db.ErrNoEntries) { return fmt.Errorf("deleteAccountFollows: db error getting follow requests owned by account %s: %w", account.ID, err) } @@ -215,23 +209,15 @@ func (p *Processor) deleteAccountFollows(ctx context.Context, account *gtsmodel. // For each follow owned by this account, unfollow // and process side effects (noop if remote account). for _, followRequest := range followRequesting { - uri, err := p.state.DB.UnfollowRequest(ctx, account.ID, followRequest.TargetAccountID) - if err != nil { - return fmt.Errorf("deleteAccountFollows: db error unfollowRequesting account: %w", err) - } - - if uri == "" { - // There was no follow request after all. - // Some race condition? Skip. - log.WithContext(ctx).WithField("followRequest", followRequest).Warn("UnfollowRequest did not return uri, likely race condition") - continue + if err := p.state.DB.DeleteFollowRequestByID(ctx, followRequest.ID); err != nil { + return fmt.Errorf("deleteAccountFollows: db error unfollowingRequesting account: %w", err) } // Dummy out a follow so our side effects func // has something to work with. This follow will // never enter the db, it's just for convenience. follow := >smodel.Follow{ - URI: uri, + URI: followRequest.URI, AccountID: followRequest.AccountID, Account: followRequest.Account, TargetAccountID: followRequest.TargetAccountID, @@ -284,16 +270,9 @@ func (p *Processor) unfollowSideEffectsFunc(deletedAccount *gtsmodel.Account) fu } func (p *Processor) deleteAccountBlocks(ctx context.Context, account *gtsmodel.Account) error { - // Delete blocks created by this account. - if err := p.state.DB.DeleteBlocksByOriginAccountID(ctx, account.ID); err != nil { - return fmt.Errorf("deleteAccountBlocks: db error deleting blocks created by account %s: %w", account.ID, err) + if err := p.state.DB.DeleteAccountBlocks(ctx, account.ID); err != nil { + return fmt.Errorf("deleteAccountBlocks: db error deleting account blocks for %s: %w", account.ID, err) } - - // Delete blocks targeting this account. - if err := p.state.DB.DeleteBlocksByTargetAccountID(ctx, account.ID); err != nil { - return fmt.Errorf("deleteAccountBlocks: db error deleting blocks targeting account %s: %w", account.ID, err) - } - return nil } @@ -386,13 +365,13 @@ statusLoop: } func (p *Processor) deleteAccountNotifications(ctx context.Context, account *gtsmodel.Account) error { - // Delete all notifications targeting given account. - if err := p.state.DB.DeleteNotifications(ctx, account.ID, ""); err != nil && !errors.Is(err, db.ErrNoEntries) { + // Delete all notifications of all types targeting given account. + if err := p.state.DB.DeleteNotifications(ctx, nil, account.ID, ""); err != nil && !errors.Is(err, db.ErrNoEntries) { return err } - // Delete all notifications originating from given account. - if err := p.state.DB.DeleteNotifications(ctx, "", account.ID); err != nil && !errors.Is(err, db.ErrNoEntries) { + // Delete all notifications of all types originating from given account. + if err := p.state.DB.DeleteNotifications(ctx, nil, "", account.ID); err != nil && !errors.Is(err, db.ErrNoEntries) { return err } diff --git a/internal/processing/account/follow.go b/internal/processing/account/follow.go index 8d053e92a..ab8fecd94 100644 --- a/internal/processing/account/follow.go +++ b/internal/processing/account/follow.go @@ -40,7 +40,7 @@ func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode } // Check if a follow exists already. - if follows, err := p.state.DB.IsFollowing(ctx, requestingAccount, targetAccount); err != nil { + if follows, err := p.state.DB.IsFollowing(ctx, requestingAccount.ID, targetAccount.ID); err != nil { err = fmt.Errorf("FollowCreate: db error checking follow: %w", err) return nil, gtserror.NewErrorInternalError(err) } else if follows { @@ -49,7 +49,7 @@ func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode } // Check if a follow request exists already. - if followRequested, err := p.state.DB.IsFollowRequested(ctx, requestingAccount, targetAccount); err != nil { + if followRequested, err := p.state.DB.IsFollowRequested(ctx, requestingAccount.ID, targetAccount.ID); err != nil { err = fmt.Errorf("FollowCreate: db error checking follow request: %w", err) return nil, gtserror.NewErrorInternalError(err) } else if followRequested { @@ -75,7 +75,7 @@ func (p *Processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode Notify: form.Notify, } - if err := p.state.DB.Put(ctx, fr); err != nil { + if err := p.state.DB.PutFollowRequest(ctx, fr); err != nil { err = fmt.Errorf("FollowCreate: error creating follow request in db: %s", err) return nil, gtserror.NewErrorInternalError(err) } @@ -141,7 +141,7 @@ func (p *Processor) getFollowTarget(ctx context.Context, requestingAccountID str } // Do nothing if a block exists in either direction between accounts. - if blocked, err := p.state.DB.IsBlocked(ctx, requestingAccountID, targetAccountID, true); err != nil { + 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 { @@ -173,12 +173,30 @@ func (p *Processor) getFollowTarget(ctx context.Context, requestingAccountID str // messages will be returned which should then be processed by a client // api worker. func (p *Processor) unfollow(ctx context.Context, requestingAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) ([]messages.FromClientAPI, error) { - msgs := []messages.FromClientAPI{} + var msgs []messages.FromClientAPI - if fURI, err := p.state.DB.Unfollow(ctx, requestingAccount.ID, targetAccount.ID); err != nil { - err = fmt.Errorf("unfollow: error deleting follow from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) + // 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) return nil, err - } else if fURI != "" { + } + + if follow != nil { + // Delete known follow from database with ID. + 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) + return nil, err + } + + // If err == db.ErrNoEntries here then it + // indicates a race condition with another + // unfollow for the same requester->target. + return msgs, nil + } + // Follow status changed, process side effects. msgs = append(msgs, messages.FromClientAPI{ APObjectType: ap.ActivityFollow, @@ -186,25 +204,43 @@ func (p *Processor) unfollow(ctx context.Context, requestingAccount *gtsmodel.Ac GTSModel: >smodel.Follow{ AccountID: requestingAccount.ID, TargetAccountID: targetAccount.ID, - URI: fURI, + URI: follow.URI, }, OriginAccount: requestingAccount, TargetAccount: targetAccount, }) } - if frURI, err := p.state.DB.UnfollowRequest(ctx, requestingAccount.ID, targetAccount.ID); err != nil { - err = fmt.Errorf("unfollow: error deleting follow request from %s targeting %s: %w", requestingAccount.ID, targetAccount.ID, err) + // 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) return nil, err - } else if frURI != "" { - // Follow request status changed, process side effects. + } + + if followReq != nil { + // Delete known follow request from database with ID. + 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) + return nil, err + } + + // If err == db.ErrNoEntries here then it + // indicates a race condition with another + // unfollow for the same requester->target. + return msgs, nil + } + + // Follow status changed, process side effects. msgs = append(msgs, messages.FromClientAPI{ APObjectType: ap.ActivityFollow, APActivityType: ap.ActivityUndo, GTSModel: >smodel.Follow{ AccountID: requestingAccount.ID, TargetAccountID: targetAccount.ID, - URI: frURI, + URI: followReq.URI, }, OriginAccount: requestingAccount, TargetAccount: targetAccount, diff --git a/internal/processing/account/get.go b/internal/processing/account/get.go index cfa6d4896..84d00c46b 100644 --- a/internal/processing/account/get.go +++ b/internal/processing/account/get.go @@ -73,7 +73,7 @@ func (p *Processor) getFor(ctx context.Context, requestingAccount *gtsmodel.Acco var blocked bool var err error if requestingAccount != nil { - blocked, err = p.state.DB.IsBlocked(ctx, requestingAccount.ID, targetAccount.ID, true) + blocked, err = p.state.DB.IsEitherBlocked(ctx, requestingAccount.ID, targetAccount.ID) if err != nil { return nil, gtserror.NewErrorInternalError(fmt.Errorf("error checking account block: %s", err)) } diff --git a/internal/processing/account/relationships.go b/internal/processing/account/relationships.go index 4afe36afe..d12d989ef 100644 --- a/internal/processing/account/relationships.go +++ b/internal/processing/account/relationships.go @@ -31,7 +31,7 @@ import ( // FollowersGet fetches a list of the target account's followers. func (p *Processor) FollowersGet(ctx context.Context, requestingAccount *gtsmodel.Account, targetAccountID string) ([]apimodel.Account, gtserror.WithCode) { - if blocked, err := p.state.DB.IsBlocked(ctx, requestingAccount.ID, targetAccountID, true); err != nil { + if blocked, err := p.state.DB.IsEitherBlocked(ctx, requestingAccount.ID, targetAccountID); err != nil { err = fmt.Errorf("FollowersGet: db error checking block: %w", err) return nil, gtserror.NewErrorInternalError(err) } else if blocked { @@ -39,7 +39,7 @@ func (p *Processor) FollowersGet(ctx context.Context, requestingAccount *gtsmode return nil, gtserror.NewErrorNotFound(err) } - follows, err := p.state.DB.GetFollows(ctx, "", targetAccountID) + follows, err := p.state.DB.GetAccountFollowers(ctx, targetAccountID) if err != nil { if !errors.Is(err, db.ErrNoEntries) { err = fmt.Errorf("FollowersGet: db error getting followers: %w", err) @@ -53,7 +53,7 @@ func (p *Processor) FollowersGet(ctx context.Context, requestingAccount *gtsmode // FollowingGet fetches a list of the accounts that target account is following. func (p *Processor) FollowingGet(ctx context.Context, requestingAccount *gtsmodel.Account, targetAccountID string) ([]apimodel.Account, gtserror.WithCode) { - if blocked, err := p.state.DB.IsBlocked(ctx, requestingAccount.ID, targetAccountID, true); err != nil { + if blocked, err := p.state.DB.IsEitherBlocked(ctx, requestingAccount.ID, targetAccountID); err != nil { err = fmt.Errorf("FollowingGet: db error checking block: %w", err) return nil, gtserror.NewErrorInternalError(err) } else if blocked { @@ -61,7 +61,7 @@ func (p *Processor) FollowingGet(ctx context.Context, requestingAccount *gtsmode return nil, gtserror.NewErrorNotFound(err) } - follows, err := p.state.DB.GetFollows(ctx, targetAccountID, "") + follows, err := p.state.DB.GetAccountFollows(ctx, targetAccountID) if err != nil { if !errors.Is(err, db.ErrNoEntries) { err = fmt.Errorf("FollowingGet: db error getting followers: %w", err) @@ -70,7 +70,7 @@ func (p *Processor) FollowingGet(ctx context.Context, requestingAccount *gtsmode return []apimodel.Account{}, nil } - return p.accountsFromFollows(ctx, follows, requestingAccount.ID) + return p.targetAccountsFromFollows(ctx, follows, requestingAccount.ID) } // RelationshipGet returns a relationship model describing the relationship of the targetAccount to the Authed account. @@ -101,7 +101,7 @@ func (p *Processor) accountsFromFollows(ctx context.Context, follows []*gtsmodel continue } - if blocked, err := p.state.DB.IsBlocked(ctx, requestingAccountID, follow.AccountID, true); err != nil { + if blocked, err := p.state.DB.IsEitherBlocked(ctx, requestingAccountID, follow.AccountID); err != nil { err = fmt.Errorf("accountsFromFollows: db error checking block: %w", err) return nil, gtserror.NewErrorInternalError(err) } else if blocked { @@ -113,8 +113,35 @@ func (p *Processor) accountsFromFollows(ctx context.Context, follows []*gtsmodel err = fmt.Errorf("accountsFromFollows: error converting account to api account: %w", err) return nil, gtserror.NewErrorInternalError(err) } + accounts = append(accounts, *account) } + return accounts, nil +} +func (p *Processor) targetAccountsFromFollows(ctx context.Context, follows []*gtsmodel.Follow, requestingAccountID string) ([]apimodel.Account, gtserror.WithCode) { + accounts := make([]apimodel.Account, 0, len(follows)) + for _, follow := range follows { + if follow.TargetAccount == nil { + // No account set for some reason; just skip. + log.WithContext(ctx).WithField("follow", follow).Warn("follow had no associated target account") + continue + } + + if blocked, err := p.state.DB.IsEitherBlocked(ctx, requestingAccountID, follow.TargetAccountID); err != nil { + err = fmt.Errorf("targetAccountsFromFollows: db error checking block: %w", err) + return nil, gtserror.NewErrorInternalError(err) + } else if blocked { + continue + } + + account, err := p.tc.AccountToAPIAccountPublic(ctx, follow.TargetAccount) + if err != nil { + err = fmt.Errorf("targetAccountsFromFollows: error converting account to api account: %w", err) + return nil, gtserror.NewErrorInternalError(err) + } + + accounts = append(accounts, *account) + } return accounts, nil } diff --git a/internal/processing/account/statuses.go b/internal/processing/account/statuses.go index 9ff23ad4b..0b4ee5a2a 100644 --- a/internal/processing/account/statuses.go +++ b/internal/processing/account/statuses.go @@ -19,6 +19,7 @@ package account import ( "context" + "errors" "fmt" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" @@ -32,10 +33,11 @@ import ( // the account given in authed. func (p *Processor) StatusesGet(ctx context.Context, requestingAccount *gtsmodel.Account, targetAccountID string, limit int, excludeReplies bool, excludeReblogs bool, maxID string, minID string, pinned bool, mediaOnly bool, publicOnly bool) (*apimodel.PageableResponse, gtserror.WithCode) { if requestingAccount != nil { - if blocked, err := p.state.DB.IsBlocked(ctx, requestingAccount.ID, targetAccountID, true); err != nil { + if blocked, err := p.state.DB.IsEitherBlocked(ctx, requestingAccount.ID, targetAccountID); err != nil { return nil, gtserror.NewErrorInternalError(err) } else if blocked { - return nil, gtserror.NewErrorNotFound(fmt.Errorf("block exists between accounts")) + err := errors.New("block exists between accounts") + return nil, gtserror.NewErrorNotFound(err) } } @@ -57,14 +59,10 @@ func (p *Processor) StatusesGet(ctx context.Context, requestingAccount *gtsmodel return nil, gtserror.NewErrorInternalError(err) } - // Filtering + serialization process is the same for - // either pinned status queries or 'normal' ones. - filtered := make([]*gtsmodel.Status, 0, len(statuses)) - for _, s := range statuses { - visible, err := p.filter.StatusVisible(ctx, s, requestingAccount) - if err == nil && visible { - filtered = append(filtered, s) - } + // Filtering + serialization process is the same for either pinned status queries or 'normal' ones. + filtered, err := p.filter.StatusesVisible(ctx, requestingAccount, statuses) + if err != nil { + return nil, gtserror.NewErrorInternalError(err) } count := len(filtered) |