From 6e09d485c4395a970a3ee28c106973c5dc4658bc Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 23 Feb 2021 11:34:15 -0800 Subject: [PATCH] Outbox sensitive to user agent strings --- bookwyrm/models/activitypub_mixin.py | 6 ++--- bookwyrm/tests/views/test_helpers.py | 6 ++--- bookwyrm/tests/views/test_outbox.py | 37 ++++++++++++++++++++++++++++ bookwyrm/views/feed.py | 4 +-- bookwyrm/views/helpers.py | 4 +-- bookwyrm/views/outbox.py | 7 +++++- 6 files changed, 53 insertions(+), 11 deletions(-) diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index 84293725..d934681e 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -282,7 +282,7 @@ class OrderedCollectionPageMixin(ObjectMixin): def to_ordered_collection(self, queryset, \ remote_id=None, page=False, collection_only=False, **kwargs): - ''' an ordered collection of whatevers ''' + 'pure=pure, '' an ordered collection of whatevers ''' if not queryset.ordered: raise RuntimeError('queryset must be ordered') @@ -472,7 +472,7 @@ def sign_and_send(sender, data, destination): # pylint: disable=unused-argument def to_ordered_collection_page( - queryset, remote_id, id_only=False, page=1, **kwargs): + queryset, remote_id, id_only=False, page=1, pure=False, **kwargs): ''' serialize and pagiante a queryset ''' paginated = Paginator(queryset, PAGE_LENGTH) @@ -480,7 +480,7 @@ def to_ordered_collection_page( if id_only: items = [s.remote_id for s in activity_page.object_list] else: - items = [s.to_activity() for s in activity_page.object_list] + items = [s.to_activity(pure=pure) for s in activity_page.object_list] prev_page = next_page = None if activity_page.has_next(): diff --git a/bookwyrm/tests/views/test_helpers.py b/bookwyrm/tests/views/test_helpers.py index b75d61d5..b3a79b32 100644 --- a/bookwyrm/tests/views/test_helpers.py +++ b/bookwyrm/tests/views/test_helpers.py @@ -188,18 +188,18 @@ class ViewsHelpers(TestCase): def test_is_bookwyrm_request(self): ''' checks if a request came from a bookwyrm instance ''' request = self.factory.get('', {'q': 'Test Book'}) - self.assertFalse(views.helpers.is_bookworm_request(request)) + self.assertFalse(views.helpers.is_bookwyrm_request(request)) request = self.factory.get( '', {'q': 'Test Book'}, HTTP_USER_AGENT=\ "http.rb/4.4.1 (Mastodon/3.3.0; +https://mastodon.social/)" ) - self.assertFalse(views.helpers.is_bookworm_request(request)) + self.assertFalse(views.helpers.is_bookwyrm_request(request)) request = self.factory.get( '', {'q': 'Test Book'}, HTTP_USER_AGENT=USER_AGENT) - self.assertTrue(views.helpers.is_bookworm_request(request)) + self.assertTrue(views.helpers.is_bookwyrm_request(request)) def test_existing_user(self): diff --git a/bookwyrm/tests/views/test_outbox.py b/bookwyrm/tests/views/test_outbox.py index d59f028c..7986dea6 100644 --- a/bookwyrm/tests/views/test_outbox.py +++ b/bookwyrm/tests/views/test_outbox.py @@ -7,6 +7,7 @@ from django.test import TestCase from django.test.client import RequestFactory from bookwyrm import models, views +from bookwyrm.settings import USER_AGENT # pylint: disable=too-many-public-methods @@ -90,3 +91,39 @@ class OutboxView(TestCase): data = json.loads(result.content) self.assertEqual(data['type'], 'OrderedCollection') self.assertEqual(data['totalItems'], 1) + + def test_outbox_bookwyrm_request_true(self): + ''' should differentiate between bookwyrm and outside requests ''' + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): + models.Review.objects.create( + name='hi', + content='look at this', + user=self.local_user, + book=self.book, + privacy='public', + ) + + request = self.factory.get('', {'page': 1}, HTTP_USER_AGENT=USER_AGENT) + result = views.Outbox.as_view()(request, 'mouse') + + data = json.loads(result.content) + self.assertEqual(len(data['orderedItems']), 1) + self.assertEqual(data['orderedItems'][0]['type'], 'Review') + + def test_outbox_bookwyrm_request_false(self): + ''' should differentiate between bookwyrm and outside requests ''' + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): + models.Review.objects.create( + name='hi', + content='look at this', + user=self.local_user, + book=self.book, + privacy='public', + ) + + request = self.factory.get('', {'page': 1}) + result = views.Outbox.as_view()(request, 'mouse') + + data = json.loads(result.content) + self.assertEqual(len(data['orderedItems']), 1) + self.assertEqual(data['orderedItems'][0]['type'], 'Article') diff --git a/bookwyrm/views/feed.py b/bookwyrm/views/feed.py index 0e550f0c..059237b9 100644 --- a/bookwyrm/views/feed.py +++ b/bookwyrm/views/feed.py @@ -13,7 +13,7 @@ from bookwyrm.activitypub import ActivitypubResponse from bookwyrm.settings import PAGE_LENGTH from .helpers import get_activity_feed from .helpers import get_user_from_username -from .helpers import is_api_request, is_bookworm_request, object_visible_to_user +from .helpers import is_api_request, is_bookwyrm_request, object_visible_to_user # pylint: disable= no-self-use @@ -107,7 +107,7 @@ class Status(View): if is_api_request(request): return ActivitypubResponse( - status.to_activity(pure=not is_bookworm_request(request))) + status.to_activity(pure=not is_bookwyrm_request(request))) data = {**feed_page_data(request.user), **{ 'title': 'Status by %s' % user.username, diff --git a/bookwyrm/views/helpers.py b/bookwyrm/views/helpers.py index 842b8d1c..6eeaa926 100644 --- a/bookwyrm/views/helpers.py +++ b/bookwyrm/views/helpers.py @@ -24,8 +24,8 @@ def is_api_request(request): request.path[-5:] == '.json' -def is_bookworm_request(request): - ''' check if the request is coming from another bookworm instance ''' +def is_bookwyrm_request(request): + ''' check if the request is coming from another bookwyrm instance ''' user_agent = request.headers.get('User-Agent') if user_agent is None or \ re.search(regex.bookwyrm_user_agent, user_agent) is None: diff --git a/bookwyrm/views/outbox.py b/bookwyrm/views/outbox.py index 8bfc3b3d..5df9d199 100644 --- a/bookwyrm/views/outbox.py +++ b/bookwyrm/views/outbox.py @@ -4,6 +4,7 @@ from django.shortcuts import get_object_or_404 from django.views import View from bookwyrm import activitypub, models +from .helpers import is_bookwyrm_request # pylint: disable= no-self-use @@ -17,6 +18,10 @@ class Outbox(View): filter_type = None return JsonResponse( - user.to_outbox(**request.GET, filter_type=filter_type), + user.to_outbox( + **request.GET, + filter_type=filter_type, + pure=not is_bookwyrm_request(request) + ), encoder=activitypub.ActivityEncoder )