From 02e6602a0bba359f0160133c24c37a19c657a916 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 17 Apr 2021 17:55:22 -0700 Subject: [PATCH] Reject statuses from deactivated remote users --- bookwyrm/models/activitypub_mixin.py | 6 ++-- bookwyrm/models/user.py | 5 ++++ bookwyrm/tests/views/inbox/test_inbox.py | 29 +++++++++++++++++++ .../tests/views/inbox/test_inbox_create.py | 2 +- bookwyrm/views/inbox.py | 6 ++++ 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index ce6245b2..f687e96c 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -193,7 +193,7 @@ class ObjectMixin(ActivitypubMixin): def save(self, *args, created=None, **kwargs): """ broadcast created/updated/deleted objects as appropriate """ broadcast = kwargs.get("broadcast", True) - # this bonus kwarg woul cause an error in the base save method + # this bonus kwarg would cause an error in the base save method if "broadcast" in kwargs: del kwargs["broadcast"] @@ -241,9 +241,7 @@ class ObjectMixin(ActivitypubMixin): return # is this a deletion? - if (hasattr(self, "deleted") and self.deleted) or ( - hasattr(self, "is_active") and not self.is_active - ): + if hasattr(self, "deleted") and self.deleted: activity = self.to_delete_activity(user) else: activity = self.to_update_activity(user) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 9585a4c4..0f98c82d 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -145,6 +145,11 @@ class User(OrderedCollectionPageMixin, AbstractUser): return self.name return self.localname or self.username + @property + def deleted(self): + """ for consistent naming """ + return not self.is_active + activity_serializer = activitypub.Person @classmethod diff --git a/bookwyrm/tests/views/inbox/test_inbox.py b/bookwyrm/tests/views/inbox/test_inbox.py index 50fb1ecc..c39a3fd2 100644 --- a/bookwyrm/tests/views/inbox/test_inbox.py +++ b/bookwyrm/tests/views/inbox/test_inbox.py @@ -1,5 +1,6 @@ """ tests incoming activities""" import json +import pathlib from unittest.mock import patch from django.http import HttpResponseNotAllowed, HttpResponseNotFound @@ -26,6 +27,16 @@ class Inbox(TestCase): ) local_user.remote_id = "https://example.com/user/mouse" local_user.save(broadcast=False) + with patch("bookwyrm.models.user.set_remote_server.delay"): + self.remote_user = models.User.objects.create_user( + "rat", + "rat@rat.com", + "ratword", + local=False, + remote_id="https://example.com/users/rat", + inbox="https://example.com/users/rat/inbox", + outbox="https://example.com/users/rat/outbox", + ) self.create_json = { "id": "hi", "type": "Create", @@ -131,3 +142,21 @@ class Inbox(TestCase): server_name="mastodon.social", status="blocked" ) self.assertTrue(views.inbox.is_blocked_activity(activity)) + + def test_create_by_deactivated_user(self): + """ don't let deactivated users post """ + self.remote_user.delete(broadcast=False) + self.assertTrue(self.remote_user.deleted) + datafile = pathlib.Path(__file__).parent.joinpath("../../data/ap_note.json") + status_data = json.loads(datafile.read_bytes()) + activity = self.create_json + activity["actor"] = self.remote_user.remote_id + activity["object"] = status_data + + with patch("bookwyrm.views.inbox.has_valid_signature") as mock_valid: + mock_valid.return_value = True + + result = self.client.post( + "/inbox", json.dumps(activity), content_type="application/json" + ) + self.assertEqual(result.status_code, 403) diff --git a/bookwyrm/tests/views/inbox/test_inbox_create.py b/bookwyrm/tests/views/inbox/test_inbox_create.py index 16c674e0..3d2ce1c0 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_create.py +++ b/bookwyrm/tests/views/inbox/test_inbox_create.py @@ -32,7 +32,7 @@ class InboxCreate(TestCase): remote_id="https://example.com/status/1", ) with patch("bookwyrm.models.user.set_remote_server.delay"): - models.User.objects.create_user( + self.remote_user = models.User.objects.create_user( "rat", "rat@rat.com", "ratword", diff --git a/bookwyrm/views/inbox.py b/bookwyrm/views/inbox.py index a8eb4851..c701956d 100644 --- a/bookwyrm/views/inbox.py +++ b/bookwyrm/views/inbox.py @@ -80,6 +80,12 @@ def is_blocked_user_agent(request): def is_blocked_activity(activity_json): """ get the sender out of activity json and check if it's blocked """ actor = activity_json.get("actor") + + # check if the user is banned/deleted + existing = models.User.find_existing_by_remote_id(actor) + if existing and existing.deleted: + return True + if not actor: # well I guess it's not even a valid activity so who knows return False