summaryrefslogtreecommitdiff
path: root/internal/processing/fedi/common.go
diff options
context:
space:
mode:
authorLibravatar tobi <tobi.smethurst@protonmail.com>2025-10-15 18:57:57 +0200
committerLibravatar tobi <tobi.smethurst@protonmail.com>2025-10-17 15:33:49 +0200
commit6fee55dcff976f3eeae5879fe91d2f27780d0da4 (patch)
treed028c3ac30a84fc6095c9ca9dd4d136f905d8887 /internal/processing/fedi/common.go
parent[bugfix] Fix HTTP return code for Likes of remote statuses (#4504) (diff)
downloadgotosocial-6fee55dcff976f3eeae5879fe91d2f27780d0da4.tar.xz
[chore] Rationalize HTTP return codes for fedi endpoints, other tidying up (#4503)
# Description > If this is a code change, please include a summary of what you've coded, and link to the issue(s) it closes/implements. > > If this is a documentation change, please briefly describe what you've changed and why. This pull request does some refactoring of the fedi API endpoints and processing functions, and the authenticate + pub key deref functions, to try to return fewer silly HTTP codes like 410 Gone (when a *remote* account is gone, not a local one), and 500 errors where something isn't really an error. Also does some general tidying up and renaming for consistency. ## Checklist Please put an x inside each checkbox to indicate that you've read and followed it: `[ ]` -> `[x]` If this is a documentation change, only the first checkbox must be filled (you can delete the others if you want). - [x] I/we have read the [GoToSocial contribution guidelines](https://codeberg.org/superseriousbusiness/gotosocial/src/branch/main/CONTRIBUTING.md). - [x] I/we have discussed the proposed changes already, either in an issue on the repository, or in the Matrix chat. - [x] I/we have not leveraged AI to create the proposed changes. - [x] I/we have performed a self-review of added code. - [x] I/we have written code that is legible and maintainable by others. - [x] I/we have commented the added code, particularly in hard-to-understand areas. - [ ] I/we have made any necessary changes to documentation. - [ ] I/we have added tests that cover new code. - [x] I/we have run tests and they pass locally with the changes. - [x] I/we have run `go fmt ./...` and `golangci-lint run`. Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4503 Co-authored-by: tobi <tobi.smethurst@protonmail.com> Co-committed-by: tobi <tobi.smethurst@protonmail.com>
Diffstat (limited to 'internal/processing/fedi/common.go')
-rw-r--r--internal/processing/fedi/common.go107
1 files changed, 39 insertions, 68 deletions
diff --git a/internal/processing/fedi/common.go b/internal/processing/fedi/common.go
index fc783f93e..ff6ed6fd4 100644
--- a/internal/processing/fedi/common.go
+++ b/internal/processing/fedi/common.go
@@ -20,7 +20,6 @@ package fedi
import (
"context"
"errors"
- "fmt"
"net/url"
"code.superseriousbusiness.org/gotosocial/internal/db"
@@ -30,21 +29,23 @@ import (
type commonAuth struct {
handshakingURI *url.URL // Set to requestingAcct's URI if we're currently handshaking them.
- requestingAcct *gtsmodel.Account // Remote account making request to this instance.
- receivingAcct *gtsmodel.Account // Local account receiving the request.
+ requester *gtsmodel.Account // Remote account making request to this instance.
+ receiver *gtsmodel.Account // Local account receiving the request.
}
+// authenticate is a util function for authenticating a signed GET
+// request to one of the AP/fedi resources handled in this package.
func (p *Processor) authenticate(ctx context.Context, requestedUser string) (*commonAuth, gtserror.WithCode) {
- // First get the requested (receiving) LOCAL account with username from database.
+ // Get the requested local account
+ // with given username from database.
receiver, err := p.state.DB.GetAccountByUsernameDomain(ctx, requestedUser, "")
- if err != nil {
- if !errors.Is(err, db.ErrNoEntries) {
- // Real db error.
- err = gtserror.Newf("db error getting account %s: %w", requestedUser, err)
- return nil, gtserror.NewErrorInternalError(err)
- }
+ if err != nil && !errors.Is(err, db.ErrNoEntries) {
+ err = gtserror.Newf("db error getting account %s: %w", requestedUser, err)
+ return nil, gtserror.NewErrorInternalError(err)
+ }
- // Account just not found in the db.
+ if receiver == nil {
+ err := gtserror.Newf("account %s not found in the db", requestedUser)
return nil, gtserror.NewErrorNotFound(err)
}
@@ -60,74 +61,44 @@ func (p *Processor) authenticate(ctx context.Context, requestedUser string) (*co
// don't know the requester yet.
return &commonAuth{
handshakingURI: pubKeyAuth.OwnerURI,
- receivingAcct: receiver,
+ receiver: receiver,
}, nil
}
// Get requester from auth.
requester := pubKeyAuth.Owner
- // Ensure block does not exist between receiver and requester.
- blocked, err := p.state.DB.IsEitherBlocked(ctx, receiver.ID, requester.ID)
- if err != nil {
- err := gtserror.Newf("error checking block: %w", err)
- return nil, gtserror.NewErrorInternalError(err)
- } else if blocked {
- const text = "block exists between accounts"
- return nil, gtserror.NewErrorForbidden(errors.New(text))
+ // Check if requester is suspended.
+ switch {
+ case !requester.IsSuspended():
+ // No problem.
+
+ case requester.DeletedSelf():
+ // Requester deleted their own account.
+ // Why are they now requesting something?
+ err := gtserror.Newf("requester %s self-deleted", requester.UsernameDomain())
+ return nil, gtserror.NewErrorUnauthorized(err)
+
+ default:
+ // Admin from our instance likely suspended account.
+ err := gtserror.Newf("requester %s is suspended", requester.UsernameDomain())
+ return nil, gtserror.NewErrorForbidden(err)
}
- return &commonAuth{
- requestingAcct: requester,
- receivingAcct: receiver,
- }, nil
-}
-
-// validateIntReqRequest is a shortcut function
-// for returning an accepted interaction request
-// targeting `requestedUser`.
-func (p *Processor) validateIntReqRequest(
- ctx context.Context,
- requestedUser string,
- intReqID string,
-) (*gtsmodel.InteractionRequest, gtserror.WithCode) {
- // Authenticate incoming request, getting related accounts.
- auth, errWithCode := p.authenticate(ctx, requestedUser)
- if errWithCode != nil {
- return nil, errWithCode
- }
-
- if auth.handshakingURI != nil {
- // We're currently handshaking, which means we don't know
- // this account yet. This should be a very rare race condition.
- err := gtserror.Newf("network race handshaking %s", auth.handshakingURI)
- return nil, gtserror.NewErrorInternalError(err)
- }
-
- // Fetch interaction request with the given ID.
- req, err := p.state.DB.GetInteractionRequestByID(ctx, intReqID)
- if err != nil && !errors.Is(err, db.ErrNoEntries) {
- err := gtserror.Newf("db error getting interaction request %s: %w", intReqID, err)
+ // Ensure receiver does not block requester.
+ blocked, err := p.state.DB.IsBlocked(ctx, receiver.ID, requester.ID)
+ if err != nil {
+ err := gtserror.Newf("db error checking block: %w", err)
return nil, gtserror.NewErrorInternalError(err)
}
- // Ensure that this is an existing
- // and *accepted* interaction request.
- if req == nil || !req.IsAccepted() {
- const text = "interaction request not found"
- return nil, gtserror.NewErrorNotFound(errors.New(text))
- }
-
- // Ensure interaction request was accepted
- // by the account in the request path.
- if req.TargetAccountID != auth.receivingAcct.ID {
- text := fmt.Sprintf(
- "account %s is not targeted by interaction request %s and therefore can't accept it",
- requestedUser, intReqID,
- )
- return nil, gtserror.NewErrorNotFound(errors.New(text))
+ if blocked {
+ var text = requestedUser + " blocks " + requester.Username
+ return nil, gtserror.NewErrorForbidden(errors.New(text))
}
- // All fine.
- return req, nil
+ return &commonAuth{
+ requester: requester,
+ receiver: receiver,
+ }, nil
}