Add tests for remote actors (fetch keys via http.)

This commit is contained in:
Adam Kelly 2020-05-13 12:26:07 +01:00
parent 3236e95ea2
commit 4974fe4e5b
2 changed files with 52 additions and 4 deletions

View File

@ -1,5 +1,11 @@
from collections import namedtuple
from urllib.parse import urlsplit from urllib.parse import urlsplit
from Crypto import Random
from Crypto.PublicKey import RSA
import responses
from django.test import TestCase, Client from django.test import TestCase, Client
from django.utils.http import http_date 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.activitypub import get_follow_request
from fedireads.settings import DOMAIN from fedireads.settings import DOMAIN
Sender = namedtuple('Sender', ('actor', 'private_key', 'public_key'))
class Signature(TestCase): class Signature(TestCase):
def setUp(self): def setUp(self):
self.mouse = User.objects.create_user('mouse', 'mouse@example.com', '') self.mouse = User.objects.create_user('mouse', 'mouse@example.com', '')
self.rat = User.objects.create_user('rat', 'rat@example.com', '') self.rat = User.objects.create_user('rat', 'rat@example.com', '')
self.cat = User.objects.create_user('cat', 'cat@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() c = Client()
return c.post( return c.post(
urlsplit(self.rat.inbox).path, urlsplit(self.rat.inbox).path,
data=get_follow_request( data=get_follow_request(
self.mouse, sender,
self.rat, self.rat,
), ),
content_type='application/json', content_type='application/json',
@ -34,7 +53,7 @@ class Signature(TestCase):
def test_correct_signature(self): def test_correct_signature(self):
now = http_date() now = http_date()
signature = make_signature(self.mouse, self.rat.inbox, now) 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): def test_wrong_signature(self):
''' Messages must be signed by the right actor. ''' Messages must be signed by the right actor.
@ -42,4 +61,32 @@ class Signature(TestCase):
''' '''
now = http_date() now = http_date()
signature = make_signature(self.cat, self.rat.inbox, now) 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

View File

@ -10,3 +10,4 @@ pycryptodome==3.9.4
python-dateutil==2.8.1 python-dateutil==2.8.1
redis==3.4.1 redis==3.4.1
requests==2.22.0 requests==2.22.0
responses==0.10.14