summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/gotosocial/action/server/server.go2
-rw-r--r--internal/federation/federatingdb/create.go90
-rw-r--r--internal/federation/federatingdb/db.go4
-rw-r--r--testrig/federatingdb.go2
4 files changed, 84 insertions, 14 deletions
diff --git a/cmd/gotosocial/action/server/server.go b/cmd/gotosocial/action/server/server.go
index 8deed6ecc..376ade13d 100644
--- a/cmd/gotosocial/action/server/server.go
+++ b/cmd/gotosocial/action/server/server.go
@@ -213,7 +213,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
visFilter := visibility.NewFilter(state)
intFilter := interaction.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)
federator := federation.NewFederator(
state,
diff --git a/internal/federation/federatingdb/create.go b/internal/federation/federatingdb/create.go
index 2a780ed7c..60232efe3 100644
--- a/internal/federation/federatingdb/create.go
+++ b/internal/federation/federatingdb/create.go
@@ -445,42 +445,106 @@ func (f *federatingDB) activityFollow(ctx context.Context, asType vocab.Type, re
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)
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)
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 {
- return fmt.Errorf(
- "activityLike: requestingAccount %s is not Like actor account %s",
- requestingAccount.URI, fave.Account.URI,
+ // Ensure requester not trying to
+ // Like on someone else's behalf.
+ if fave.AccountID != requestingAcct.ID {
+ 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.PendingApproval = &pendingApproval
+ fave.PreApproved = preApproved
if err := f.state.DB.PutStatusFave(ctx, fave); err != nil {
if errors.Is(err, db.ErrAlreadyExists) {
- // The Like already exists in the database, which
- // means we've already handled side effects. We can
- // just return nil here and be done with it.
+ // The fave already exists in the
+ // database, which means we've already
+ // handled side effects. We can just
+ // return nil here and be done with it.
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{
APObjectType: ap.ActivityLike,
APActivityType: ap.ActivityCreate,
GTSModel: fave,
- Receiving: receivingAccount,
- Requesting: requestingAccount,
+ Receiving: receivingAcct,
+ Requesting: requestingAcct,
})
return nil
diff --git a/internal/federation/federatingdb/db.go b/internal/federation/federatingdb/db.go
index 3388d7a03..ba10ed98b 100644
--- a/internal/federation/federatingdb/db.go
+++ b/internal/federation/federatingdb/db.go
@@ -23,6 +23,7 @@ import (
"github.com/superseriousbusiness/activity/pub"
"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/visibility"
"github.com/superseriousbusiness/gotosocial/internal/state"
@@ -58,6 +59,7 @@ type federatingDB struct {
state *state.State
converter *typeutils.Converter
visFilter *visibility.Filter
+ intFilter *interaction.Filter
spamFilter *spam.Filter
}
@@ -67,12 +69,14 @@ func New(
state *state.State,
converter *typeutils.Converter,
visFilter *visibility.Filter,
+ intFilter *interaction.Filter,
spamFilter *spam.Filter,
) DB {
fdb := federatingDB{
state: state,
converter: converter,
visFilter: visFilter,
+ intFilter: intFilter,
spamFilter: spamFilter,
}
return &fdb
diff --git a/testrig/federatingdb.go b/testrig/federatingdb.go
index 41c5a8ae9..73731abae 100644
--- a/testrig/federatingdb.go
+++ b/testrig/federatingdb.go
@@ -19,6 +19,7 @@ package testrig
import (
"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/visibility"
"github.com/superseriousbusiness/gotosocial/internal/state"
@@ -31,6 +32,7 @@ func NewTestFederatingDB(state *state.State) federatingdb.DB {
state,
typeutils.NewConverter(state),
visibility.NewFilter(state),
+ interaction.NewFilter(state),
spam.NewFilter(state),
)
}