1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
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{},
BoostedMentionedAccounts: []*gtsmodel.Account{},
}
// get the author account
if targetStatus.GTSAuthorAccount == nil {
statusAuthor := >smodel.Account{}
if err := f.db.GetByID(targetStatus.AccountID, statusAuthor); err != nil {
return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting statusAuthor with id %s: %s", targetStatus.AccountID, err)
}
targetStatus.GTSAuthorAccount = statusAuthor
}
accounts.StatusAuthor = targetStatus.GTSAuthorAccount
// get the replied to account from the status and add it to the pile
if targetStatus.InReplyToAccountID != "" {
repliedToAccount := >smodel.Account{}
if err := f.db.GetByID(targetStatus.InReplyToAccountID, repliedToAccount); err != nil {
return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting repliedToAcount with id %s: %s", targetStatus.InReplyToAccountID, err)
}
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
boostedStatus := >smodel.Status{}
if err := f.db.GetByID(targetStatus.BoostOfID, boostedStatus); err != nil {
return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting boostedStatus with id %s: %s", targetStatus.BoostOfID, err)
}
boostedAccount := >smodel.Account{}
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.BoostedStatusAuthor = boostedAccount
// the boosted status might be a reply to another account so we should get that too
if boostedStatus.InReplyToAccountID != "" {
boostedStatusRepliedToAccount := >smodel.Account{}
if err := f.db.GetByID(boostedStatus.InReplyToAccountID, boostedStatusRepliedToAccount); err != nil {
return accounts, fmt.Errorf("PullRelevantAccountsFromStatus: error getting boostedStatusRepliedToAccount with id %s: %s", boostedStatus.InReplyToAccountID, err)
}
accounts.BoostedReplyToAccount = boostedStatusRepliedToAccount
}
// 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 boosted mentioned account: %s", err)
}
accounts.BoostedMentionedAccounts = append(accounts.BoostedMentionedAccounts, mentionedAccount)
}
}
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 _, 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
}
|