From d81bfb6573b8bca275e9dea578615d29abfe9fdc Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 16 Feb 2021 16:35:28 -0800 Subject: [PATCH] Fixes unfollow --- bookwyrm/activitypub/base_activity.py | 7 ++-- bookwyrm/activitypub/verbs.py | 8 ++++- bookwyrm/models/relationship.py | 2 +- bookwyrm/tests/views/test_inbox.py | 49 ++++++++++++++++++--------- bookwyrm/views/inbox.py | 2 +- 5 files changed, 47 insertions(+), 21 deletions(-) diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index db6cdc941..008d30877 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -85,11 +85,14 @@ class ActivityObject: # figure out the right model -- wish I had a better way for this model = model or get_model_from_type(self.type) - if hasattr(model, 'ignore_activity') and model.ignore_activity(self): - return instance + # only reject statuses if we're potentially creating them + if allow_create and \ + hasattr(model, 'ignore_activity') and model.ignore_activity(self): + return None # check for an existing instance instance = instance or model.find_existing(self.serialize()) + if not instance and not allow_create: # so that we don't create when we want to delete or update return None diff --git a/bookwyrm/activitypub/verbs.py b/bookwyrm/activitypub/verbs.py index 300e1bf35..aa6e7eee9 100644 --- a/bookwyrm/activitypub/verbs.py +++ b/bookwyrm/activitypub/verbs.py @@ -1,6 +1,7 @@ ''' undo wrapper activity ''' from dataclasses import dataclass from typing import List +from django.apps import apps from .base_activity import ActivityObject, Signature, resolve_remote_id from .book import Edition @@ -59,7 +60,12 @@ class Undo(Verb): def action(self): ''' find and remove the activity object ''' - obj = self.object.to_model(save=False, allow_create=False) + # this is so hacky but it does make it work.... + # (because you Reject a request and Undo a follow + model = None + if self.object.type == 'Follow': + model = apps.get_model('bookwyrm.UserFollows') + obj = self.object.to_model(model=model, save=False, allow_create=False) obj.delete() diff --git a/bookwyrm/models/relationship.py b/bookwyrm/models/relationship.py index cdeebc86d..722f0fac4 100644 --- a/bookwyrm/models/relationship.py +++ b/bookwyrm/models/relationship.py @@ -56,7 +56,7 @@ class UserRelationship(BookWyrmModel): return '%s#%s/%d' % (base_path, status, self.id) -class UserFollows(UserRelationship): +class UserFollows(ActivitypubMixin, UserRelationship): ''' Following a user ''' status = 'follows' diff --git a/bookwyrm/tests/views/test_inbox.py b/bookwyrm/tests/views/test_inbox.py index d2e28380c..2e677cbf3 100644 --- a/bookwyrm/tests/views/test_inbox.py +++ b/bookwyrm/tests/views/test_inbox.py @@ -42,7 +42,7 @@ class Inbox(TestCase): 'type': 'Create', 'actor': 'hi', "to": [ - "https://www.w3.org/ns/activitystreams#Public" + "https://www.w3.org/ns/activitystreams#public" ], "cc": [ "https://example.com/user/mouse/followers" @@ -296,19 +296,23 @@ class Inbox(TestCase): def test_handle_unfollow(self): ''' remove a relationship ''' + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): + rel = models.UserFollows.objects.create( + user_subject=self.remote_user, user_object=self.local_user) activity = { "type": "Undo", + "id": "bleh", + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "cc": ["https://example.com/user/mouse/followers"], + 'actor': self.remote_user.remote_id, "@context": "https://www.w3.org/ns/activitystreams", "object": { - "id": "https://example.com/users/rat/follows/123", + "id": rel.remote_id, "type": "Follow", "actor": "https://example.com/users/rat", "object": "https://example.com/user/mouse" } } - with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): - models.UserFollows.objects.create( - user_subject=self.remote_user, user_object=self.local_user) self.assertEqual(self.remote_user, self.local_user.followers.first()) views.inbox.activity_task(activity) @@ -493,13 +497,16 @@ class Inbox(TestCase): activity = { 'id': 'https://example.com/fav/1#undo', 'type': 'Undo', + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "cc": ["https://example.com/user/mouse/followers"], + 'actor': self.remote_user.remote_id, 'object': { '@context': 'https://www.w3.org/ns/activitystreams', 'id': 'https://example.com/fav/1', 'actor': 'https://example.com/users/rat', 'type': 'Like', 'published': 'Mon, 25 May 2020 19:31:20 GMT', - 'object': 'https://example.com/fav/1', + 'object': self.status.remote_id, } } models.Favorite.objects.create( @@ -557,17 +564,21 @@ class Inbox(TestCase): def test_handle_unboost(self): ''' undo a boost ''' + boost = models.Boost.objects.create( + boosted_status=self.status, user=self.remote_user) activity = { 'type': 'Undo', + 'actor': 'hi', + 'id': 'bleh', + "to": ["https://www.w3.org/ns/activitystreams#public"], + "cc": ["https://example.com/user/mouse/followers"], 'object': { 'type': 'Announce', - 'id': '%s/boost' % self.status.remote_id, + 'id': boost.remote_id, 'actor': self.local_user.remote_id, - 'object': self.status.to_activity(), + 'object': self.status.remote_id, } } - models.Boost.objects.create( - boosted_status=self.status, user=self.remote_user) views.inbox.activity_task(activity) @@ -695,12 +706,18 @@ class Inbox(TestCase): self.assertEqual(block.user_subject, self.remote_user) self.assertEqual(block.user_object, self.local_user) - activity = {'type': 'Undo', 'object': { - "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://example.com/9e1f41ac-9ddd-4159", - "type": "Block", - "actor": "https://example.com/users/rat", - "object": "https://example.com/user/mouse" + activity = { + 'type': 'Undo', + 'actor': 'hi', + 'id': 'bleh', + "to": ["https://www.w3.org/ns/activitystreams#public"], + "cc": ["https://example.com/user/mouse/followers"], + 'object': { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://example.com/9e1f41ac-9ddd-4159", + "type": "Block", + "actor": "https://example.com/users/rat", + "object": "https://example.com/user/mouse" }} views.inbox.activity_task(activity) self.assertFalse(models.UserBlocks.objects.exists()) diff --git a/bookwyrm/views/inbox.py b/bookwyrm/views/inbox.py index 6e7b036b3..58356e1c6 100644 --- a/bookwyrm/views/inbox.py +++ b/bookwyrm/views/inbox.py @@ -56,7 +56,7 @@ def activity_task(activity_json): try: activity = activitypub.parse(activity_json) except activitypub.ActivitySerializerError: - return + raise#return # cool that worked, now we should do the action described by the type # (create, update, delete, etc)