diff --git a/CHANGELOG.md b/CHANGELOG.md index 2444415..e769d3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## [unreleased] +## Breaking changes +- While in early stages, doing some renaming of modules to suit the longer term. `federation.controllers` has been split into two, `federation.outbound` and `federation.inbound`. The following methods have new import locations: + * `federation.controllers.handle_receive` -> `federation.inbound.handle_receive` + * `federation.controllers.handle_create_payload` -> `federation.outbound.handle_create_payload` + ## Added - `Relationship` base entity which represents relationships between two handles. Types can be following, sharing, ignoring and blocking. The Diaspora counterpart, `DiasporaRequest`, which represents a sharing/following request is outwards a single entity, but incoming a double entity, handled by creating both a sharing and following version of the relationship. - `Profile` base entity and Diaspora counterpart `DiasporaProfile`. Represents a user profile. diff --git a/federation/controllers.py b/federation/inbound.py similarity index 60% rename from federation/controllers.py rename to federation/inbound.py index 444091d..1010619 100644 --- a/federation/controllers.py +++ b/federation/inbound.py @@ -1,8 +1,6 @@ import importlib -from federation.entities.diaspora.mappers import get_outbound_entity from federation.exceptions import NoSuitableProtocolFoundError -from federation.protocols.diaspora.protocol import Protocol PROTOCOLS = ( "diaspora", @@ -36,24 +34,3 @@ def handle_receive(payload, user=None, sender_key_fetcher=None, skip_author_veri entities = mappers.message_to_objects(message) return sender, found_protocol.PROTOCOL_NAME, entities - - -def handle_create_payload(from_user, to_user, entity): - """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` must have `private_key` and `handle` attributes. - `to_user` must have `key` attribute. - """ - # 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) - return data diff --git a/federation/outbound.py b/federation/outbound.py new file mode 100644 index 0000000..b490a60 --- /dev/null +++ b/federation/outbound.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +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): + """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` must have `private_key` and `handle` attributes. + `to_user` must have `key` attribute. + """ + # 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) + return data diff --git a/federation/tests/test_controllers.py b/federation/tests/test_controllers.py deleted file mode 100644 index cb850cd..0000000 --- a/federation/tests/test_controllers.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -from unittest.mock import patch, Mock -from Crypto.PublicKey import RSA -import pytest - -from federation.controllers import handle_receive, handle_create_payload -from federation.entities.diaspora.entities import DiasporaPost -from federation.exceptions import NoSuitableProtocolFoundError -from federation.protocols.diaspora.protocol import Protocol -from federation.tests.fixtures.payloads import UNENCRYPTED_DIASPORA_PAYLOAD - - -class TestHandleReceiveProtocolIdentification(object): - def test_handle_receive_routes_to_identified_protocol(self): - payload = UNENCRYPTED_DIASPORA_PAYLOAD - with patch.object( - Protocol, - 'receive', - return_value=("foobar@domain.tld", "")) as mock_receive,\ - patch( - "federation.entities.diaspora.mappers.message_to_objects", - return_value=[]) as mock_message_to_objects: - handle_receive(payload) - assert mock_receive.called - - def test_handle_receive_raises_on_unidentified_protocol(self): - payload = "foobar" - with pytest.raises(NoSuitableProtocolFoundError): - handle_receive(payload) - - -class TestHandleCreatePayloadBuildsAPayload(object): - def test_handle_create_payload_builds_an_xml(self): - from_user = Mock(private_key=RSA.generate(2048), handle="foobar@domain.tld") - to_user = Mock(key=RSA.generate(2048).publickey()) - entity = DiasporaPost() - data = handle_create_payload(from_user, to_user, entity) - assert len(data) > 0 - parts = data.split("=") - assert len(parts) == 2 - assert parts[0] == "xml" - assert len(parts[1]) > 0 - - @patch("federation.controllers.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) - assert mock_get_outbound_entity.called - diff --git a/federation/tests/test_inbound.py b/federation/tests/test_inbound.py new file mode 100644 index 0000000..879e7d1 --- /dev/null +++ b/federation/tests/test_inbound.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from unittest.mock import patch + +import pytest + +from federation.exceptions import NoSuitableProtocolFoundError +from federation.inbound import handle_receive +from federation.protocols.diaspora.protocol import Protocol +from federation.tests.fixtures.payloads import UNENCRYPTED_DIASPORA_PAYLOAD + + +class TestHandleReceiveProtocolIdentification(object): + def test_handle_receive_routes_to_identified_protocol(self): + payload = UNENCRYPTED_DIASPORA_PAYLOAD + with patch.object( + Protocol, + 'receive', + return_value=("foobar@domain.tld", "")) as mock_receive,\ + patch( + "federation.entities.diaspora.mappers.message_to_objects", + return_value=[]) as mock_message_to_objects: + handle_receive(payload) + assert mock_receive.called + + def test_handle_receive_raises_on_unidentified_protocol(self): + payload = "foobar" + with pytest.raises(NoSuitableProtocolFoundError): + handle_receive(payload) diff --git a/federation/tests/test_outbound.py b/federation/tests/test_outbound.py new file mode 100644 index 0000000..591bb59 --- /dev/null +++ b/federation/tests/test_outbound.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from unittest.mock import Mock, patch + +from Crypto.PublicKey import RSA + +from federation.entities.diaspora.entities import DiasporaPost +from federation.outbound import handle_create_payload + + +class TestHandleCreatePayloadBuildsAPayload(object): + def test_handle_create_payload_builds_an_xml(self): + from_user = Mock(private_key=RSA.generate(2048), handle="foobar@domain.tld") + to_user = Mock(key=RSA.generate(2048).publickey()) + entity = DiasporaPost() + data = handle_create_payload(from_user, to_user, entity) + assert len(data) > 0 + parts = data.split("=") + assert len(parts) == 2 + assert parts[0] == "xml" + assert len(parts[1]) > 0 + + @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) + assert mock_get_outbound_entity.called