diff options
Diffstat (limited to 'internal/visibility')
-rw-r--r-- | internal/visibility/statusvisible.go | 27 | ||||
-rw-r--r-- | internal/visibility/util.go | 146 |
2 files changed, 152 insertions, 21 deletions
diff --git a/internal/visibility/statusvisible.go b/internal/visibility/statusvisible.go index c022be359..dc6b74702 100644 --- a/internal/visibility/statusvisible.go +++ b/internal/visibility/statusvisible.go @@ -19,9 +19,20 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount relevantAccounts, err := f.pullRelevantAccountsFromStatus(targetStatus) if err != nil { l.Debugf("error pulling relevant accounts for status %s: %s", targetStatus.ID, err) + return false, fmt.Errorf("error pulling relevant accounts for status %s: %s", targetStatus.ID, err) + } + + domainBlocked, err := f.domainBlockedRelevant(relevantAccounts) + if err != nil { + l.Debugf("error checking domain block: %s", err) + return false, fmt.Errorf("error checking domain block: %s", err) } - targetAccount := relevantAccounts.StatusAuthor + if domainBlocked { + return false, nil + } + + targetAccount := relevantAccounts.StatusAuthor // if target account is suspended then don't show the status if !targetAccount.SuspendedAt.IsZero() { l.Trace("target account suspended at is not zero") @@ -123,8 +134,8 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount } // status boosts accounts id - if relevantAccounts.BoostedAccount != nil { - if blocked, err := f.db.Blocked(relevantAccounts.BoostedAccount.ID, requestingAccount.ID); err != nil { + if relevantAccounts.BoostedStatusAuthor != nil { + if blocked, err := f.db.Blocked(relevantAccounts.BoostedStatusAuthor.ID, requestingAccount.ID); err != nil { return false, err } else if blocked { l.Trace("a block exists between requesting account and boosted account") @@ -152,6 +163,16 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount } } + // boost mentions accounts + for _, a := range relevantAccounts.BoostedMentionedAccounts { + if blocked, err := f.db.Blocked(a.ID, requestingAccount.ID); err != nil { + return false, err + } else if blocked { + l.Trace("a block exists between requesting account and a boosted mentioned account") + return false, nil + } + } + // if the requesting account is mentioned in the status it should always be visible for _, acct := range relevantAccounts.MentionedAccounts { if acct.ID == requestingAccount.ID { diff --git a/internal/visibility/util.go b/internal/visibility/util.go index f52661d0b..a12dd555f 100644 --- a/internal/visibility/util.go +++ b/internal/visibility/util.go @@ -3,12 +3,14 @@ package visibility import ( "fmt" + "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" ) func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) (*relevantAccounts, error) { accounts := &relevantAccounts{ - MentionedAccounts: []*gtsmodel.Account{}, + MentionedAccounts: []*gtsmodel.Account{}, + BoostedMentionedAccounts: []*gtsmodel.Account{}, } // get the author account @@ -30,6 +32,21 @@ func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) ( accounts.ReplyToAccount = repliedToAccount } + // now get all accounts with IDs that are mentioned in the status + for _, mentionID := range targetStatus.Mentions { + + mention := >smodel.Mention{} + if err := f.db.GetByID(mentionID, mention); err != nil { + return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting mention with id %s: %s", mentionID, err) + } + + mentionedAccount := >smodel.Account{} + if err := f.db.GetByID(mention.TargetAccountID, mentionedAccount); err != nil { + return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting mentioned account: %s", err) + } + accounts.MentionedAccounts = append(accounts.MentionedAccounts, mentionedAccount) + } + // get the boosted account from the status and add it to the pile if targetStatus.BoostOfID != "" { // retrieve the boosted status first @@ -41,7 +58,7 @@ func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) ( if err := f.db.GetByID(boostedStatus.AccountID, boostedAccount); err != nil { return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting boostedAccount with id %s: %s", boostedStatus.AccountID, err) } - accounts.BoostedAccount = boostedAccount + accounts.BoostedStatusAuthor = boostedAccount // the boosted status might be a reply to another account so we should get that too if boostedStatus.InReplyToAccountID != "" { @@ -51,21 +68,20 @@ func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) ( } accounts.BoostedReplyToAccount = boostedStatusRepliedToAccount } - } - // now get all accounts with IDs that are mentioned in the status - for _, mentionID := range targetStatus.Mentions { - - mention := >smodel.Mention{} - if err := f.db.GetByID(mentionID, mention); err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting mention with id %s: %s", mentionID, err) - } + // now get all accounts with IDs that are mentioned in the status + for _, mentionID := range boostedStatus.Mentions { + mention := >smodel.Mention{} + if err := f.db.GetByID(mentionID, mention); err != nil { + return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting boosted mention with id %s: %s", mentionID, err) + } - mentionedAccount := >smodel.Account{} - if err := f.db.GetByID(mention.TargetAccountID, mentionedAccount); err != nil { - return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting mentioned account: %s", err) + mentionedAccount := >smodel.Account{} + if err := f.db.GetByID(mention.TargetAccountID, mentionedAccount); err != nil { + return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting boosted mentioned account: %s", err) + } + accounts.BoostedMentionedAccounts = append(accounts.BoostedMentionedAccounts, mentionedAccount) } - accounts.MentionedAccounts = append(accounts.MentionedAccounts, mentionedAccount) } return accounts, nil @@ -73,9 +89,103 @@ func (f *filter) pullRelevantAccountsFromStatus(targetStatus *gtsmodel.Status) ( // relevantAccounts denotes accounts that are replied to, boosted by, or mentioned in a status. type relevantAccounts struct { - StatusAuthor *gtsmodel.Account - ReplyToAccount *gtsmodel.Account - BoostedAccount *gtsmodel.Account + // Who wrote the status + StatusAuthor *gtsmodel.Account + // Who is the status replying to + ReplyToAccount *gtsmodel.Account + // Which accounts are mentioned (tagged) in the status + MentionedAccounts []*gtsmodel.Account + // Who authed the boosted status + BoostedStatusAuthor *gtsmodel.Account + // If the boosted status replies to another account, who does it reply to? BoostedReplyToAccount *gtsmodel.Account - MentionedAccounts []*gtsmodel.Account + // Who is mentioned (tagged) in the boosted status + BoostedMentionedAccounts []*gtsmodel.Account +} + +// blockedDomain checks whether the given domain is blocked by us or not +func (f *filter) blockedDomain(host string) (bool, error) { + b := >smodel.DomainBlock{} + err := f.db.GetWhere([]db.Where{{Key: "domain", Value: host, CaseInsensitive: true}}, b) + if err == nil { + // block exists + return true, nil + } + + if _, ok := err.(db.ErrNoEntries); ok { + // there are no entries so there's no block + return false, nil + } + + // there's an actual error + return false, err +} + +// domainBlockedRelevant checks through all relevant accounts attached to a status +// to make sure none of them are domain blocked by this instance. +// +// Will return true+nil if there's a block, false+nil if there's no block, or +// an error if something goes wrong. +func (f *filter) domainBlockedRelevant(r *relevantAccounts) (bool, error) { + if r.StatusAuthor != nil { + b, err := f.blockedDomain(r.StatusAuthor.Domain) + if err != nil { + return false, err + } + if b { + return true, nil + } + } + + if r.ReplyToAccount != nil { + b, err := f.blockedDomain(r.ReplyToAccount.Domain) + if err != nil { + return false, err + } + if b { + return true, nil + } + } + + for _, a := range r.MentionedAccounts { + b, err := f.blockedDomain(a.Domain) + if err != nil { + return false, err + } + if b { + return true, nil + } + } + + if r.BoostedStatusAuthor != nil { + b, err := f.blockedDomain(r.BoostedStatusAuthor.Domain) + if err != nil { + return false, err + } + if b { + return true, nil + } + } + + if r.BoostedReplyToAccount != nil { + b, err := f.blockedDomain(r.BoostedReplyToAccount.Domain) + if err != nil { + return false, err + } + if b { + return true, nil + } + } + + for _, a := range r.BoostedMentionedAccounts { + b, err := f.blockedDomain(a.Domain) + if err != nil { + return false, err + } + if b { + return true, nil + } + } + + return false, nil } |