Tests for remote feeds

This commit is contained in:
Pedro Ferreira 2017-08-05 19:32:01 +02:00
parent e2ec8313dc
commit 778f74200a
2 changed files with 80 additions and 13 deletions

View File

@ -48,6 +48,9 @@ class Message(object):
def __init__(self, feed, content, signature, sequence=1, timestamp=None, previous=None): def __init__(self, feed, content, signature, sequence=1, timestamp=None, previous=None):
self.feed = feed self.feed = feed
self.content = content self.content = content
if signature is None:
raise ValueError("signature can't be None")
self.signature = signature self.signature = signature
self.previous = previous self.previous = previous
@ -93,11 +96,23 @@ class Message(object):
class LocalMessage(Message): class LocalMessage(Message):
def __init__(self, feed, content, signature=None, sequence=1, timestamp=None, previous=None): def __init__(self, feed, content, signature=None, sequence=1, timestamp=None, previous=None):
super(LocalMessage, self).__init__(feed, content, signature, sequence, timestamp, previous) self.feed = feed
if signature is None: self.content = content
self.signature = self.sign()
def sign(self): self.previous = previous
if self.previous:
self.sequence = self.previous.sequence + 1
else:
self.sequence = sequence
self.timestamp = int(time.time() * 1000) if timestamp is None else timestamp
if signature is None:
self.signature = self._sign()
else:
self.signature = signature
def _sign(self):
# ensure ordering of keys and indentation of 2 characters, like ssb-keys # ensure ordering of keys and indentation of 2 characters, like ssb-keys
data = dumps(self.to_dict(add_signature=False), indent=2) data = dumps(self.to_dict(add_signature=False), indent=2)
return (b64encode(bytes(self.feed.sign(data.encode('ascii')))) + b'.sig.ed25519').decode('ascii') return (b64encode(bytes(self.feed.sign(data.encode('ascii')))) + b'.sig.ed25519').decode('ascii')

View File

