use require_POST decorator in inbox

This commit is contained in:
Mouse Reeve 2020-12-14 11:29:22 -08:00
parent 7f6390f722
commit 171b8c75ae
2 changed files with 77 additions and 4 deletions

View file

@ -6,6 +6,7 @@ import django.db.utils
from django.http import HttpResponse from django.http import HttpResponse
from django.http import HttpResponseBadRequest, HttpResponseNotFound from django.http import HttpResponseBadRequest, HttpResponseNotFound
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
import requests import requests
from bookwyrm import activitypub, models, outgoing from bookwyrm import activitypub, models, outgoing
@ -15,6 +16,7 @@ from bookwyrm.signatures import Signature
@csrf_exempt @csrf_exempt
@require_POST
def inbox(request, username): def inbox(request, username):
''' incoming activitypub events ''' ''' incoming activitypub events '''
try: try:
@ -26,11 +28,9 @@ def inbox(request, username):
@csrf_exempt @csrf_exempt
@require_POST
def shared_inbox(request): def shared_inbox(request):
''' incoming activitypub events ''' ''' incoming activitypub events '''
if request.method == 'GET':
return HttpResponseNotFound()
try: try:
resp = request.body resp = request.body
activity = json.loads(resp) activity = json.loads(resp)

View file

@ -1,6 +1,10 @@
''' test incoming activities ''' ''' test incoming activities '''
from unittest.mock import patch from unittest.mock import patch
from django.http import HttpResponseBadRequest, HttpResponseNotAllowed, \
HttpResponseNotFound
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory
from bookwyrm import models, incoming from bookwyrm import models, incoming
@ -13,7 +17,7 @@ class Incoming(TestCase):
'mouse', 'mouse@mouse.com', 'mouseword', local=True) 'mouse', 'mouse@mouse.com', 'mouseword', local=True)
self.local_user.remote_id = 'http://local.com/user/mouse' self.local_user.remote_id = 'http://local.com/user/mouse'
self.local_user.save() 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( self.remote_user = models.User.objects.create_user(
'rat', 'rat@rat.com', 'ratword', 'rat', 'rat@rat.com', 'ratword',
local=False, local=False,
@ -26,6 +30,75 @@ class Incoming(TestCase):
content='Test status', content='Test status',
remote_id='http://local.com/status/1', 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): def test_handle_follow(self):