diff --git a/internal/federation/dereferencing/account.go b/internal/federation/dereferencing/account.go index a4e74de3c..562062c8d 100644 --- a/internal/federation/dereferencing/account.go +++ b/internal/federation/dereferencing/account.go @@ -42,6 +42,11 @@ import ( // accountUpToDate returns whether the given account model is both updateable (i.e. // non-instance remote account) and whether it needs an update based on `fetched_at`. func accountUpToDate(account *gtsmodel.Account) bool { + if !account.SuspendedAt.IsZero() { + // Can't update suspended accounts. + return true + } + if account.IsLocal() { // Can't update local accounts. return true @@ -331,6 +336,11 @@ func (d *Dereferencer) enrichAccountSafely( account *gtsmodel.Account, apubAcc ap.Accountable, ) (*gtsmodel.Account, ap.Accountable, error) { + // Noop if account has been suspended. + if !account.SuspendedAt.IsZero() { + return account, nil, nil + } + // By default use account.URI // as the per-URI deref lock. uriStr := account.URI diff --git a/internal/federation/federatingprotocol.go b/internal/federation/federatingprotocol.go index 5a913dbbe..802a8b1dc 100644 --- a/internal/federation/federatingprotocol.go +++ b/internal/federation/federatingprotocol.go @@ -288,6 +288,13 @@ func (f *Federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr return nil, false, err } + if !requestingAccount.SuspendedAt.IsZero() { + // Account was marked as suspended by a + // local admin action. Stop request early. + w.WriteHeader(http.StatusForbidden) + return ctx, false, nil + } + // We have everything we need now, set the requesting // and receiving accounts on the context for later use. ctx = gtscontext.SetRequestingAccount(ctx, requestingAccount) diff --git a/internal/processing/fedi/common.go b/internal/processing/fedi/common.go index 38c31ffd2..c41f1e00c 100644 --- a/internal/processing/fedi/common.go +++ b/internal/processing/fedi/common.go @@ -63,6 +63,13 @@ func (p *Processor) authenticate(ctx context.Context, requestedUsername string) return nil, nil, gtserror.NewErrorUnauthorized(err) } + if !requestingAccount.SuspendedAt.IsZero() { + // Account was marked as suspended by a + // local admin action. Stop request early. + err = fmt.Errorf("account %s marked as suspended", requestingAccount.ID) + return nil, nil, gtserror.NewErrorForbidden(err) + } + // Ensure no block exists between requester + requested. blocked, err := p.state.DB.IsEitherBlocked(ctx, requestedAccount.ID, requestingAccount.ID) if err != nil { @@ -72,7 +79,7 @@ func (p *Processor) authenticate(ctx context.Context, requestedUsername string) if blocked { err = fmt.Errorf("block exists between accounts %s and %s", requestedAccount.ID, requestingAccount.ID) - return nil, nil, gtserror.NewErrorUnauthorized(err) + return nil, nil, gtserror.NewErrorForbidden(err) } return requestedAccount, requestingAccount, nil diff --git a/internal/processing/fedi/user.go b/internal/processing/fedi/user.go index 67f137f25..17663a8f4 100644 --- a/internal/processing/fedi/user.go +++ b/internal/processing/fedi/user.go @@ -106,6 +106,13 @@ func (p *Processor) UserGet(ctx context.Context, requestedUsername string, reque return nil, gtserror.NewErrorUnauthorized(err) } + if !requestingAccount.SuspendedAt.IsZero() { + // Account was marked as suspended by a + // local admin action. Stop request early. + err = fmt.Errorf("account %s marked as suspended", requestingAccount.ID) + return nil, gtserror.NewErrorForbidden(err) + } + blocked, err := p.state.DB.IsBlocked(ctx, requestedAccount.ID, requestingAccount.ID) if err != nil { err := gtserror.Newf("error checking block from account %s to account %s: %w", requestedAccount.ID, requestingAccount.ID, err) @@ -114,7 +121,7 @@ func (p *Processor) UserGet(ctx context.Context, requestedUsername string, reque if blocked { err := fmt.Errorf("account %s blocks account %s", requestedAccount.ID, requestingAccount.ID) - return nil, gtserror.NewErrorUnauthorized(err) + return nil, gtserror.NewErrorForbidden(err) } return data(person)