mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[chore] Add interaction filter to complement existing visibility filter (#3111)
* [chore] Add interaction filter to complement existing visibility filter * pass in ptr to visibility and interaction filters to Processor{} to ensure shared * use int constants for for match type, cache db calls in filterctx * function name typo 😇 --------- Co-authored-by: kim <grufwub@gmail.com>
This commit is contained in:
@ -38,7 +38,7 @@ type Processor struct {
|
||||
state *state.State
|
||||
converter *typeutils.Converter
|
||||
mediaManager *media.Manager
|
||||
filter *visibility.Filter
|
||||
visFilter *visibility.Filter
|
||||
formatter *text.Formatter
|
||||
federator *federation.Federator
|
||||
parseMention gtsmodel.ParseMentionFunc
|
||||
@ -52,7 +52,7 @@ func New(
|
||||
converter *typeutils.Converter,
|
||||
mediaManager *media.Manager,
|
||||
federator *federation.Federator,
|
||||
filter *visibility.Filter,
|
||||
visFilter *visibility.Filter,
|
||||
parseMention gtsmodel.ParseMentionFunc,
|
||||
) Processor {
|
||||
return Processor{
|
||||
@ -60,7 +60,7 @@ func New(
|
||||
state: state,
|
||||
converter: converter,
|
||||
mediaManager: mediaManager,
|
||||
filter: filter,
|
||||
visFilter: visFilter,
|
||||
formatter: text.NewFormatter(state.DB),
|
||||
federator: federator,
|
||||
parseMention: parseMention,
|
||||
|
@ -64,7 +64,7 @@ func (p *Processor) BookmarksGet(ctx context.Context, requestingAccount *gtsmode
|
||||
return nil, gtserror.NewErrorInternalError(err) // A real error has occurred.
|
||||
}
|
||||
|
||||
visible, err := p.filter.StatusVisible(ctx, requestingAccount, status)
|
||||
visible, err := p.visFilter.StatusVisible(ctx, requestingAccount, status)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error checking bookmarked status visibility: %s", err)
|
||||
continue
|
||||
|
@ -42,7 +42,7 @@ func (p *Processor) ListsGet(ctx context.Context, requestingAccount *gtsmodel.Ac
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error: %w", err))
|
||||
}
|
||||
|
||||
visible, err := p.filter.AccountVisible(ctx, requestingAccount, targetAccount)
|
||||
visible, err := p.visFilter.AccountVisible(ctx, requestingAccount, targetAccount)
|
||||
if err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error: %w", err))
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ func (p *Processor) StatusesGet(
|
||||
|
||||
// Filtering + serialization process is the same for
|
||||
// both pinned status queries and 'normal' ones.
|
||||
filtered, err := p.filter.StatusesVisible(ctx, requestingAccount, statuses)
|
||||
filtered, err := p.visFilter.StatusesVisible(ctx, requestingAccount, statuses)
|
||||
if err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||
@ -114,6 +115,8 @@ func (suite *AdminStandardTestSuite) SetupTest() {
|
||||
suite.mediaManager,
|
||||
&suite.state,
|
||||
suite.emailSender,
|
||||
visibility.NewFilter(&suite.state),
|
||||
interaction.NewFilter(&suite.state),
|
||||
)
|
||||
|
||||
testrig.StartWorkers(&suite.state, suite.processor.Workers())
|
||||
|
@ -55,7 +55,7 @@ func (p *Processor) GetTargetAccountBy(
|
||||
}
|
||||
|
||||
// Check whether target account is visible to requesting account.
|
||||
visible, err = p.filter.AccountVisible(ctx, requester, target)
|
||||
visible, err = p.visFilter.AccountVisible(ctx, requester, target)
|
||||
if err != nil {
|
||||
return nil, false, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
@ -241,7 +241,7 @@ func (p *Processor) getVisibleAPIAccounts(
|
||||
}
|
||||
|
||||
// Check whether this account is visible to requesting account.
|
||||
visible, err := p.filter.AccountVisible(ctx, requester, account)
|
||||
visible, err := p.visFilter.AccountVisible(ctx, requester, account)
|
||||
if err != nil {
|
||||
l.Errorf("error checking account visibility: %v", err)
|
||||
continue
|
||||
|
@ -33,7 +33,7 @@ type Processor struct {
|
||||
media *media.Manager
|
||||
converter *typeutils.Converter
|
||||
federator *federation.Federator
|
||||
filter *visibility.Filter
|
||||
visFilter *visibility.Filter
|
||||
}
|
||||
|
||||
// New returns a new Processor instance.
|
||||
@ -42,13 +42,13 @@ func New(
|
||||
media *media.Manager,
|
||||
converter *typeutils.Converter,
|
||||
federator *federation.Federator,
|
||||
filter *visibility.Filter,
|
||||
visFilter *visibility.Filter,
|
||||
) Processor {
|
||||
return Processor{
|
||||
state: state,
|
||||
media: media,
|
||||
converter: converter,
|
||||
federator: federator,
|
||||
filter: filter,
|
||||
visFilter: visFilter,
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ func (p *Processor) GetTargetStatusBy(
|
||||
}
|
||||
|
||||
// Check whether target status is visible to requesting account.
|
||||
visible, err = p.filter.StatusVisible(ctx, requester, target)
|
||||
visible, err = p.visFilter.StatusVisible(ctx, requester, target)
|
||||
if err != nil {
|
||||
return nil, false, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ type Processor struct {
|
||||
state *state.State
|
||||
federator *federation.Federator
|
||||
converter *typeutils.Converter
|
||||
filter *visibility.Filter
|
||||
visFilter *visibility.Filter
|
||||
}
|
||||
|
||||
// New returns a
|
||||
@ -42,13 +42,13 @@ func New(
|
||||
common *common.Processor,
|
||||
converter *typeutils.Converter,
|
||||
federator *federation.Federator,
|
||||
filter *visibility.Filter,
|
||||
visFilter *visibility.Filter,
|
||||
) Processor {
|
||||
return Processor{
|
||||
c: common,
|
||||
state: state,
|
||||
federator: federator,
|
||||
converter: converter,
|
||||
filter: filter,
|
||||
visFilter: visFilter,
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func (p *Processor) StatusGet(ctx context.Context, requestedUser string, statusI
|
||||
return nil, gtserror.NewErrorNotFound(errors.New(text))
|
||||
}
|
||||
|
||||
visible, err := p.filter.StatusVisible(ctx, requestingAcct, status)
|
||||
visible, err := p.visFilter.StatusVisible(ctx, requestingAcct, status)
|
||||
if err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
@ -163,7 +163,7 @@ func (p *Processor) StatusRepliesGet(
|
||||
}
|
||||
|
||||
// Reslice replies dropping all those invisible to requester.
|
||||
replies, err = p.filter.StatusesVisible(ctx, requestingAcct, replies)
|
||||
replies, err = p.visFilter.StatusesVisible(ctx, requestingAcct, replies)
|
||||
if err != nil {
|
||||
err := gtserror.Newf("error filtering status replies: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/cleaner"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
mm "github.com/superseriousbusiness/gotosocial/internal/media"
|
||||
@ -173,11 +174,10 @@ func NewProcessor(
|
||||
mediaManager *mm.Manager,
|
||||
state *state.State,
|
||||
emailSender email.Sender,
|
||||
visFilter *visibility.Filter,
|
||||
intFilter *interaction.Filter,
|
||||
) *Processor {
|
||||
var (
|
||||
parseMentionFunc = GetParseMentionFunc(state, federator)
|
||||
filter = visibility.NewFilter(state)
|
||||
)
|
||||
var parseMentionFunc = GetParseMentionFunc(state, federator)
|
||||
|
||||
processor := &Processor{
|
||||
converter: converter,
|
||||
@ -191,26 +191,26 @@ func NewProcessor(
|
||||
//
|
||||
// Start with sub processors that will
|
||||
// be required by the workers processor.
|
||||
common := common.New(state, mediaManager, converter, federator, filter)
|
||||
processor.account = account.New(&common, state, converter, mediaManager, federator, filter, parseMentionFunc)
|
||||
common := common.New(state, mediaManager, converter, federator, visFilter)
|
||||
processor.account = account.New(&common, state, converter, mediaManager, federator, visFilter, parseMentionFunc)
|
||||
processor.media = media.New(&common, state, converter, federator, mediaManager, federator.TransportController())
|
||||
processor.stream = stream.New(state, oauthServer)
|
||||
|
||||
// Instantiate the rest of the sub
|
||||
// processors + pin them to this struct.
|
||||
processor.account = account.New(&common, state, converter, mediaManager, federator, filter, parseMentionFunc)
|
||||
processor.account = account.New(&common, state, converter, mediaManager, federator, visFilter, parseMentionFunc)
|
||||
processor.admin = admin.New(&common, state, cleaner, federator, converter, mediaManager, federator.TransportController(), emailSender)
|
||||
processor.conversations = conversations.New(state, converter, filter)
|
||||
processor.fedi = fedi.New(state, &common, converter, federator, filter)
|
||||
processor.conversations = conversations.New(state, converter, visFilter)
|
||||
processor.fedi = fedi.New(state, &common, converter, federator, visFilter)
|
||||
processor.filtersv1 = filtersv1.New(state, converter, &processor.stream)
|
||||
processor.filtersv2 = filtersv2.New(state, converter, &processor.stream)
|
||||
processor.list = list.New(state, converter)
|
||||
processor.markers = markers.New(state, converter)
|
||||
processor.polls = polls.New(&common, state, converter)
|
||||
processor.report = report.New(state, converter)
|
||||
processor.timeline = timeline.New(state, converter, filter)
|
||||
processor.search = search.New(state, federator, converter, filter)
|
||||
processor.status = status.New(state, &common, &processor.polls, federator, converter, filter, parseMentionFunc)
|
||||
processor.timeline = timeline.New(state, converter, visFilter)
|
||||
processor.search = search.New(state, federator, converter, visFilter)
|
||||
processor.status = status.New(state, &common, &processor.polls, federator, converter, visFilter, intFilter, parseMentionFunc)
|
||||
processor.user = user.New(state, converter, oauthServer, emailSender)
|
||||
|
||||
// The advanced migrations processor sequences advanced migrations from all other processors.
|
||||
@ -223,7 +223,7 @@ func NewProcessor(
|
||||
state,
|
||||
federator,
|
||||
converter,
|
||||
filter,
|
||||
visFilter,
|
||||
emailSender,
|
||||
&processor.account,
|
||||
&processor.media,
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||
@ -122,7 +123,17 @@ func (suite *ProcessingStandardTestSuite) SetupTest() {
|
||||
suite.oauthServer = testrig.NewTestOauthServer(suite.db)
|
||||
suite.emailSender = testrig.NewEmailSender("../../web/template/", nil)
|
||||
|
||||
suite.processor = processing.NewProcessor(cleaner.New(&suite.state), suite.typeconverter, suite.federator, suite.oauthServer, suite.mediaManager, &suite.state, suite.emailSender)
|
||||
suite.processor = processing.NewProcessor(
|
||||
cleaner.New(&suite.state),
|
||||
suite.typeconverter,
|
||||
suite.federator,
|
||||
suite.oauthServer,
|
||||
suite.mediaManager,
|
||||
&suite.state,
|
||||
suite.emailSender,
|
||||
visibility.NewFilter(&suite.state),
|
||||
interaction.NewFilter(&suite.state),
|
||||
)
|
||||
testrig.StartWorkers(&suite.state, suite.processor.Workers())
|
||||
|
||||
testrig.StandardDBSetup(suite.db, suite.testAccounts)
|
||||
|
@ -28,15 +28,15 @@ type Processor struct {
|
||||
state *state.State
|
||||
federator *federation.Federator
|
||||
converter *typeutils.Converter
|
||||
filter *visibility.Filter
|
||||
visFilter *visibility.Filter
|
||||
}
|
||||
|
||||
// New returns a new status processor.
|
||||
func New(state *state.State, federator *federation.Federator, converter *typeutils.Converter, filter *visibility.Filter) Processor {
|
||||
func New(state *state.State, federator *federation.Federator, converter *typeutils.Converter, visFilter *visibility.Filter) Processor {
|
||||
return Processor{
|
||||
state: state,
|
||||
federator: federator,
|
||||
converter: converter,
|
||||
filter: filter,
|
||||
visFilter: visFilter,
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ func (p *Processor) packageStatuses(
|
||||
|
||||
for _, status := range statuses {
|
||||
// Ensure requester can see result status.
|
||||
visible, err := p.filter.StatusVisible(ctx, requestingAccount, status)
|
||||
visible, err := p.visFilter.StatusVisible(ctx, requestingAccount, status)
|
||||
if err != nil {
|
||||
err = gtserror.Newf("error checking visibility of status %s for account %s: %w", status.ID, requestingAccount.ID, err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
|
@ -66,7 +66,7 @@ func (p *Processor) BoostCreate(
|
||||
}
|
||||
|
||||
// Ensure valid boost target for requester.
|
||||
boostable, err := p.filter.StatusBoostable(ctx,
|
||||
policyResult, err := p.intFilter.StatusBoostable(ctx,
|
||||
requester,
|
||||
target,
|
||||
)
|
||||
@ -75,12 +75,14 @@ func (p *Processor) BoostCreate(
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if !boostable {
|
||||
err := gtserror.New("status is not boostable")
|
||||
return nil, gtserror.NewErrorNotFound(err)
|
||||
if policyResult.Forbidden() {
|
||||
const errText = "you do not have permission to boost this status"
|
||||
err := gtserror.New(errText)
|
||||
return nil, gtserror.NewErrorForbidden(err, errText)
|
||||
}
|
||||
|
||||
// Status is visible and boostable.
|
||||
// Status is visible and boostable
|
||||
// (though maybe pending approval).
|
||||
boost, err := p.converter.StatusToBoost(ctx,
|
||||
target,
|
||||
requester,
|
||||
@ -90,6 +92,29 @@ func (p *Processor) BoostCreate(
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
// Derive pendingApproval status.
|
||||
var pendingApproval bool
|
||||
switch {
|
||||
case policyResult.WithApproval():
|
||||
// We're allowed to do
|
||||
// this pending approval.
|
||||
pendingApproval = true
|
||||
|
||||
case policyResult.MatchedOnCollection():
|
||||
// We're permitted to do this, but since
|
||||
// we matched due to presence in a followers
|
||||
// or following collection, we should mark
|
||||
// as pending approval and wait for an accept.
|
||||
pendingApproval = true
|
||||
|
||||
case policyResult.Permitted():
|
||||
// We're permitted to do this
|
||||
// based on another kind of match.
|
||||
pendingApproval = false
|
||||
}
|
||||
|
||||
boost.PendingApproval = &pendingApproval
|
||||
|
||||
// Store the new boost.
|
||||
if err := p.state.DB.PutStatus(ctx, boost); err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
@ -184,7 +209,7 @@ func (p *Processor) StatusBoostedBy(ctx context.Context, requestingAccount *gtsm
|
||||
targetStatus = boostedStatus
|
||||
}
|
||||
|
||||
visible, err := p.filter.StatusVisible(ctx, requestingAccount, targetStatus)
|
||||
visible, err := p.visFilter.StatusVisible(ctx, requestingAccount, targetStatus)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("BoostedBy: error seeing if status %s is visible: %s", targetStatus.ID, err)
|
||||
return nil, gtserror.NewErrorNotFound(err)
|
||||
|
@ -341,7 +341,7 @@ func (p *Processor) ContextGet(
|
||||
// Convert ancestors + filter
|
||||
// out ones that aren't visible.
|
||||
for _, status := range threadContext.ancestors {
|
||||
if v, err := p.filter.StatusVisible(ctx, requester, status); err == nil && v {
|
||||
if v, err := p.visFilter.StatusVisible(ctx, requester, status); err == nil && v {
|
||||
status, err := convert(ctx, status, requester)
|
||||
if err == nil {
|
||||
apiContext.Ancestors = append(apiContext.Ancestors, *status)
|
||||
@ -352,7 +352,7 @@ func (p *Processor) ContextGet(
|
||||
// Convert descendants + filter
|
||||
// out ones that aren't visible.
|
||||
for _, status := range threadContext.descendants {
|
||||
if v, err := p.filter.StatusVisible(ctx, requester, status); err == nil && v {
|
||||
if v, err := p.visFilter.StatusVisible(ctx, requester, status); err == nil && v {
|
||||
status, err := convert(ctx, status, requester)
|
||||
if err == nil {
|
||||
apiContext.Descendants = append(apiContext.Descendants, *status)
|
||||
@ -453,7 +453,7 @@ func (p *Processor) WebContextGet(
|
||||
// Ensure status is actually
|
||||
// visible to just anyone, and
|
||||
// hide / don't include it if not.
|
||||
v, err := p.filter.StatusVisible(ctx, nil, status)
|
||||
v, err := p.visFilter.StatusVisible(ctx, nil, status)
|
||||
if err != nil || !v {
|
||||
if !inReplies {
|
||||
// Main thread entry hidden.
|
||||
|
@ -169,6 +169,8 @@ func (p *Processor) Create(
|
||||
|
||||
func (p *Processor) processInReplyTo(ctx context.Context, requester *gtsmodel.Account, status *gtsmodel.Status, inReplyToID string) gtserror.WithCode {
|
||||
if inReplyToID == "" {
|
||||
// Not a reply.
|
||||
// Nothing to do.
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -191,6 +193,45 @@ func (p *Processor) processInReplyTo(ctx context.Context, requester *gtsmodel.Ac
|
||||
return errWithCode
|
||||
}
|
||||
|
||||
// Ensure valid reply target for requester.
|
||||
policyResult, err := p.intFilter.StatusReplyable(ctx,
|
||||
requester,
|
||||
inReplyTo,
|
||||
)
|
||||
if err != nil {
|
||||
err := gtserror.Newf("error seeing if status %s is replyable: %w", status.ID, err)
|
||||
return gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if policyResult.Forbidden() {
|
||||
const errText = "you do not have permission to reply to this status"
|
||||
err := gtserror.New(errText)
|
||||
return gtserror.NewErrorForbidden(err, errText)
|
||||
}
|
||||
|
||||
// Derive pendingApproval status.
|
||||
var pendingApproval bool
|
||||
switch {
|
||||
case policyResult.WithApproval():
|
||||
// We're allowed to do
|
||||
// this pending approval.
|
||||
pendingApproval = true
|
||||
|
||||
case policyResult.MatchedOnCollection():
|
||||
// We're permitted to do this, but since
|
||||
// we matched due to presence in a followers
|
||||
// or following collection, we should mark
|
||||
// as pending approval and wait for an accept.
|
||||
pendingApproval = true
|
||||
|
||||
case policyResult.Permitted():
|
||||
// We're permitted to do this
|
||||
// based on another kind of match.
|
||||
pendingApproval = false
|
||||
}
|
||||
|
||||
status.PendingApproval = &pendingApproval
|
||||
|
||||
// Set status fields from inReplyTo.
|
||||
status.InReplyToID = inReplyTo.ID
|
||||
status.InReplyTo = inReplyTo
|
||||
|
@ -72,28 +72,73 @@ func (p *Processor) getFaveableStatus(
|
||||
}
|
||||
|
||||
// FaveCreate adds a fave for the requestingAccount, targeting the given status (no-op if fave already exists).
|
||||
func (p *Processor) FaveCreate(ctx context.Context, requestingAccount *gtsmodel.Account, targetStatusID string) (*apimodel.Status, gtserror.WithCode) {
|
||||
targetStatus, existingFave, errWithCode := p.getFaveableStatus(ctx, requestingAccount, targetStatusID)
|
||||
func (p *Processor) FaveCreate(
|
||||
ctx context.Context,
|
||||
requester *gtsmodel.Account,
|
||||
targetStatusID string,
|
||||
) (*apimodel.Status, gtserror.WithCode) {
|
||||
status, existingFave, errWithCode := p.getFaveableStatus(ctx, requester, targetStatusID)
|
||||
if errWithCode != nil {
|
||||
return nil, errWithCode
|
||||
}
|
||||
|
||||
if existingFave != nil {
|
||||
// Status is already faveed.
|
||||
return p.c.GetAPIStatus(ctx, requestingAccount, targetStatus)
|
||||
return p.c.GetAPIStatus(ctx, requester, status)
|
||||
}
|
||||
|
||||
// Create and store a new fave
|
||||
// Ensure valid fave target for requester.
|
||||
policyResult, err := p.intFilter.StatusLikeable(ctx,
|
||||
requester,
|
||||
status,
|
||||
)
|
||||
if err != nil {
|
||||
err := gtserror.Newf("error seeing if status %s is likeable: %w", status.ID, err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if policyResult.Forbidden() {
|
||||
const errText = "you do not have permission to fave this status"
|
||||
err := gtserror.New(errText)
|
||||
return nil, gtserror.NewErrorForbidden(err, errText)
|
||||
}
|
||||
|
||||
// Derive pendingApproval status.
|
||||
var pendingApproval bool
|
||||
switch {
|
||||
case policyResult.WithApproval():
|
||||
// We're allowed to do
|
||||
// this pending approval.
|
||||
pendingApproval = true
|
||||
|
||||
case policyResult.MatchedOnCollection():
|
||||
// We're permitted to do this, but since
|
||||
// we matched due to presence in a followers
|
||||
// or following collection, we should mark
|
||||
// as pending approval and wait for an accept.
|
||||
pendingApproval = true
|
||||
|
||||
case policyResult.Permitted():
|
||||
// We're permitted to do this
|
||||
// based on another kind of match.
|
||||
pendingApproval = false
|
||||
}
|
||||
|
||||
status.PendingApproval = &pendingApproval
|
||||
|
||||
// Create a new fave, marking it
|
||||
// as pending approval if necessary.
|
||||
faveID := id.NewULID()
|
||||
gtsFave := >smodel.StatusFave{
|
||||
ID: faveID,
|
||||
AccountID: requestingAccount.ID,
|
||||
Account: requestingAccount,
|
||||
TargetAccountID: targetStatus.AccountID,
|
||||
TargetAccount: targetStatus.Account,
|
||||
StatusID: targetStatus.ID,
|
||||
Status: targetStatus,
|
||||
URI: uris.GenerateURIForLike(requestingAccount.Username, faveID),
|
||||
AccountID: requester.ID,
|
||||
Account: requester,
|
||||
TargetAccountID: status.AccountID,
|
||||
TargetAccount: status.Account,
|
||||
StatusID: status.ID,
|
||||
Status: status,
|
||||
URI: uris.GenerateURIForLike(requester.Username, faveID),
|
||||
PendingApproval: &pendingApproval,
|
||||
}
|
||||
|
||||
if err := p.state.DB.PutStatusFave(ctx, gtsFave); err != nil {
|
||||
@ -106,11 +151,11 @@ func (p *Processor) FaveCreate(ctx context.Context, requestingAccount *gtsmodel.
|
||||
APObjectType: ap.ActivityLike,
|
||||
APActivityType: ap.ActivityCreate,
|
||||
GTSModel: gtsFave,
|
||||
Origin: requestingAccount,
|
||||
Target: targetStatus.Account,
|
||||
Origin: requester,
|
||||
Target: status.Account,
|
||||
})
|
||||
|
||||
return p.c.GetAPIStatus(ctx, requestingAccount, targetStatus)
|
||||
return p.c.GetAPIStatus(ctx, requester, status)
|
||||
}
|
||||
|
||||
// FaveRemove removes a fave for the requesting account, targeting the given status (no-op if fave doesn't exist).
|
||||
|
@ -19,6 +19,7 @@ package status
|
||||
|
||||
import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing/common"
|
||||
@ -35,7 +36,8 @@ type Processor struct {
|
||||
state *state.State
|
||||
federator *federation.Federator
|
||||
converter *typeutils.Converter
|
||||
filter *visibility.Filter
|
||||
visFilter *visibility.Filter
|
||||
intFilter *interaction.Filter
|
||||
formatter *text.Formatter
|
||||
parseMention gtsmodel.ParseMentionFunc
|
||||
|
||||
@ -50,7 +52,8 @@ func New(
|
||||
polls *polls.Processor,
|
||||
federator *federation.Federator,
|
||||
converter *typeutils.Converter,
|
||||
filter *visibility.Filter,
|
||||
visFilter *visibility.Filter,
|
||||
intFilter *interaction.Filter,
|
||||
parseMention gtsmodel.ParseMentionFunc,
|
||||
) Processor {
|
||||
return Processor{
|
||||
@ -58,7 +61,8 @@ func New(
|
||||
state: state,
|
||||
federator: federator,
|
||||
converter: converter,
|
||||
filter: filter,
|
||||
visFilter: visFilter,
|
||||
intFilter: intFilter,
|
||||
formatter: text.NewFormatter(state.DB),
|
||||
parseMention: parseMention,
|
||||
polls: polls,
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||
@ -89,16 +90,30 @@ func (suite *StatusStandardTestSuite) SetupTest() {
|
||||
suite.mediaManager = testrig.NewTestMediaManager(&suite.state)
|
||||
suite.federator = testrig.NewTestFederator(&suite.state, suite.tc, suite.mediaManager)
|
||||
|
||||
filter := visibility.NewFilter(&suite.state)
|
||||
visFilter := visibility.NewFilter(&suite.state)
|
||||
intFilter := interaction.NewFilter(&suite.state)
|
||||
testrig.StartTimelines(
|
||||
&suite.state,
|
||||
filter,
|
||||
visFilter,
|
||||
suite.typeConverter,
|
||||
)
|
||||
|
||||
common := common.New(&suite.state, suite.mediaManager, suite.typeConverter, suite.federator, filter)
|
||||
common := common.New(&suite.state, suite.mediaManager, suite.typeConverter, suite.federator, visFilter)
|
||||
polls := polls.New(&common, &suite.state, suite.typeConverter)
|
||||
suite.status = status.New(&suite.state, &common, &polls, suite.federator, suite.typeConverter, filter, processing.GetParseMentionFunc(&suite.state, suite.federator))
|
||||
|
||||
suite.status = status.New(
|
||||
&suite.state,
|
||||
&common,
|
||||
&polls,
|
||||
suite.federator,
|
||||
suite.typeConverter,
|
||||
visFilter,
|
||||
intFilter,
|
||||
processing.GetParseMentionFunc(
|
||||
&suite.state,
|
||||
suite.federator,
|
||||
),
|
||||
)
|
||||
|
||||
testrig.StandardDBSetup(suite.db, suite.testAccounts)
|
||||
testrig.StandardStorageSetup(suite.storage, "../../../testrig/media")
|
||||
|
@ -133,19 +133,22 @@ func (suite *StatusUpdateTestSuite) TestStreamNotification() {
|
||||
"interaction_policy": {
|
||||
"can_favourite": {
|
||||
"always": [
|
||||
"public"
|
||||
"public",
|
||||
"me"
|
||||
],
|
||||
"with_approval": []
|
||||
},
|
||||
"can_reply": {
|
||||
"always": [
|
||||
"public"
|
||||
"public",
|
||||
"me"
|
||||
],
|
||||
"with_approval": []
|
||||
},
|
||||
"can_reblog": {
|
||||
"always": [
|
||||
"public"
|
||||
"public",
|
||||
"me"
|
||||
],
|
||||
"with_approval": []
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func (p *Processor) FavedTimelineGet(ctx context.Context, authed *oauth.Auth, ma
|
||||
|
||||
items := make([]interface{}, 0, count)
|
||||
for _, s := range statuses {
|
||||
visible, err := p.filter.StatusVisible(ctx, authed.Account, s)
|
||||
visible, err := p.visFilter.StatusVisible(ctx, authed.Account, s)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error checking status visibility: %v", err)
|
||||
continue
|
||||
|
@ -62,7 +62,7 @@ func HomeTimelineGrab(state *state.State) timeline.GrabFunction {
|
||||
}
|
||||
|
||||
// HomeTimelineFilter returns a function that satisfies FilterFunction for home timelines.
|
||||
func HomeTimelineFilter(state *state.State, filter *visibility.Filter) timeline.FilterFunction {
|
||||
func HomeTimelineFilter(state *state.State, visFilter *visibility.Filter) timeline.FilterFunction {
|
||||
return func(ctx context.Context, accountID string, item timeline.Timelineable) (shouldIndex bool, err error) {
|
||||
status, ok := item.(*gtsmodel.Status)
|
||||
if !ok {
|
||||
@ -76,7 +76,7 @@ func HomeTimelineFilter(state *state.State, filter *visibility.Filter) timeline.
|
||||
return false, err
|
||||
}
|
||||
|
||||
timelineable, err := filter.StatusHomeTimelineable(ctx, requestingAccount, status)
|
||||
timelineable, err := visFilter.StatusHomeTimelineable(ctx, requestingAccount, status)
|
||||
if err != nil {
|
||||
err = gtserror.Newf("error checking hometimelineability of status %s for account %s: %w", status.ID, accountID, err)
|
||||
return false, err
|
||||
|
@ -62,7 +62,7 @@ func ListTimelineGrab(state *state.State) timeline.GrabFunction {
|
||||
}
|
||||
|
||||
// ListTimelineFilter returns a function that satisfies FilterFunction for list timelines.
|
||||
func ListTimelineFilter(state *state.State, filter *visibility.Filter) timeline.FilterFunction {
|
||||
func ListTimelineFilter(state *state.State, visFilter *visibility.Filter) timeline.FilterFunction {
|
||||
return func(ctx context.Context, listID string, item timeline.Timelineable) (shouldIndex bool, err error) {
|
||||
status, ok := item.(*gtsmodel.Status)
|
||||
if !ok {
|
||||
@ -82,7 +82,7 @@ func ListTimelineFilter(state *state.State, filter *visibility.Filter) timeline.
|
||||
return false, err
|
||||
}
|
||||
|
||||
timelineable, err := filter.StatusHomeTimelineable(ctx, requestingAccount, status)
|
||||
timelineable, err := visFilter.StatusHomeTimelineable(ctx, requestingAccount, status)
|
||||
if err != nil {
|
||||
err = gtserror.Newf("error checking hometimelineability of status %s for account %s: %w", status.ID, list.AccountID, err)
|
||||
return false, err
|
||||
|
@ -190,7 +190,7 @@ func (p *Processor) notifVisible(
|
||||
return true, nil
|
||||
}
|
||||
|
||||
visible, err := p.filter.AccountVisible(ctx, acct, n.OriginAccount)
|
||||
visible, err := p.visFilter.AccountVisible(ctx, acct, n.OriginAccount)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -203,7 +203,7 @@ func (p *Processor) notifVisible(
|
||||
// If status is set, ensure it's
|
||||
// visible to notif target.
|
||||
if n.Status != nil {
|
||||
visible, err := p.filter.StatusVisible(ctx, acct, n.Status)
|
||||
visible, err := p.visFilter.StatusVisible(ctx, acct, n.Status)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ outer:
|
||||
// we end up filtering it out or not.
|
||||
nextMaxIDValue = s.ID
|
||||
|
||||
timelineable, err := p.filter.StatusPublicTimelineable(ctx, requester, s)
|
||||
timelineable, err := p.visFilter.StatusPublicTimelineable(ctx, requester, s)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error checking status visibility: %v", err)
|
||||
continue inner
|
||||
|
@ -128,7 +128,7 @@ func (p *Processor) packageTagResponse(
|
||||
compiledMutes := usermute.NewCompiledUserMuteList(mutes)
|
||||
|
||||
for _, s := range statuses {
|
||||
timelineable, err := p.filter.StatusTagTimelineable(ctx, requestingAcct, s)
|
||||
timelineable, err := p.visFilter.StatusTagTimelineable(ctx, requestingAcct, s)
|
||||
if err != nil {
|
||||
log.Errorf(ctx, "error checking status visibility: %v", err)
|
||||
continue
|
||||
|
@ -26,13 +26,13 @@ import (
|
||||
type Processor struct {
|
||||
state *state.State
|
||||
converter *typeutils.Converter
|
||||
filter *visibility.Filter
|
||||
visFilter *visibility.Filter
|
||||
}
|
||||
|
||||
func New(state *state.State, converter *typeutils.Converter, filter *visibility.Filter) Processor {
|
||||
func New(state *state.State, converter *typeutils.Converter, visFilter *visibility.Filter) Processor {
|
||||
return Processor{
|
||||
state: state,
|
||||
converter: converter,
|
||||
filter: filter,
|
||||
visFilter: visFilter,
|
||||
}
|
||||
}
|
||||
|
@ -45,8 +45,12 @@ func (suite *FromFediAPITestSuite) TestProcessFederationAnnounce() {
|
||||
testStructs := suite.SetupTestStructs()
|
||||
defer suite.TearDownTestStructs(testStructs)
|
||||
|
||||
boostedStatus := suite.testStatuses["local_account_1_status_1"]
|
||||
boostingAccount := suite.testAccounts["remote_account_1"]
|
||||
boostedStatus := >smodel.Status{}
|
||||
*boostedStatus = *suite.testStatuses["local_account_1_status_1"]
|
||||
|
||||
boostingAccount := >smodel.Account{}
|
||||
*boostingAccount = *suite.testAccounts["remote_account_1"]
|
||||
|
||||
announceStatus := >smodel.Status{}
|
||||
announceStatus.URI = "https://example.org/some-announce-uri"
|
||||
announceStatus.BoostOfURI = boostedStatus.URI
|
||||
@ -64,13 +68,25 @@ func (suite *FromFediAPITestSuite) TestProcessFederationAnnounce() {
|
||||
Receiving: suite.testAccounts["local_account_1"],
|
||||
Requesting: boostingAccount,
|
||||
})
|
||||
suite.NoError(err)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
// side effects should be triggered
|
||||
// Wait for side effects to trigger:
|
||||
// 1. status should have an ID, and be in the database
|
||||
suite.NotEmpty(announceStatus.ID)
|
||||
_, err = testStructs.State.DB.GetStatusByID(context.Background(), announceStatus.ID)
|
||||
suite.NoError(err)
|
||||
if !testrig.WaitFor(func() bool {
|
||||
if announceStatus.ID == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
_, err = testStructs.State.DB.GetStatusByID(
|
||||
context.Background(),
|
||||
announceStatus.ID,
|
||||
)
|
||||
return err == nil
|
||||
}) {
|
||||
suite.FailNow("timed out waiting for announce to be in the database")
|
||||
}
|
||||
|
||||
// 2. a notification should exist for the announce
|
||||
where := []db.Where{
|
||||
@ -89,78 +105,89 @@ func (suite *FromFediAPITestSuite) TestProcessFederationAnnounce() {
|
||||
suite.False(*notif.Read)
|
||||
}
|
||||
|
||||
// Todo: fix this test up in interaction policies PR.
|
||||
// func (suite *FromFediAPITestSuite) TestProcessReplyMention() {
|
||||
// testStructs := suite.SetupTestStructs()
|
||||
// defer suite.TearDownTestStructs(testStructs)
|
||||
func (suite *FromFediAPITestSuite) TestProcessReplyMention() {
|
||||
testStructs := suite.SetupTestStructs()
|
||||
defer suite.TearDownTestStructs(testStructs)
|
||||
|
||||
// repliedAccount := suite.testAccounts["local_account_1"]
|
||||
// repliedStatus := suite.testStatuses["local_account_1_status_1"]
|
||||
// replyingAccount := suite.testAccounts["remote_account_1"]
|
||||
repliedAccount := >smodel.Account{}
|
||||
*repliedAccount = *suite.testAccounts["local_account_1"]
|
||||
|
||||
// // Set the replyingAccount's last fetched_at
|
||||
// // date to something recent so no refresh is attempted,
|
||||
// // and ensure it isn't a suspended account.
|
||||
// replyingAccount.FetchedAt = time.Now()
|
||||
// replyingAccount.SuspendedAt = time.Time{}
|
||||
// replyingAccount.SuspensionOrigin = ""
|
||||
// err := testStructs.State.DB.UpdateAccount(context.Background(),
|
||||
// replyingAccount,
|
||||
// "fetched_at",
|
||||
// "suspended_at",
|
||||
// "suspension_origin",
|
||||
// )
|
||||
// suite.NoError(err)
|
||||
repliedStatus := >smodel.Status{}
|
||||
*repliedStatus = *suite.testStatuses["local_account_1_status_1"]
|
||||
|
||||
// // Get replying statusable to use from remote test statuses.
|
||||
// const replyingURI = "http://fossbros-anonymous.io/users/foss_satan/statuses/106221634728637552"
|
||||
// replyingStatusable := testrig.NewTestFediStatuses()[replyingURI]
|
||||
// ap.AppendInReplyTo(replyingStatusable, testrig.URLMustParse(repliedStatus.URI))
|
||||
replyingAccount := >smodel.Account{}
|
||||
*replyingAccount = *suite.testAccounts["remote_account_1"]
|
||||
|
||||
// // Open a websocket stream to later test the streamed status reply.
|
||||
// wssStream, errWithCode := testStructs.Processor.Stream().Open(context.Background(), repliedAccount, stream.TimelineHome)
|
||||
// suite.NoError(errWithCode)
|
||||
// Set the replyingAccount's last fetched_at
|
||||
// date to something recent so no refresh is attempted,
|
||||
// and ensure it isn't a suspended account.
|
||||
replyingAccount.FetchedAt = time.Now()
|
||||
replyingAccount.SuspendedAt = time.Time{}
|
||||
replyingAccount.SuspensionOrigin = ""
|
||||
err := testStructs.State.DB.UpdateAccount(context.Background(),
|
||||
replyingAccount,
|
||||
"fetched_at",
|
||||
"suspended_at",
|
||||
"suspension_origin",
|
||||
)
|
||||
suite.NoError(err)
|
||||
|
||||
// // Send the replied status off to the fedi worker to be further processed.
|
||||
// err = testStructs.Processor.Workers().ProcessFromFediAPI(context.Background(), &messages.FromFediAPI{
|
||||
// APObjectType: ap.ObjectNote,
|
||||
// APActivityType: ap.ActivityCreate,
|
||||
// APObject: replyingStatusable,
|
||||
// Receiving: repliedAccount,
|
||||
// Requesting: replyingAccount,
|
||||
// })
|
||||
// suite.NoError(err)
|
||||
// Get replying statusable to use from remote test statuses.
|
||||
const replyingURI = "http://fossbros-anonymous.io/users/foss_satan/statuses/106221634728637552"
|
||||
replyingStatusable := testrig.NewTestFediStatuses()[replyingURI]
|
||||
ap.AppendInReplyTo(replyingStatusable, testrig.URLMustParse(repliedStatus.URI))
|
||||
|
||||
// // side effects should be triggered
|
||||
// // 1. status should be in the database
|
||||
// replyingStatus, err := testStructs.State.DB.GetStatusByURI(context.Background(), replyingURI)
|
||||
// suite.NoError(err)
|
||||
// Open a websocket stream to later test the streamed status reply.
|
||||
wssStream, errWithCode := testStructs.Processor.Stream().Open(context.Background(), repliedAccount, stream.TimelineHome)
|
||||
suite.NoError(errWithCode)
|
||||
|
||||
// // 2. a notification should exist for the mention
|
||||
// var notif gtsmodel.Notification
|
||||
// err = testStructs.State.DB.GetWhere(context.Background(), []db.Where{
|
||||
// {Key: "status_id", Value: replyingStatus.ID},
|
||||
// }, ¬if)
|
||||
// suite.NoError(err)
|
||||
// suite.Equal(gtsmodel.NotificationMention, notif.NotificationType)
|
||||
// suite.Equal(replyingStatus.InReplyToAccountID, notif.TargetAccountID)
|
||||
// suite.Equal(replyingStatus.AccountID, notif.OriginAccountID)
|
||||
// suite.Equal(replyingStatus.ID, notif.StatusID)
|
||||
// suite.False(*notif.Read)
|
||||
// Send the replied status off to the fedi worker to be further processed.
|
||||
err = testStructs.Processor.Workers().ProcessFromFediAPI(context.Background(), &messages.FromFediAPI{
|
||||
APObjectType: ap.ObjectNote,
|
||||
APActivityType: ap.ActivityCreate,
|
||||
APObject: replyingStatusable,
|
||||
Receiving: repliedAccount,
|
||||
Requesting: replyingAccount,
|
||||
})
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
// ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
|
||||
// msg, ok := wssStream.Recv(ctx)
|
||||
// suite.True(ok)
|
||||
// Wait for side effects to trigger:
|
||||
// 1. status should be in the database
|
||||
var replyingStatus *gtsmodel.Status
|
||||
if !testrig.WaitFor(func() bool {
|
||||
replyingStatus, err = testStructs.State.DB.GetStatusByURI(context.Background(), replyingURI)
|
||||
return err == nil
|
||||
}) {
|
||||
suite.FailNow("timed out waiting for replying status to be in the database")
|
||||
}
|
||||
|
||||
// suite.Equal(stream.EventTypeNotification, msg.Event)
|
||||
// suite.NotEmpty(msg.Payload)
|
||||
// suite.EqualValues([]string{stream.TimelineHome}, msg.Stream)
|
||||
// notifStreamed := &apimodel.Notification{}
|
||||
// err = json.Unmarshal([]byte(msg.Payload), notifStreamed)
|
||||
// suite.NoError(err)
|
||||
// suite.Equal("mention", notifStreamed.Type)
|
||||
// suite.Equal(replyingAccount.ID, notifStreamed.Account.ID)
|
||||
// }
|
||||
// 2. a notification should exist for the mention
|
||||
var notif gtsmodel.Notification
|
||||
err = testStructs.State.DB.GetWhere(context.Background(), []db.Where{
|
||||
{Key: "status_id", Value: replyingStatus.ID},
|
||||
}, ¬if)
|
||||
suite.NoError(err)
|
||||
suite.Equal(gtsmodel.NotificationMention, notif.NotificationType)
|
||||
suite.Equal(replyingStatus.InReplyToAccountID, notif.TargetAccountID)
|
||||
suite.Equal(replyingStatus.AccountID, notif.OriginAccountID)
|
||||
suite.Equal(replyingStatus.ID, notif.StatusID)
|
||||
suite.False(*notif.Read)
|
||||
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
|
||||
msg, ok := wssStream.Recv(ctx)
|
||||
suite.True(ok)
|
||||
|
||||
suite.Equal(stream.EventTypeNotification, msg.Event)
|
||||
suite.NotEmpty(msg.Payload)
|
||||
suite.EqualValues([]string{stream.TimelineHome}, msg.Stream)
|
||||
notifStreamed := &apimodel.Notification{}
|
||||
err = json.Unmarshal([]byte(msg.Payload), notifStreamed)
|
||||
suite.NoError(err)
|
||||
suite.Equal("mention", notifStreamed.Type)
|
||||
suite.Equal(replyingAccount.ID, notifStreamed.Account.ID)
|
||||
}
|
||||
|
||||
func (suite *FromFediAPITestSuite) TestProcessFave() {
|
||||
testStructs := suite.SetupTestStructs()
|
||||
@ -305,8 +332,11 @@ func (suite *FromFediAPITestSuite) TestProcessAccountDelete() {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
deletedAccount := suite.testAccounts["remote_account_1"]
|
||||
receivingAccount := suite.testAccounts["local_account_1"]
|
||||
deletedAccount := >smodel.Account{}
|
||||
*deletedAccount = *suite.testAccounts["remote_account_1"]
|
||||
|
||||
receivingAccount := >smodel.Account{}
|
||||
*receivingAccount = *suite.testAccounts["local_account_1"]
|
||||
|
||||
// before doing the delete....
|
||||
// make local_account_1 and remote_account_1 into mufos
|
||||
|
@ -36,7 +36,7 @@ type Surface struct {
|
||||
State *state.State
|
||||
Converter *typeutils.Converter
|
||||
Stream *stream.Processor
|
||||
Filter *visibility.Filter
|
||||
VisFilter *visibility.Filter
|
||||
EmailSender email.Sender
|
||||
Conversations *conversations.Processor
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func (suite *SurfaceNotifyTestSuite) TestSpamNotifs() {
|
||||
State: testStructs.State,
|
||||
Converter: testStructs.TypeConverter,
|
||||
Stream: testStructs.Processor.Stream(),
|
||||
Filter: visibility.NewFilter(testStructs.State),
|
||||
VisFilter: visibility.NewFilter(testStructs.State),
|
||||
EmailSender: testStructs.EmailSender,
|
||||
Conversations: testStructs.Processor.Conversations(),
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ func (s *Surface) timelineAndNotifyStatusForFollowers(
|
||||
// If it's not timelineable, we can just stop early, since lists
|
||||
// are prettymuch subsets of the home timeline, so if it shouldn't
|
||||
// appear there, it shouldn't appear in lists either.
|
||||
timelineable, err := s.Filter.StatusHomeTimelineable(
|
||||
timelineable, err := s.VisFilter.StatusHomeTimelineable(
|
||||
ctx, follow.Account, status,
|
||||
)
|
||||
if err != nil {
|
||||
@ -482,7 +482,7 @@ func (s *Surface) timelineStatusUpdateForFollowers(
|
||||
// If it's not timelineable, we can just stop early, since lists
|
||||
// are prettymuch subsets of the home timeline, so if it shouldn't
|
||||
// appear there, it shouldn't appear in lists either.
|
||||
timelineable, err := s.Filter.StatusHomeTimelineable(
|
||||
timelineable, err := s.VisFilter.StatusHomeTimelineable(
|
||||
ctx, follow.Account, status,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -40,7 +40,7 @@ func New(
|
||||
state *state.State,
|
||||
federator *federation.Federator,
|
||||
converter *typeutils.Converter,
|
||||
filter *visibility.Filter,
|
||||
visFilter *visibility.Filter,
|
||||
emailSender email.Sender,
|
||||
account *account.Processor,
|
||||
media *media.Processor,
|
||||
@ -61,7 +61,7 @@ func New(
|
||||
State: state,
|
||||
Converter: converter,
|
||||
Stream: stream,
|
||||
Filter: filter,
|
||||
VisFilter: visFilter,
|
||||
EmailSender: emailSender,
|
||||
Conversations: conversations,
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/cleaner"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
@ -160,7 +161,18 @@ func (suite *WorkersTestSuite) SetupTestStructs() *TestStructs {
|
||||
oauthServer := testrig.NewTestOauthServer(db)
|
||||
emailSender := testrig.NewEmailSender("../../../web/template/", nil)
|
||||
|
||||
processor := processing.NewProcessor(cleaner.New(&state), typeconverter, federator, oauthServer, mediaManager, &state, emailSender)
|
||||
processor := processing.NewProcessor(
|
||||
cleaner.New(&state),
|
||||
typeconverter,
|
||||
federator,
|
||||
oauthServer,
|
||||
mediaManager,
|
||||
&state,
|
||||
emailSender,
|
||||
visibility.NewFilter(&state),
|
||||
interaction.NewFilter(&state),
|
||||
)
|
||||
|
||||
testrig.StartWorkers(&state, processor.Workers())
|
||||
|
||||
testrig.StandardDBSetup(db, suite.testAccounts)
|
||||
|
Reference in New Issue
Block a user