kopia lustrzana https://gitlab.com/jaywink/federation
Make to_user optional in handle_create_payload
Public content does not require a recipient.merge-requests/130/head
rodzic
b2011b3fac
commit
c8f436cd4e
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue