From 0c6049b81cd361d76148b3fb82758dbc8e8dfc81 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 18 Dec 2020 12:38:27 -0800 Subject: [PATCH] Discard remote boosts --- bookwyrm/activitypub/base_activity.py | 3 +++ bookwyrm/incoming.py | 23 ++++------------------- bookwyrm/models/status.py | 25 ++++++++++++++++++++++++- bookwyrm/tests/test_incoming.py | 5 ++++- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index 6401bb89a..90101a853 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -74,6 +74,9 @@ class ActivityObject: model.activity_serializer) ) + if hasattr(model, 'ignore_activity') and model.ignore_activity(self): + return instance + # check for an existing instance, if we're not updating a known obj instance = instance or model.find_existing(self.serialize()) or model() diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index c1c15ca93..ddf99f97b 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -197,26 +197,11 @@ def handle_create(activity): # not a type of status we are prepared to deserialize return - if activity.type == 'Note': - # keep notes if they are replies to existing statuses - reply = models.Status.objects.filter( - remote_id=activity.inReplyTo - ).first() - - if not reply: - discard = True - # keep notes if they mention local users - tags = [l['href'] for l in activity.tag if l['type'] == 'Mention'] - for tag in tags: - if models.User.objects.filter( - remote_id=tag, local=True).exists(): - # we found a mention of a known use boost - discard = False - break - if discard: - return - status = activity.to_model(model) + if not status: + # it was discarded because it's not a bookwyrm type + return + # create a notification if this is a reply notified = [] if status.reply_parent and status.reply_parent.user.local: diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index b12173b1d..3162c22b7 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -1,7 +1,9 @@ ''' models for storing different kinds of Activities ''' -from django.utils import timezone +from dataclasses import MISSING +from django.apps import apps from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models +from django.utils import timezone from model_utils.managers import InheritanceManager from bookwyrm import activitypub @@ -46,6 +48,27 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): serialize_reverse_fields = [('attachments', 'attachment')] deserialize_reverse_fields = [('attachments', 'attachment')] + @classmethod + def ignore_activity(cls, activity): + ''' keep notes if they are replies to existing statuses ''' + if activity.type != 'Note': + return False + if cls.objects.filter( + remote_id=activity.inReplyTo).exists(): + return False + + # keep notes if they mention local users + if activity.tag == MISSING or activity.tag is None: + return True + tags = [l['href'] for l in activity.tag if l['type'] == 'Mention'] + for tag in tags: + user_model = apps.get_model('bookwyrm.User', require_ready=True) + if user_model.objects.filter( + remote_id=tag, local=True).exists(): + # we found a mention of a known use boost + return False + return True + @classmethod def replies(cls, status): ''' load all replies to a status. idk if there's a better way diff --git a/bookwyrm/tests/test_incoming.py b/bookwyrm/tests/test_incoming.py index 22f1521be..2cc4c1f44 100644 --- a/bookwyrm/tests/test_incoming.py +++ b/bookwyrm/tests/test_incoming.py @@ -410,7 +410,10 @@ class Incoming(TestCase): 'actor': self.remote_user.remote_id, 'object': self.status.to_activity(), } - incoming.handle_boost(activity) + with patch('bookwyrm.models.status.Status.ignore_activity') \ + as discarder: + discarder.return_value = False + incoming.handle_boost(activity) boost = models.Boost.objects.get() self.assertEqual(boost.boosted_status, self.status) notification = models.Notification.objects.get()