mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-29 20:06:16 -06:00
210 lines
5.8 KiB
Go
210 lines
5.8 KiB
Go
package visibility
|
|
|
|
import (
|
|
"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{},
|
|
BoostedMentionedAccounts: []*gtsmodel.Account{},
|
|
}
|
|
|
|
// 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 {
|
|
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 {
|
|
targetStatus.Mentions = mentions
|
|
}
|
|
}
|
|
|
|
for _, m := range targetStatus.Mentions {
|
|
if m.TargetAccount == nil {
|
|
t, err := f.db.GetAccountByID(m.TargetAccountID)
|
|
if err == nil {
|
|
m.TargetAccount = t
|
|
}
|
|
}
|
|
accounts.MentionedAccounts = append(accounts.MentionedAccounts, m.TargetAccount)
|
|
}
|
|
|
|
// 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 {
|
|
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 {
|
|
targetStatus.BoostOf = boostedStatus
|
|
}
|
|
}
|
|
|
|
// get the boosted account if it's not set on the status already
|
|
if targetStatus.BoostOfAccountID != "" && targetStatus.BoostOfAccount == nil {
|
|
if targetStatus.BoostOf != nil && targetStatus.BoostOf.Account != nil {
|
|
targetStatus.BoostOfAccount = targetStatus.BoostOf.Account
|
|
} else {
|
|
boostedAccount, err := f.db.GetAccountByID(targetStatus.BoostOfAccountID)
|
|
if err == nil {
|
|
targetStatus.BoostOfAccount = boostedAccount
|
|
}
|
|
}
|
|
}
|
|
accounts.BoostedStatusAuthor = targetStatus.BoostOfAccount
|
|
|
|
if targetStatus.BoostOf != nil {
|
|
// 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 {
|
|
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 {
|
|
targetStatus.BoostOf.Mentions = mentions
|
|
}
|
|
}
|
|
|
|
for _, m := range targetStatus.BoostOf.Mentions {
|
|
if m.TargetAccount == nil {
|
|
t, err := f.db.GetAccountByID(m.TargetAccountID)
|
|
if err == nil {
|
|
m.TargetAccount = t
|
|
}
|
|
}
|
|
accounts.BoostedMentionedAccounts = append(accounts.BoostedMentionedAccounts, m.TargetAccount)
|
|
}
|
|
}
|
|
|
|
return accounts, nil
|
|
}
|
|
|
|
// relevantAccounts denotes accounts that are replied to, boosted by, or mentioned in a status.
|
|
type relevantAccounts struct {
|
|
// 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
|
|
// 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 err == db.ErrNoEntries {
|
|
// 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 {
|
|
if a == nil {
|
|
continue
|
|
}
|
|
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 {
|
|
if a == nil {
|
|
continue
|
|
}
|
|
b, err := f.blockedDomain(a.Domain)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if b {
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|