diff options
| author | 2025-04-06 14:39:40 +0200 | |
|---|---|---|
| committer | 2025-04-06 14:39:40 +0200 | |
| commit | 8ae2440da3a9b66c379c5a9444b50e758deef61b (patch) | |
| tree | 06b3ba58208434f6ddbd198a396159ac2c4d9c80 /internal/federation/dereferencing/status.go | |
| parent | [feature] Allow deleting avatar + header via settings panel (#3970) (diff) | |
| download | gotosocial-8ae2440da3a9b66c379c5a9444b50e758deef61b.tar.xz | |
[chore] Migrate accounts to new table, relax uniqueness constraint of actor `url` and collections (#3928)
* [chore] Migrate accounts to new table, relax uniqueness constraint of actor url and collections
* fiddle with it! (that's what she said)
* remove unused cache fields
* sillyness
* fix tiny whoopsie
Diffstat (limited to 'internal/federation/dereferencing/status.go')
| -rw-r--r-- | internal/federation/dereferencing/status.go | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/internal/federation/dereferencing/status.go b/internal/federation/dereferencing/status.go index 2718187cf..d99bae15b 100644 --- a/internal/federation/dereferencing/status.go +++ b/internal/federation/dereferencing/status.go @@ -454,7 +454,8 @@ func (d *Dereferencer) enrichStatus( // Ensure we have the author account of the status dereferenced (+ up-to-date). If this is a new status // (i.e. status.AccountID == "") then any error here is irrecoverable. status.AccountID must ALWAYS be set. - if _, _, err := d.getAccountByURI(ctx, requestUser, attributedTo); err != nil && status.AccountID == "" { + // We want the exact URI match here as well, not the imprecise URL match. + if _, _, err := d.getAccountByURI(ctx, requestUser, attributedTo, false); err != nil && status.AccountID == "" { // Note that we specifically DO NOT wrap the error, instead collapsing it as string. // Errors fetching an account do not necessarily relate to dereferencing the status. @@ -671,7 +672,7 @@ func (d *Dereferencer) fetchStatusMentions( // Search existing status for a mention already stored, // else ensure new mention's target account is populated. - mention, alreadyExists, err = d.getPopulatedMention(ctx, + mention, alreadyExists, err = d.populateMentionTarget(ctx, requestUser, existing, mention, @@ -1290,7 +1291,7 @@ func (d *Dereferencer) handleStatusEdit( return cols, nil } -// getPopulatedMention tries to populate the given +// populateMentionTarget tries to populate the given // mention with the correct TargetAccount and (if not // yet set) TargetAccountURI, returning the populated // mention. @@ -1302,7 +1303,13 @@ func (d *Dereferencer) handleStatusEdit( // Otherwise, this function will try to parse first // the Href of the mention, and then the namestring, // to see who it targets, and go fetch that account. -func (d *Dereferencer) getPopulatedMention( +// +// Note: Ordinarily it would make sense to try the +// namestring first, as it definitely can't be a URL +// rather than a URI, but because some remotes do +// silly things like only provide `@username` instead +// of `@username@domain`, we try by URI first. +func (d *Dereferencer) populateMentionTarget( ctx context.Context, requestUser string, existing *gtsmodel.Status, @@ -1312,8 +1319,9 @@ func (d *Dereferencer) getPopulatedMention( bool, // True if mention already exists in the DB. error, ) { - // Mentions can be created using Name or Href. - // Prefer Href (TargetAccountURI), fall back to Name. + // Mentions can be created using `name` or `href`. + // + // Prefer `href` (TargetAccountURI), fall back to Name. if mention.TargetAccountURI != "" { // Look for existing mention with target account's URI, if so use this. @@ -1323,19 +1331,24 @@ func (d *Dereferencer) getPopulatedMention( } // Ensure that mention account URI is parseable. - accountURI, err := url.Parse(mention.TargetAccountURI) + targetAccountURI, err := url.Parse(mention.TargetAccountURI) if err != nil { err := gtserror.Newf("invalid account uri %q: %w", mention.TargetAccountURI, err) return nil, false, err } - // Ensure we have account of the mention target dereferenced. + // Ensure we have the account of + // the mention target dereferenced. + // + // Use exact URI match only, not URL, + // as we want to be precise here. mention.TargetAccount, _, err = d.getAccountByURI(ctx, requestUser, - accountURI, + targetAccountURI, + false, ) if err != nil { - err := gtserror.Newf("failed to dereference account %s: %w", accountURI, err) + err := gtserror.Newf("failed to dereference account %s: %w", targetAccountURI, err) return nil, false, err } } else { @@ -1353,17 +1366,32 @@ func (d *Dereferencer) getPopulatedMention( return existingMention, true, nil } - // Ensure we have the account of the mention target dereferenced. + // Ensure we have the account of + // the mention target dereferenced. + // + // This might fail if the remote does + // something silly like only setting + // `@username` and not `@username@domain`. mention.TargetAccount, _, err = d.getAccountByUsernameDomain(ctx, requestUser, username, domain, ) - if err != nil { + if err != nil && !errors.Is(err, db.ErrNoEntries) { err := gtserror.Newf("failed to dereference account %s: %w", mention.NameString, err) return nil, false, err } + if mention.TargetAccount == nil { + // Probably failed for abovementioned + // silly reason. Nothing we can do about it. + err := gtserror.Newf( + "failed to populate mention target account (badly formatted namestring?) %s: %w", + mention.NameString, err, + ) + return nil, false, err + } + // Look for existing mention with target account's URI, if so use this. existingMention, ok = existing.GetMentionByTargetURI(mention.TargetAccountURI) if ok && existingMention.ID != "" { |
