diff --git a/fedireads/tests/test_signing.py b/fedireads/tests/test_signing.py index f4da6033c..6cb69f16f 100644 --- a/fedireads/tests/test_signing.py +++ b/fedireads/tests/test_signing.py @@ -1,5 +1,11 @@ +from collections import namedtuple from urllib.parse import urlsplit +from Crypto import Random +from Crypto.PublicKey import RSA + +import responses + from django.test import TestCase, Client from django.utils.http import http_date @@ -8,18 +14,31 @@ from fedireads.broadcast import make_signature from fedireads.activitypub import get_follow_request from fedireads.settings import DOMAIN +Sender = namedtuple('Sender', ('actor', 'private_key', 'public_key')) + class Signature(TestCase): def setUp(self): self.mouse = User.objects.create_user('mouse', 'mouse@example.com', '') self.rat = User.objects.create_user('rat', 'rat@example.com', '') self.cat = User.objects.create_user('cat', 'cat@example.com', '') - def send_follow(self, signature, now): + random_generator = Random.new().read + key = RSA.generate(1024, random_generator) + private_key = key.export_key().decode('utf8') + public_key = key.publickey().export_key().decode('utf8') + + self.fake_remote = Sender( + 'http://localhost/user/remote', + private_key, + public_key, + ) + + def send_follow(self, sender, signature, now): c = Client() return c.post( urlsplit(self.rat.inbox).path, data=get_follow_request( - self.mouse, + sender, self.rat, ), content_type='application/json', @@ -34,7 +53,7 @@ class Signature(TestCase): def test_correct_signature(self): now = http_date() signature = make_signature(self.mouse, self.rat.inbox, now) - return self.send_follow(signature, now).status_code == 200 + return self.send_follow(self.mouse, signature, now).status_code == 200 def test_wrong_signature(self): ''' Messages must be signed by the right actor. @@ -42,4 +61,32 @@ class Signature(TestCase): ''' now = http_date() signature = make_signature(self.cat, self.rat.inbox, now) - assert self.send_follow(signature, now).status_code == 401 + assert self.send_follow(self.mouse, signature, now).status_code == 401 + + @responses.activate + def test_remote_signer(self): + responses.add( + responses.GET, + self.fake_remote.actor, + json={'publicKey': { + 'publicKeyPem': self.fake_remote.public_key + }}, + status=200) + + now = http_date() + sender = self.fake_remote + signature = make_signature(sender, self.rat.inbox, now) + assert self.send_follow(sender, signature, now).status_code == 200 + + @responses.activate + def test_nonexistent_signer(self): + responses.add( + responses.GET, + self.fake_remote.actor, + json={'error': 'not found'}, + status=404) + + now = http_date() + sender = self.fake_remote + signature = make_signature(sender, self.rat.inbox, now) + assert self.send_follow(sender, signature, now).status_code == 401 diff --git a/requirements.txt b/requirements.txt index 262b6e28a..7c386d2fd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,4 @@ pycryptodome==3.9.4 python-dateutil==2.8.1 redis==3.4.1 requests==2.22.0 +responses==0.10.14