From 171b8c75aef447ffb4ca13a906fb7c78a11f7db8 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 14 Dec 2020 11:29:22 -0800 Subject: [PATCH] use require_POST decorator in inbox --- bookwyrm/incoming.py | 6 +-- bookwyrm/tests/test_incoming.py | 75 ++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index fe521772..734549f4 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -6,6 +6,7 @@ import django.db.utils from django.http import HttpResponse from django.http import HttpResponseBadRequest, HttpResponseNotFound from django.views.decorators.csrf import csrf_exempt +from django.views.decorators.http import require_POST import requests from bookwyrm import activitypub, models, outgoing @@ -15,6 +16,7 @@ from bookwyrm.signatures import Signature @csrf_exempt +@require_POST def inbox(request, username): ''' incoming activitypub events ''' try: @@ -26,11 +28,9 @@ def inbox(request, username): @csrf_exempt +@require_POST def shared_inbox(request): ''' incoming activitypub events ''' - if request.method == 'GET': - return HttpResponseNotFound() - try: resp = request.body activity = json.loads(resp) diff --git a/bookwyrm/tests/test_incoming.py b/bookwyrm/tests/test_incoming.py index 674f69b9..8b226792 100644 --- a/bookwyrm/tests/test_incoming.py +++ b/bookwyrm/tests/test_incoming.py @@ -1,6 +1,10 @@ ''' test incoming activities ''' from unittest.mock import patch + +from django.http import HttpResponseBadRequest, HttpResponseNotAllowed, \ + HttpResponseNotFound from django.test import TestCase +from django.test.client import RequestFactory from bookwyrm import models, incoming @@ -13,7 +17,7 @@ class Incoming(TestCase): 'mouse', 'mouse@mouse.com', 'mouseword', local=True) self.local_user.remote_id = 'http://local.com/user/mouse' self.local_user.save() - with patch('bookwyrm.models.user.get_remote_reviews.delay'): + with patch('bookwyrm.models.user.set_remote_server.delay'): self.remote_user = models.User.objects.create_user( 'rat', 'rat@rat.com', 'ratword', local=False, @@ -26,6 +30,75 @@ class Incoming(TestCase): content='Test status', remote_id='http://local.com/status/1', ) + self.factory = RequestFactory() + + + def test_inbox_invalid_get(self): + ''' shouldn't try to handle if the user is not found ''' + request = self.factory.get('http://www.example.com/') + self.assertIsInstance( + incoming.inbox(request, 'anything'), HttpResponseNotAllowed) + self.assertIsInstance( + incoming.shared_inbox(request), HttpResponseNotAllowed) + + def test_inbox_invalid_user(self): + ''' shouldn't try to handle if the user is not found ''' + request = self.factory.post('http://www.example.com/') + self.assertIsInstance( + incoming.inbox(request, 'fish@tomato.com'), HttpResponseNotFound) + + def test_inbox_invalid_no_object(self): + ''' json is missing "object" field ''' + request = self.factory.post( + self.local_user.shared_inbox, data={}) + self.assertIsInstance( + incoming.shared_inbox(request), HttpResponseBadRequest) + + def test_inbox_invalid_bad_signature(self): + ''' bad request for invalid signature ''' + request = self.factory.post( + self.local_user.shared_inbox, + '{"type": "Test", "object": "exists"}', + content_type='application/json') + with patch('bookwyrm.incoming.has_valid_signature') as mock_has_valid: + mock_has_valid.return_value = False + self.assertEqual( + incoming.shared_inbox(request).status_code, 401) + + def test_inbox_invalid_bad_signature_delete(self): + ''' invalid signature for Delete is okay though ''' + request = self.factory.post( + self.local_user.shared_inbox, + '{"type": "Delete", "object": "exists"}', + content_type='application/json') + with patch('bookwyrm.incoming.has_valid_signature') as mock_has_valid: + mock_has_valid.return_value = False + self.assertEqual( + incoming.shared_inbox(request).status_code, 200) + + def test_inbox_unknown_type(self): + ''' never heard of that activity type, don't have a handler for it ''' + request = self.factory.post( + self.local_user.shared_inbox, + '{"type": "Fish", "object": "exists"}', + content_type='application/json') + with patch('bookwyrm.incoming.has_valid_signature') as mock_has_valid: + mock_has_valid.return_value = True + self.assertIsInstance( + incoming.shared_inbox(request), HttpResponseNotFound) + + def test_inbox_success(self): + ''' a known type, for which we start a task ''' + request = self.factory.post( + self.local_user.shared_inbox, + '{"type": "Accept", "object": "exists"}', + content_type='application/json') + with patch('bookwyrm.incoming.has_valid_signature') as mock_has_valid: + mock_has_valid.return_value = True + + with patch('bookwyrm.incoming.handle_follow_accept.delay'): + self.assertEqual( + incoming.shared_inbox(request).status_code, 200) def test_handle_follow(self):