mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-21 19:26:40 +00:00
[bugfix] Check interaction policies properly on incoming Likes (#3416)
This commit is contained in:
parent
cb9008fb41
commit
1c895f314c
|
@ -213,7 +213,7 @@
|
||||||
visFilter := visibility.NewFilter(state)
|
visFilter := visibility.NewFilter(state)
|
||||||
intFilter := interaction.NewFilter(state)
|
intFilter := interaction.NewFilter(state)
|
||||||
spamFilter := spam.NewFilter(state)
|
spamFilter := spam.NewFilter(state)
|
||||||
federatingDB := federatingdb.New(state, typeConverter, visFilter, spamFilter)
|
federatingDB := federatingdb.New(state, typeConverter, visFilter, intFilter, spamFilter)
|
||||||
transportController := transport.NewController(state, federatingDB, &federation.Clock{}, client)
|
transportController := transport.NewController(state, federatingDB, &federation.Clock{}, client)
|
||||||
federator := federation.NewFederator(
|
federator := federation.NewFederator(
|
||||||
state,
|
state,
|
||||||
|
|
|
@ -445,42 +445,106 @@ func (f *federatingDB) activityFollow(ctx context.Context, asType vocab.Type, re
|
||||||
LIKE HANDLERS
|
LIKE HANDLERS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (f *federatingDB) activityLike(ctx context.Context, asType vocab.Type, receivingAccount *gtsmodel.Account, requestingAccount *gtsmodel.Account) error {
|
func (f *federatingDB) activityLike(
|
||||||
|
ctx context.Context,
|
||||||
|
asType vocab.Type,
|
||||||
|
receivingAcct *gtsmodel.Account,
|
||||||
|
requestingAcct *gtsmodel.Account,
|
||||||
|
) error {
|
||||||
like, ok := asType.(vocab.ActivityStreamsLike)
|
like, ok := asType.(vocab.ActivityStreamsLike)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("activityLike: could not convert type to like")
|
err := gtserror.Newf("could not convert asType %T to ActivityStreamsLike", asType)
|
||||||
|
return gtserror.SetMalformed(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fave, err := f.converter.ASLikeToFave(ctx, like)
|
fave, err := f.converter.ASLikeToFave(ctx, like)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("activityLike: could not convert Like to fave: %w", err)
|
return gtserror.Newf("could not convert Like to fave: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fave.AccountID != requestingAccount.ID {
|
// Ensure requester not trying to
|
||||||
return fmt.Errorf(
|
// Like on someone else's behalf.
|
||||||
"activityLike: requestingAccount %s is not Like actor account %s",
|
if fave.AccountID != requestingAcct.ID {
|
||||||
requestingAccount.URI, fave.Account.URI,
|
text := fmt.Sprintf(
|
||||||
|
"requestingAcct %s is not Like actor account %s",
|
||||||
|
requestingAcct.URI, fave.Account.URI,
|
||||||
)
|
)
|
||||||
|
return gtserror.NewErrorForbidden(errors.New(text), text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !*fave.Status.Local {
|
||||||
|
// Only process likes of local statuses.
|
||||||
|
// TODO: process for remote statuses as well.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure valid Like target for requester.
|
||||||
|
policyResult, err := f.intFilter.StatusLikeable(ctx,
|
||||||
|
requestingAcct,
|
||||||
|
fave.Status,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
err := gtserror.Newf("error seeing if status %s is likeable: %w", fave.Status.ID, err)
|
||||||
|
return gtserror.NewErrorInternalError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if policyResult.Forbidden() {
|
||||||
|
const errText = "requester does not have permission to Like this status"
|
||||||
|
err := gtserror.New(errText)
|
||||||
|
return gtserror.NewErrorForbidden(err, errText)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derive pendingApproval
|
||||||
|
// and preapproved status.
|
||||||
|
var (
|
||||||
|
pendingApproval bool
|
||||||
|
preApproved bool
|
||||||
|
)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case policyResult.WithApproval():
|
||||||
|
// Requester allowed to do
|
||||||
|
// this pending approval.
|
||||||
|
pendingApproval = true
|
||||||
|
|
||||||
|
case policyResult.MatchedOnCollection():
|
||||||
|
// Requester allowed to do this,
|
||||||
|
// but matched on collection.
|
||||||
|
// Preapprove Like and have the
|
||||||
|
// processor send out an Accept.
|
||||||
|
pendingApproval = true
|
||||||
|
preApproved = true
|
||||||
|
|
||||||
|
case policyResult.Permitted():
|
||||||
|
// Requester straight up
|
||||||
|
// permitted to do this,
|
||||||
|
// no need for Accept.
|
||||||
|
pendingApproval = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set appropriate fields
|
||||||
|
// on fave and store it.
|
||||||
fave.ID = id.NewULID()
|
fave.ID = id.NewULID()
|
||||||
|
fave.PendingApproval = &pendingApproval
|
||||||
|
fave.PreApproved = preApproved
|
||||||
|
|
||||||
if err := f.state.DB.PutStatusFave(ctx, fave); err != nil {
|
if err := f.state.DB.PutStatusFave(ctx, fave); err != nil {
|
||||||
if errors.Is(err, db.ErrAlreadyExists) {
|
if errors.Is(err, db.ErrAlreadyExists) {
|
||||||
// The Like already exists in the database, which
|
// The fave already exists in the
|
||||||
// means we've already handled side effects. We can
|
// database, which means we've already
|
||||||
// just return nil here and be done with it.
|
// handled side effects. We can just
|
||||||
|
// return nil here and be done with it.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("activityLike: database error inserting fave: %w", err)
|
return gtserror.Newf("db error inserting fave: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.state.Workers.Federator.Queue.Push(&messages.FromFediAPI{
|
f.state.Workers.Federator.Queue.Push(&messages.FromFediAPI{
|
||||||
APObjectType: ap.ActivityLike,
|
APObjectType: ap.ActivityLike,
|
||||||
APActivityType: ap.ActivityCreate,
|
APActivityType: ap.ActivityCreate,
|
||||||
GTSModel: fave,
|
GTSModel: fave,
|
||||||
Receiving: receivingAccount,
|
Receiving: receivingAcct,
|
||||||
Requesting: requestingAccount,
|
Requesting: requestingAcct,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
"github.com/superseriousbusiness/activity/pub"
|
"github.com/superseriousbusiness/activity/pub"
|
||||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/filter/spam"
|
"github.com/superseriousbusiness/gotosocial/internal/filter/spam"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||||
|
@ -58,6 +59,7 @@ type federatingDB struct {
|
||||||
state *state.State
|
state *state.State
|
||||||
converter *typeutils.Converter
|
converter *typeutils.Converter
|
||||||
visFilter *visibility.Filter
|
visFilter *visibility.Filter
|
||||||
|
intFilter *interaction.Filter
|
||||||
spamFilter *spam.Filter
|
spamFilter *spam.Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,12 +69,14 @@ func New(
|
||||||
state *state.State,
|
state *state.State,
|
||||||
converter *typeutils.Converter,
|
converter *typeutils.Converter,
|
||||||
visFilter *visibility.Filter,
|
visFilter *visibility.Filter,
|
||||||
|
intFilter *interaction.Filter,
|
||||||
spamFilter *spam.Filter,
|
spamFilter *spam.Filter,
|
||||||
) DB {
|
) DB {
|
||||||
fdb := federatingDB{
|
fdb := federatingDB{
|
||||||
state: state,
|
state: state,
|
||||||
converter: converter,
|
converter: converter,
|
||||||
visFilter: visFilter,
|
visFilter: visFilter,
|
||||||
|
intFilter: intFilter,
|
||||||
spamFilter: spamFilter,
|
spamFilter: spamFilter,
|
||||||
}
|
}
|
||||||
return &fdb
|
return &fdb
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
|
"github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/filter/spam"
|
"github.com/superseriousbusiness/gotosocial/internal/filter/spam"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||||
|
@ -31,6 +32,7 @@ func NewTestFederatingDB(state *state.State) federatingdb.DB {
|
||||||
state,
|
state,
|
||||||
typeutils.NewConverter(state),
|
typeutils.NewConverter(state),
|
||||||
visibility.NewFilter(state),
|
visibility.NewFilter(state),
|
||||||
|
interaction.NewFilter(state),
|
||||||
spam.NewFilter(state),
|
spam.NewFilter(state),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue