From 3e72a9757beceb743697062b16d3be59f2b51d7f Mon Sep 17 00:00:00 2001 From: tsmethurst Date: Wed, 18 Aug 2021 17:27:41 +0200 Subject: [PATCH] i broke SOMETHING but what, it's a mystery --- internal/federation/dereferencing/status.go | 78 ++++++++++++++------- internal/processing/fromcommon.go | 23 +++--- internal/typeutils/internaltofrontend.go | 14 ++-- internal/visibility/statusvisible.go | 14 ++++ internal/visibility/util.go | 53 +++++++------- 5 files changed, 108 insertions(+), 74 deletions(-) diff --git a/internal/federation/dereferencing/status.go b/internal/federation/dereferencing/status.go index 59bf642c2..68693c021 100644 --- a/internal/federation/dereferencing/status.go +++ b/internal/federation/dereferencing/status.go @@ -317,58 +317,84 @@ func (d *deref) populateStatusFields(status *gtsmodel.Status, requestingUsername // At this point, mentions should have the namestring and mentionedAccountURI set on them. // // We should dereference any accounts mentioned here which we don't have in our db yet, by their URI. - mentions := []string{} + mentionIDs := []string{} for _, m := range status.Mentions { - if m.ID != "" { - continue // we've already populated this mention, since it has an ID + l.Debug("mention already populated") + continue + } + + if m.TargetAccountURI == "" { + // can't do anything with this mention + l.Debug("target URI not set on mention") + continue + } + + targetAccountURI, err := url.Parse(m.TargetAccountURI) + if err != nil { + l.Debugf("error parsing mentioned account uri %s: %s", m.TargetAccountURI, err) + continue + } + + var targetAccount *gtsmodel.Account + if a, err := d.db.GetAccountByURL(targetAccountURI.String()); err == nil { + targetAccount = a + } else if a, _, err := d.GetRemoteAccount(requestingUsername, targetAccountURI, false); err == nil { + targetAccount = a + } else { + // we can't find the target account so bail + l.Debug("can't retrieve account targeted by mention") + continue } mID, err := id.NewRandomULID() if err != nil { return err } - m.ID = mID - uri, err := url.Parse(m.TargetAccountURI) - if err != nil { - l.Debugf("error parsing mentioned account uri %s: %s", m.TargetAccountURI, err) - continue + m = >smodel.Mention{ + ID: mID, + StatusID: status.ID, + Status: m.Status, + CreatedAt: status.CreatedAt, + UpdatedAt: status.UpdatedAt, + OriginAccountID: status.Account.ID, + OriginAccountURI: status.AccountURI, + OriginAccount: status.Account, + TargetAccountID: targetAccount.ID, + TargetAccount: targetAccount, + NameString: m.NameString, + TargetAccountURI: targetAccount.URI, + TargetAccountURL: targetAccount.URL, } - m.StatusID = status.ID - m.Status = status - - m.OriginAccountID = status.Account.ID - m.OriginAccount = status.Account - m.OriginAccountURI = status.Account.URI - - targetAccount, _, err := d.GetRemoteAccount(requestingUsername, uri, false) - if err != nil { - continue - } - - // by this point, we know the targetAccount exists in our database with an ID :) - m.TargetAccountID = targetAccount.ID - m.TargetAccount = targetAccount if err := d.db.Put(m); err != nil { return fmt.Errorf("error creating mention: %s", err) } - mentions = append(mentions, m.ID) + mentionIDs = append(mentionIDs, m.ID) } - status.MentionIDs = mentions + status.MentionIDs = mentionIDs // status has replyToURI but we don't have an ID yet for the status it replies to if status.InReplyToURI != "" && status.InReplyToID == "" { + statusURI, err := url.Parse(status.InReplyToURI) + if err != nil { + return err + } if replyToStatus, err := d.db.GetStatusByURI(status.InReplyToURI); err == nil { // we have the status status.InReplyToID = replyToStatus.ID status.InReplyTo = replyToStatus status.InReplyToAccountID = replyToStatus.AccountID status.InReplyToAccount = replyToStatus.Account + } else if replyToStatus, _, _, err := d.GetRemoteStatus(requestingUsername, statusURI, false); err == nil { + // we got the status + status.InReplyToID = replyToStatus.ID + status.InReplyTo = replyToStatus + status.InReplyToAccountID = replyToStatus.AccountID + status.InReplyToAccount = replyToStatus.Account } } - return nil } diff --git a/internal/processing/fromcommon.go b/internal/processing/fromcommon.go index 80b18d4ac..c9d138358 100644 --- a/internal/processing/fromcommon.go +++ b/internal/processing/fromcommon.go @@ -36,13 +36,9 @@ func (p *processor) notifyStatus(status *gtsmodel.Status) error { if status.Mentions == nil { // there are mentions but they're not fully populated on the status yet so do this - menchies := []*gtsmodel.Mention{} - for _, m := range status.MentionIDs { - gtsm := >smodel.Mention{} - if err := p.db.GetByID(m, gtsm); err != nil { - return fmt.Errorf("notifyStatus: error getting mention with id %s from the db: %s", m, err) - } - menchies = append(menchies, gtsm) + menchies, err := p.db.GetMentions(status.MentionIDs) + if err != nil { + return fmt.Errorf("notifyStatus: error getting mentions for status %s from the db: %s", status.ID, err) } status.Mentions = menchies } @@ -50,15 +46,15 @@ func (p *processor) notifyStatus(status *gtsmodel.Status) error { // now we have mentions as full gtsmodel.Mention structs on the status we can continue for _, m := range status.Mentions { // make sure this is a local account, otherwise we don't need to create a notification for it - if m.OriginAccount == nil { - a := >smodel.Account{} - if err := p.db.GetByID(m.TargetAccountID, a); err != nil { + if m.TargetAccount == nil { + a, err := p.db.GetAccountByID(m.TargetAccountID) + if err != nil { // we don't have the account or there's been an error return fmt.Errorf("notifyStatus: error getting account with id %s from the db: %s", m.TargetAccountID, err) } - m.OriginAccount = a + m.TargetAccount = a } - if m.OriginAccount.Domain != "" { + if m.TargetAccount.Domain != "" { // not a local account so skip it continue } @@ -89,8 +85,11 @@ func (p *processor) notifyStatus(status *gtsmodel.Status) error { ID: notifID, NotificationType: gtsmodel.NotificationMention, TargetAccountID: m.TargetAccountID, + TargetAccount: m.TargetAccount, OriginAccountID: status.AccountID, + OriginAccount: status.Account, StatusID: status.ID, + Status: status, } if err := p.db.Put(notif); err != nil { diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go index cdf68730b..d68a16720 100644 --- a/internal/typeutils/internaltofrontend.go +++ b/internal/typeutils/internaltofrontend.go @@ -633,22 +633,22 @@ func (c *converter) RelationshipToMasto(r *gtsmodel.Relationship) (*model.Relati } func (c *converter) NotificationToMasto(n *gtsmodel.Notification) (*model.Notification, error) { - if n.TargetAccount == nil { - tAccount := >smodel.Account{} - if err := c.db.GetByID(n.TargetAccountID, tAccount); err != nil { + tAccount, err := c.db.GetAccountByID(n.TargetAccountID) + if err != nil { return nil, fmt.Errorf("NotificationToMasto: error getting target account with id %s from the db: %s", n.TargetAccountID, err) } n.TargetAccount = tAccount } if n.OriginAccount == nil { - ogAccount := >smodel.Account{} - if err := c.db.GetByID(n.OriginAccountID, ogAccount); err != nil { + ogAccount, err := c.db.GetAccountByID(n.OriginAccountID) + if err != nil { return nil, fmt.Errorf("NotificationToMasto: error getting origin account with id %s from the db: %s", n.OriginAccountID, err) } n.OriginAccount = ogAccount } + mastoAccount, err := c.AccountToMastoPublic(n.OriginAccount) if err != nil { return nil, fmt.Errorf("NotificationToMasto: error converting account to masto: %s", err) @@ -657,8 +657,8 @@ func (c *converter) NotificationToMasto(n *gtsmodel.Notification) (*model.Notifi var mastoStatus *model.Status if n.StatusID != "" { if n.Status == nil { - status := >smodel.Status{} - if err := c.db.GetByID(n.StatusID, status); err != nil { + status, err := c.db.GetStatusByID(n.StatusID) + if err != nil { return nil, fmt.Errorf("NotificationToMasto: error getting status with id %s from the db: %s", n.StatusID, err) } n.Status = status diff --git a/internal/visibility/statusvisible.go b/internal/visibility/statusvisible.go index 1cbb1b9ca..887f5c313 100644 --- a/internal/visibility/statusvisible.go +++ b/internal/visibility/statusvisible.go @@ -33,6 +33,11 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount } targetAccount := relevantAccounts.StatusAuthor + if targetAccount == nil { + l.Trace("target account is not set") + return false, nil + } + // if target account is suspended then don't show the status if !targetAccount.SuspendedAt.IsZero() { l.Trace("target account suspended at is not zero") @@ -155,6 +160,9 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount // status mentions accounts for _, a := range relevantAccounts.MentionedAccounts { + if a == nil { + continue + } if blocked, err := f.db.Blocked(a.ID, requestingAccount.ID, true); err != nil { return false, err } else if blocked { @@ -165,6 +173,9 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount // boost mentions accounts for _, a := range relevantAccounts.BoostedMentionedAccounts { + if a == nil { + continue + } if blocked, err := f.db.Blocked(a.ID, requestingAccount.ID, true); err != nil { return false, err } else if blocked { @@ -175,6 +186,9 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount // if the requesting account is mentioned in the status it should always be visible for _, acct := range relevantAccounts.MentionedAccounts { + if acct == nil { + continue + } if acct.ID == requestingAccount.ID { return true, nil // yep it's mentioned! } diff --git a/internal/visibility/util.go b/internal/visibility/util.go index aff9bb02a..91b250b3d 100644 --- a/internal/visibility/util.go +++ b/internal/visibility/util.go @@ -1,8 +1,6 @@ package visibility import ( - "fmt" - "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" ) @@ -16,29 +14,26 @@ func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) ( // get the author account if it's not set on the status already if targetStatus.Account == nil { statusAuthor, err := f.db.GetAccountByID(targetStatus.AccountID) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting statusAuthor with id %s: %s", targetStatus.AccountID, err) + if err == nil { + targetStatus.Account = statusAuthor } - targetStatus.Account = statusAuthor } accounts.StatusAuthor = targetStatus.Account // now get all accounts with IDs that are mentioned in the status if targetStatus.MentionIDs != nil && targetStatus.Mentions == nil { mentions, err := f.db.GetMentions(targetStatus.MentionIDs) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting mentions from status: %s", err) + if err == nil { + targetStatus.Mentions = mentions } - targetStatus.Mentions = mentions } for _, m := range targetStatus.Mentions { if m.TargetAccount == nil { t, err := f.db.GetAccountByID(m.TargetAccountID) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting mentions from status: %s", err) + if err == nil { + m.TargetAccount = t } - m.TargetAccount = t } accounts.MentionedAccounts = append(accounts.MentionedAccounts, m.TargetAccount) } @@ -46,20 +41,18 @@ func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) ( // get the replied to account if it's not set on the status already if targetStatus.InReplyToAccountID != "" && targetStatus.InReplyToAccount == nil { repliedToAccount, err := f.db.GetAccountByID(targetStatus.InReplyToAccountID) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting repliedToAcount with id %s: %s", targetStatus.InReplyToAccountID, err) + if err == nil { + targetStatus.InReplyToAccount = repliedToAccount } - targetStatus.InReplyToAccount = repliedToAccount } accounts.ReplyToAccount = targetStatus.InReplyToAccount // get the boosted status if it's not set on the status already if targetStatus.BoostOfID != "" && targetStatus.BoostOf == nil { boostedStatus, err := f.db.GetStatusByID(targetStatus.BoostOfID) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting boostedStatus with id %s: %s", targetStatus.BoostOfID, err) + if err == nil { + targetStatus.BoostOf = boostedStatus } - targetStatus.BoostOf = boostedStatus } // get the boosted account if it's not set on the status already @@ -68,10 +61,9 @@ func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) ( targetStatus.BoostOfAccount = targetStatus.BoostOf.Account } else { boostedAccount, err := f.db.GetAccountByID(targetStatus.BoostOfAccountID) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting boostOfAccount with id %s: %s", targetStatus.BoostOfAccountID, err) + if err == nil { + targetStatus.BoostOfAccount = boostedAccount } - targetStatus.BoostOfAccount = boostedAccount } } accounts.BoostedStatusAuthor = targetStatus.BoostOfAccount @@ -80,29 +72,26 @@ func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) ( // the boosted status might be a reply to another account so we should get that too if targetStatus.BoostOf.InReplyToAccountID != "" && targetStatus.BoostOf.InReplyToAccount == nil { boostOfInReplyToAccount, err := f.db.GetAccountByID(targetStatus.BoostOf.InReplyToAccountID) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting boostOfInReplyToAccount with id %s: %s", targetStatus.BoostOf.InReplyToAccountID, err) + if err == nil { + targetStatus.BoostOf.InReplyToAccount = boostOfInReplyToAccount } - targetStatus.BoostOf.InReplyToAccount = boostOfInReplyToAccount } accounts.BoostedReplyToAccount = targetStatus.BoostOf.InReplyToAccount // now get all accounts with IDs that are mentioned in the boosted status if targetStatus.BoostOf.MentionIDs != nil && targetStatus.BoostOf.Mentions == nil { mentions, err := f.db.GetMentions(targetStatus.BoostOf.MentionIDs) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting mentions from boostOf status: %s", err) + if err == nil { + targetStatus.BoostOf.Mentions = mentions } - targetStatus.BoostOf.Mentions = mentions } for _, m := range targetStatus.BoostOf.Mentions { if m.TargetAccount == nil { t, err := f.db.GetAccountByID(m.TargetAccountID) - if err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting mentions from boostOf status: %s", err) + if err == nil { + m.TargetAccount = t } - m.TargetAccount = t } accounts.BoostedMentionedAccounts = append(accounts.BoostedMentionedAccounts, m.TargetAccount) } @@ -172,6 +161,9 @@ func (f *filter) domainBlockedRelevant(r *relevantAccounts) (bool, error) { } for _, a := range r.MentionedAccounts { + if a == nil { + continue + } b, err := f.blockedDomain(a.Domain) if err != nil { return false, err @@ -202,6 +194,9 @@ func (f *filter) domainBlockedRelevant(r *relevantAccounts) (bool, error) { } for _, a := range r.BoostedMentionedAccounts { + if a == nil { + continue + } b, err := f.blockedDomain(a.Domain) if err != nil { return false, err