Make to_user optional in handle_create_payload

Public content does not require a recipient.
merge-requests/130/head
Jason Robinson 2016-09-05 22:08:13 +03:00
rodzic b2011b3fac
commit c8f436cd4e
5 zmienionych plików z 26 dodań i 16 usunięć

Wyświetl plik

@ -1,3 +1,9 @@
## [unreleased]
## Breaking changes
- `federation.outbound.handle_create_payload` parameter `to_user` is now optional. Public posts don't need a recipient. This also affects Diaspora protocol `build_send` method where the change is reflected similarly. [#43](https://github.com/jaywink/social-federation/pull/43)
- In practise this means the signature has changed for `handle_create_payload` and `build_send` from **`from_user, to_user, entity`** to **`entity, from_user, to_user=None`**.
## [0.4.1] - 2016-09-04
## Fixes

Wyświetl plik

@ -3,16 +3,16 @@ from federation.entities.diaspora.mappers import get_outbound_entity
from federation.protocols.diaspora.protocol import Protocol
def handle_create_payload(from_user, to_user, entity):
def handle_create_payload(entity, from_user, to_user=None):
"""Create a payload with the correct protocol.
Since we don't know the protocol, we need to first query the recipient. However, for a PoC implementation,
supporting only Diaspora, we're going to assume that for now.
Args:
from_user (obj) - User sending the object
to_user (obj) - Contact entry to send to
entity (obj) - Entity object to send
from_user (obj) - User sending the object
to_user (obj) - Contact entry to send to (required for non-public content)
`from_user` must have `private_key` and `handle` attributes.
`to_user` must have `key` attribute.
@ -20,5 +20,5 @@ def handle_create_payload(from_user, to_user, entity):
# Just use Diaspora protocol for now
protocol = Protocol()
outbound_entity = get_outbound_entity(entity)
data = protocol.build_send(from_user=from_user, to_user=to_user, entity=outbound_entity)
data = protocol.build_send(entity=outbound_entity, from_user=from_user, to_user=to_user)
return data

Wyświetl plik

@ -182,11 +182,11 @@ class Protocol(BaseProtocol):
else:
return data[0:-data[-1]]
def build_send(self, from_user, to_user, entity, *args, **kwargs):
def build_send(self, entity, from_user, to_user=None, *args, **kwargs):
"""Build POST data for sending out to remotes."""
xml = entity.to_xml()
self.init_message(xml, from_user.handle, from_user.private_key)
xml = self.create_salmon_envelope(to_user.key)
xml = self.create_salmon_envelope(to_user)
return {'xml': xml}
def init_message(self, message, author_username, private_key):
@ -319,25 +319,31 @@ class Protocol(BaseProtocol):
to_encrypt = self.pkcs7_pad(self.create_payload(), AES.block_size)
return self.inner_encrypter.encrypt(to_encrypt)
def create_salmon_envelope(self, recipient_public_key):
def create_salmon_envelope(self, recipient):
"""
Build the whole message, pulling together the encrypted payload and the
encrypted header. Selected elements are signed by the author so that
tampering can be detected.
Args:
recipient - Recipient object which must have public key as `key`
Returns:
XML document as string
"""
nsmap = {
None: PROTOCOL_NS,
'me': 'http://salmon-protocol.org/ns/magic-env'
}
doc = etree.Element("{%s}diaspora" % nsmap[None], nsmap=nsmap)
if recipient_public_key:
doc.append(self.create_encrypted_header(recipient_public_key))
if recipient:
doc.append(self.create_encrypted_header(recipient.key))
else:
doc.append(self.create_public_header())
env = etree.SubElement(doc, "{%s}env" % nsmap["me"])
etree.SubElement(env, "{%s}encoding" % nsmap["me"]).text = 'base64url'
etree.SubElement(env, "{%s}alg" % nsmap["me"]).text = 'RSA-SHA256'
if recipient_public_key:
if recipient:
payload = urlsafe_b64encode(b64encode(
self.create_encrypted_payload())).decode("ascii")
else:

Wyświetl plik

@ -150,6 +150,6 @@ class TestDiasporaProtocol(DiasporaTestBase):
mock_entity_xml = Mock()
entity = Mock(to_xml=Mock(return_value=mock_entity_xml))
from_user = Mock(handle="foobar", private_key="barfoo")
data = protocol.build_send(from_user, Mock(), entity)
data = protocol.build_send(entity, from_user)
mock_init_message.assert_called_once_with(mock_entity_xml, from_user.handle, from_user.private_key)
assert data == {"xml": "xmldata"}

Wyświetl plik

@ -13,16 +13,14 @@ class TestHandleCreatePayloadBuildsAPayload(object):
mock_protocol = Mock()
mock_protocol_class.return_value = mock_protocol
from_user = Mock()
to_user = Mock()
entity = DiasporaPost()
handle_create_payload(from_user, to_user, entity)
mock_protocol.build_send.assert_called_once_with(from_user=from_user, to_user=to_user, entity=entity)
handle_create_payload(entity, from_user)
mock_protocol.build_send.assert_called_once_with(entity=entity, from_user=from_user, to_user=None)
@patch("federation.outbound.get_outbound_entity")
def test_handle_create_payload_calls_get_outbound_entity(self, mock_get_outbound_entity):
mock_get_outbound_entity.return_value = DiasporaPost()
from_user = Mock(private_key=RSA.generate(2048), handle="foobar@domain.tld")
to_user = Mock(key=RSA.generate(2048).publickey())
entity = DiasporaPost()
handle_create_payload(from_user, to_user, entity)
handle_create_payload(entity, from_user)
assert mock_get_outbound_entity.called