From cc8888dea20bd520a0169549d2a1d0fd7469d4a1 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 23 Jan 2021 11:03:10 -0800 Subject: [PATCH] Adds incoming handler for blocking --- bookwyrm/activitypub/__init__.py | 2 +- bookwyrm/activitypub/verbs.py | 4 ++++ bookwyrm/incoming.py | 18 ++++++++++++++++++ bookwyrm/models/relationship.py | 2 +- bookwyrm/tests/test_incoming.py | 26 ++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/bookwyrm/activitypub/__init__.py b/bookwyrm/activitypub/__init__.py index a4fef41e5..a74397225 100644 --- a/bookwyrm/activitypub/__init__.py +++ b/bookwyrm/activitypub/__init__.py @@ -14,7 +14,7 @@ from .person import Person, PublicKey from .response import ActivitypubResponse from .book import Edition, Work, Author from .verbs import Create, Delete, Undo, Update -from .verbs import Follow, Accept, Reject +from .verbs import Follow, Accept, Reject, Block from .verbs import Add, AddBook, Remove # this creates a list of all the Activity types that we can serialize, diff --git a/bookwyrm/activitypub/verbs.py b/bookwyrm/activitypub/verbs.py index 7c6279279..6977ee8e8 100644 --- a/bookwyrm/activitypub/verbs.py +++ b/bookwyrm/activitypub/verbs.py @@ -48,6 +48,10 @@ class Follow(Verb): ''' Follow activity ''' type: str = 'Follow' +@dataclass(init=False) +class Block(Verb): + ''' Block activity ''' + type: str = 'Block' @dataclass(init=False) class Accept(Verb): diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index 9653c5d23..5d93756f5 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -3,6 +3,7 @@ import json from urllib.parse import urldefrag import django.db.utils +from django.db.models import Q from django.http import HttpResponse from django.http import HttpResponseBadRequest, HttpResponseNotFound from django.views.decorators.csrf import csrf_exempt @@ -51,6 +52,7 @@ def shared_inbox(request): 'Follow': handle_follow, 'Accept': handle_follow_accept, 'Reject': handle_follow_reject, + 'Block': handle_block, 'Create': handle_create, 'Delete': handle_delete_status, 'Like': handle_favorite, @@ -179,6 +181,22 @@ def handle_follow_reject(activity): request.delete() #raises models.UserFollowRequest.DoesNotExist +@app.task +def handle_block(activity): + ''' blocking a user ''' + # create "block" databse entry + block = activitypub.Block(**activity).to_model(models.UserBlocks) + + # remove follow relationships + models.UserFollows.objects.filter( + Q(user_subject=block.user_subject, user_object=block.user_object) | \ + Q(user_subject=block.user_object, user_object=block.user_subject) + ).delete() + models.UserFollowRequest.objects.filter( + Q(user_subject=block.user_subject, user_object=block.user_object) | \ + Q(user_subject=block.user_object, user_object=block.user_subject) + ).delete() + @app.task def handle_create(activity): diff --git a/bookwyrm/models/relationship.py b/bookwyrm/models/relationship.py index 0f3c1dab9..9ea75a8f7 100644 --- a/bookwyrm/models/relationship.py +++ b/bookwyrm/models/relationship.py @@ -94,5 +94,5 @@ class UserFollowRequest(UserRelationship): class UserBlocks(UserRelationship): ''' prevent another user from following you and seeing your posts ''' - # TODO: not implemented status = 'blocks' + activity_serializer = activitypub.Block diff --git a/bookwyrm/tests/test_incoming.py b/bookwyrm/tests/test_incoming.py index 2cd4869e3..024c8e253 100644 --- a/bookwyrm/tests/test_incoming.py +++ b/bookwyrm/tests/test_incoming.py @@ -540,3 +540,29 @@ class Incoming(TestCase): incoming.handle_update_work({'object': bookdata}) book = models.Work.objects.get(id=book.id) self.assertEqual(book.title, 'Piranesi') + + + def test_handle_blocks(self): + ''' create a "block" database entry from an activity ''' + self.local_user.followers.add(self.remote_user) + models.UserFollowRequest.objects.create( + user_subject=self.local_user, + user_object=self.remote_user) + self.assertTrue(models.UserFollows.objects.exists()) + self.assertTrue(models.UserFollowRequest.objects.exists()) + + activity = { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://example.com/9e1f41ac-9ddd-4159-aede-9f43c6b9314f", + "type": "Block", + "actor": "https://example.com/users/rat", + "object": "https://example.com/user/mouse" + } + + incoming.handle_block(activity) + block = models.UserBlocks.objects.get() + self.assertEqual(block.user_subject, self.remote_user) + self.assertEqual(block.user_object, self.local_user) + + self.assertFalse(models.UserFollows.objects.exists()) + self.assertFalse(models.UserFollowRequest.objects.exists())