mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-17 18:13:01 -06:00
[chore/security] refactor AuthenticateFederatedRequest() to handle account deref + suspension checks (#2371)
* refactor AuthenticateFederatedRequest() to handle account suspension + fetching of owner * small fixups * small changes * revert to 'IsEitherBlocked' instead of just 'IsBlocked" :grimace: * update code comment to indicate that AuthenticateFederatedRequest() will handle account + instance dereferencing
This commit is contained in:
parent
1ba3e14b36
commit
42d8011ff4
7 changed files with 205 additions and 198 deletions
|
|
@ -232,72 +232,17 @@ func (f *Federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr
|
|||
}
|
||||
}
|
||||
|
||||
pubKeyOwnerURI := pubKeyAuth.OwnerURI
|
||||
|
||||
// Authentication has passed, check if we need to create a
|
||||
// new instance entry for the Host of the requesting account.
|
||||
if _, err := f.db.GetInstance(ctx, pubKeyOwnerURI.Host); err != nil {
|
||||
if !errors.Is(err, db.ErrNoEntries) {
|
||||
// There's been an actual error.
|
||||
err = gtserror.Newf("error getting instance %s: %w", pubKeyOwnerURI.Host, err)
|
||||
return ctx, false, err
|
||||
}
|
||||
|
||||
// We don't have an entry for this
|
||||
// instance yet; go dereference it.
|
||||
instance, err := f.GetRemoteInstance(
|
||||
gtscontext.SetFastFail(ctx),
|
||||
username,
|
||||
&url.URL{
|
||||
Scheme: pubKeyOwnerURI.Scheme,
|
||||
Host: pubKeyOwnerURI.Host,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
err = gtserror.Newf("error dereferencing instance %s: %w", pubKeyOwnerURI.Host, err)
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if err := f.db.PutInstance(ctx, instance); err != nil && !errors.Is(err, db.ErrAlreadyExists) {
|
||||
err = gtserror.Newf("error inserting instance entry for %s: %w", pubKeyOwnerURI.Host, err)
|
||||
return nil, false, err
|
||||
}
|
||||
}
|
||||
|
||||
// We know the public key owner URI now, so we can
|
||||
// dereference the remote account (or just get it
|
||||
// from the db if we already have it).
|
||||
requestingAccount, _, err := f.GetAccountByURI(
|
||||
gtscontext.SetFastFail(ctx),
|
||||
username,
|
||||
pubKeyOwnerURI,
|
||||
)
|
||||
if err != nil {
|
||||
if gtserror.StatusCode(err) == http.StatusGone {
|
||||
// This is the same case as the http.StatusGone check above.
|
||||
// It can happen here and not there because there's a race
|
||||
// where the sending server starts sending account deletion
|
||||
// notifications out, we start processing, the request above
|
||||
// succeeds, and *then* the profile is removed and starts
|
||||
// returning 410 Gone, at which point _this_ request fails.
|
||||
w.WriteHeader(http.StatusAccepted)
|
||||
return ctx, false, nil
|
||||
}
|
||||
|
||||
err = gtserror.Newf("couldn't get requesting account %s: %w", pubKeyOwnerURI, err)
|
||||
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)
|
||||
if pubKeyAuth.Handshaking {
|
||||
// There is a mutal handshake occurring between us and
|
||||
// the owner URI. Return 202 and leave as we can't do
|
||||
// much else until the handshake procedure has finished.
|
||||
w.WriteHeader(http.StatusAccepted)
|
||||
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)
|
||||
ctx = gtscontext.SetRequestingAccount(ctx, pubKeyAuth.Owner)
|
||||
ctx = gtscontext.SetReceivingAccount(ctx, receivingAccount)
|
||||
return ctx, true, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue