summaryrefslogtreecommitdiff
path: root/internal/federation/federatingdb/create.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/federation/federatingdb/create.go')
-rw-r--r--internal/federation/federatingdb/create.go90
1 files changed, 77 insertions, 13 deletions
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