@ -2,18 +2,24 @@ from base64 import b64decode
from collections import OrderedDict from collections import OrderedDict
import pytest import pytest
from nacl.signing import SigningKey from nacl.signing import SigningKey, VerifyKey
from ssb.feed import LocalMessage, LocalFeed from ssb.feed import LocalMessage, LocalFeed, Feed, Message, NoPrivateKeyException
@pytest.fixture() @pytest.fixture()
def feed(): def local_feed():
secret = b64decode('Mz2qkNOP2K6upnqibWrR+z8pVUI1ReA1MLc7QMtF2qQ=') secret = b64decode('Mz2qkNOP2K6upnqibWrR+z8pVUI1ReA1MLc7QMtF2qQ=')
return LocalFeed(SigningKey(secret)) return LocalFeed(SigningKey(secret))
def test_feed(): @pytest.fixture()
def remote_feed():
public = b64decode('I/4cyN/jPBbDsikbHzAEvmaYlaJK33lW3UhWjNXjyrU=')
return Feed(VerifyKey(public))
def test_local_feed():
secret = b64decode('Mz2qkNOP2K6upnqibWrR+z8pVUI1ReA1MLc7QMtF2qQ=') secret = b64decode('Mz2qkNOP2K6upnqibWrR+z8pVUI1ReA1MLc7QMtF2qQ=')
feed = LocalFeed(SigningKey(secret)) feed = LocalFeed(SigningKey(secret))
assert bytes(feed.private_key) == secret assert bytes(feed.private_key) == secret
@ -21,10 +27,17 @@ def test_feed():
assert feed.id == '@I/4cyN/jPBbDsikbHzAEvmaYlaJK33lW3UhWjNXjyrU=.ed25519' assert feed.id == '@I/4cyN/jPBbDsikbHzAEvmaYlaJK33lW3UhWjNXjyrU=.ed25519'
def test_message(feed): def test_remote_feed():
m1 = LocalMessage(feed, OrderedDict([ public = b64decode('I/4cyN/jPBbDsikbHzAEvmaYlaJK33lW3UhWjNXjyrU=')
feed = Feed(VerifyKey(public))
assert bytes(feed.public_key) == public
assert feed.id == '@I/4cyN/jPBbDsikbHzAEvmaYlaJK33lW3UhWjNXjyrU=.ed25519'
def test_local_message(local_feed):
m1 = LocalMessage(local_feed, OrderedDict([
('type', 'about'), ('type', 'about'),
('about', feed.id), ('about', local_feed.id),
('name', 'neo'), ('name', 'neo'),
('description', 'The Chosen One') ('description', 'The Chosen One')
]), timestamp=1495706260190) ]), timestamp=1495706260190)
@ -35,9 +48,9 @@ def test_message(feed):
'lPsQ9P10OgeyH6u0unFgiI2wV/RQ7Q2x2ebxnXYCzsJ055TBMXphRADTKhOMS2EkUxXQ9k3amj5fnWPudGxwBQ==.sig.ed25519' 'lPsQ9P10OgeyH6u0unFgiI2wV/RQ7Q2x2ebxnXYCzsJ055TBMXphRADTKhOMS2EkUxXQ9k3amj5fnWPudGxwBQ==.sig.ed25519'
assert m1.key == '%xRDqws/TrQmOd4aEwZ32jdLhP873ZKjIgHlggPR0eoo=.sha256' assert m1.key == '%xRDqws/TrQmOd4aEwZ32jdLhP873ZKjIgHlggPR0eoo=.sha256'
m2 = LocalMessage(feed, OrderedDict([ m2 = LocalMessage(local_feed, OrderedDict([
('type', 'about'), ('type', 'about'),
('about', feed.id), ('about', local_feed.id),
('name', 'morpheus'), ('name', 'morpheus'),
('description', 'Dude with big jaw') ('description', 'Dude with big jaw')
]), previous=m1, timestamp=1495706447426) ]), previous=m1, timestamp=1495706447426)
@ -47,3 +60,42 @@ def test_message(feed):
assert m2.signature == \ assert m2.signature == \
'3SY85LX6/ppOfP4SbfwZbKfd6DccbLRiB13pwpzbSK0nU52OEJxOqcJ2Uensr6RkrWztWLIq90sNOn1zRAoOAw==.sig.ed25519' '3SY85LX6/ppOfP4SbfwZbKfd6DccbLRiB13pwpzbSK0nU52OEJxOqcJ2Uensr6RkrWztWLIq90sNOn1zRAoOAw==.sig.ed25519'
assert m2.key == '%nx13uks5GUwuKJC49PfYGMS/1pgGTtwwdWT7kbVaroM=.sha256' assert m2.key == '%nx13uks5GUwuKJC49PfYGMS/1pgGTtwwdWT7kbVaroM=.sha256'
def test_remote_message(remote_feed):
signature = 'lPsQ9P10OgeyH6u0unFgiI2wV/RQ7Q2x2ebxnXYCzsJ055TBMXphRADTKhOMS2EkUxXQ9k3amj5fnWPudGxwBQ==.sig.ed25519'
m1 = Message(remote_feed, OrderedDict([
('type', 'about'),
('about', remote_feed.id),
('name', 'neo'),
('description', 'The Chosen One')
]), signature, timestamp=1495706260190)
assert m1.timestamp == 1495706260190
assert m1.previous is None
assert m1.sequence == 1
assert m1.signature == signature
assert m1.key == '%xRDqws/TrQmOd4aEwZ32jdLhP873ZKjIgHlggPR0eoo=.sha256'
signature = '3SY85LX6/ppOfP4SbfwZbKfd6DccbLRiB13pwpzbSK0nU52OEJxOqcJ2Uensr6RkrWztWLIq90sNOn1zRAoOAw==.sig.ed25519'
m2 = Message(remote_feed, OrderedDict([
('type', 'about'),
('about', remote_feed.id),
('name', 'morpheus'),
('description', 'Dude with big jaw')
]), signature, previous=m1, timestamp=1495706447426)
assert m2.timestamp == 1495706447426
assert m2.previous is m1
assert m2.sequence == 2
assert m2.signature == signature
m2.verify(signature)
assert m2.key == '%nx13uks5GUwuKJC49PfYGMS/1pgGTtwwdWT7kbVaroM=.sha256'
def test_remote_no_signature(remote_feed):
with pytest.raises(ValueError):
Message(remote_feed, OrderedDict([
('type', 'about'),
('about', remote_feed.id),
('name', 'neo'),
('description', 'The Chosen One')
]), None, timestamp=1495706260190)