simplify GetParseMentionFunc

This commit is contained in:
tsmethurst 2022-06-02 17:07:59 +02:00
parent 5e993f6799
commit 8ac9001df2

View file

@ -21,13 +21,14 @@ package processing
import (
"context"
"fmt"
"strings"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation"
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/util"
)
func GetParseMentionFunc(dbConn db.DB, federator federation.Federator) gtsmodel.ParseMentionFunc {
@ -38,91 +39,35 @@ func GetParseMentionFunc(dbConn db.DB, federator federation.Federator) gtsmodel.
return nil, fmt.Errorf("couldn't get mention origin account with id %s", originAccountID)
}
// A mentioned account looks like "@test@example.org" or just "@test" for a local account
// -- we can guarantee this from the regex that targetAccounts should have been derived from.
// But we still need to do a bit of fiddling to get what we need here -- the username and domain (if given).
// 1. trim off the first @
trimmed := strings.TrimPrefix(targetAccount, "@")
// 2. split the username and domain
split := strings.Split(trimmed, "@")
// 3. if it's length 1 it's a local account, length 2 means remote, anything else means something is wrong
var local bool
switch len(split) {
case 1:
local = true
case 2:
local = false
default:
return nil, fmt.Errorf("mentioned account format '%s' was not valid", targetAccount)
}
var username, domain string
username = split[0]
if !local {
domain = split[1]
}
// 4. check we now have a proper username and domain
if username == "" || (!local && domain == "") {
return nil, fmt.Errorf("username or domain for '%s' was nil", targetAccount)
username, domain, err := util.ExtractNamestringParts(targetAccount)
if err != nil {
return nil, fmt.Errorf("couldn't extract namestring parts from %s: %s", targetAccount, err)
}
var mentionedAccount *gtsmodel.Account
if local {
if domain == "" || domain == config.GetHost() || domain == config.GetAccountDomain() {
localAccount, err := dbConn.GetLocalAccountByUsername(ctx, username)
if err != nil {
return nil, err
}
mentionedAccount = localAccount
} else {
remoteAccount := &gtsmodel.Account{}
where := []db.Where{
{
Key: "username",
Value: username,
CaseInsensitive: true,
},
{
Key: "domain",
Value: domain,
CaseInsensitive: true,
},
var requestingUsername string
if originAccount.Domain == "" {
requestingUsername = originAccount.Username
}
remoteAccount, err := federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
RequestingUsername: requestingUsername,
RemoteAccountUsername: username,
RemoteAccountHost: domain,
})
if err != nil {
return nil, fmt.Errorf("error dereferencing account: %s", err)
}
err := dbConn.GetWhere(ctx, where, remoteAccount)
if err == nil {
// the account was already in the database
mentionedAccount = remoteAccount
} else {
// we couldn't get it from the database
if err != db.ErrNoEntries {
// a serious error has happened so bail
return nil, fmt.Errorf("error getting account with username '%s' and domain '%s': %s", username, domain, err)
}
// we were able to resolve it!
mentionedAccount = remoteAccount
// We just don't have the account, so try getting it.
var requestingUsername string
if originAccount.Domain == "" {
requestingUsername = originAccount.Username
}
resolvedAccount, err := federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
RequestingUsername: requestingUsername,
RemoteAccountUsername: username,
RemoteAccountHost: domain,
})
if err != nil {
return nil, fmt.Errorf("error dereferencing account: %s", err)
}
// we were able to resolve it!
mentionedAccount = resolvedAccount
}
}
mentionID, err := id.NewRandomULID()