bookwyrm/fedireads/tests/test_signing.py

93 lines
3 KiB
Python
Raw Normal View History

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
from fedireads.models import User
from fedireads.broadcast import make_signature
from fedireads.activitypub import get_follow_request
from fedireads.settings import DOMAIN
2020-05-14 01:23:54 +00:00
Sender = namedtuple('Sender', ('remote_id', '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', '')
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(
sender,
self.rat,
),
content_type='application/json',
**{
'HTTP_DATE': now,
'HTTP_SIGNATURE': signature,
'HTTP_CONTENT_TYPE': 'application/activity+json; charset=utf-8',
'HTTP_HOST': DOMAIN,
}
)
def test_correct_signature(self):
now = http_date()
signature = make_signature(self.mouse, self.rat.inbox, now)
return self.send_follow(self.mouse, signature, now).status_code == 200
def test_wrong_signature(self):
''' Messages must be signed by the right actor.
(cat cannot sign messages on behalf of mouse)
'''
now = http_date()
signature = make_signature(self.cat, self.rat.inbox, now)
assert self.send_follow(self.mouse, signature, now).status_code == 401
@responses.activate
def test_remote_signer(self):
responses.add(
responses.GET,
2020-05-14 01:23:54 +00:00
self.fake_remote.remote_id,
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,
2020-05-14 01:23:54 +00:00
self.fake_remote.remote_id,
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