Merge pull request #86 from jaywink/receiving-guid-on-private-diaspora-payload

Add receiving user guid to entity for private Diaspora payloads
merge-requests/130/head
Jason Robinson 2017-05-21 22:54:58 +03:00 zatwierdzone przez GitHub
commit 2773405f09
5 zmienionych plików z 18 dodań i 8 usunięć

Wyświetl plik

@ -8,9 +8,10 @@
### Added
* New style Diaspora public payloads are now supported (see [here](https://github.com/diaspora/diaspora_federation/issues/30)). Old style payloads are still supported. Payloads are also still sent out old style.
* Add new `Follow` base entity and support for the new Diaspora "contact" payload. The simple `Follow` maps to Diaspora contact entity with following/sharing both true or false. Sharing as a separate concept is not currently supported.
* Added `_receiving_guid` to all entities. This is filled with `user.guid` if `user` is passed to `federation.inbound.handle_receive` and it has a `guid`. Normally in for example Diaspora, this will always be done in private payloads.
### Fixed
* Legacy Diaspora retraction of sharing/following is now supported correctly. The end result is a `DiasporaRetraction` for entity type `Profile`.
* Legacy Diaspora retraction of sharing/following is now supported correctly. The end result is a `DiasporaRetraction` for entity type `Profile`. Since the payload doesn't contain the receiving user for a sharing/following retraction in legacy Diaspora protocol, we store the guid of the user in the entity as `_receiving_guid`, assuming it was passed in for processing.
## [0.11.0] - 2017-05-08

Wyświetl plik

@ -13,6 +13,8 @@ class BaseEntity(object):
_required = []
_children = []
_allowed_children = ()
# If we have a receiver for a private payload, store receiving user guid here
_receiving_guid = ""
_source_protocol = ""
_source_object = None
_sender_key = ""

Wyświetl plik

@ -52,7 +52,7 @@ def xml_children_as_dict(node):
return dict((e.tag, e.text) for e in node)
def element_to_objects(element, sender_key_fetcher=None):
def element_to_objects(element, sender_key_fetcher=None, user=None):
"""Transform an Element to a list of entities recursively.
Possible child entities are added to each entity `_children` list.
@ -60,6 +60,7 @@ def element_to_objects(element, sender_key_fetcher=None):
:param tree: Element
:param sender_key_fetcher: Function to fetch sender public key. If not given, key will always be fetched
over network. The function should take sender handle as the only parameter.
:param user: Optional receiving user object. If given, should have a `handle`.
:returns: list of entities
"""
entities = []
@ -76,6 +77,9 @@ def element_to_objects(element, sender_key_fetcher=None):
entity._source_protocol = "diaspora"
# Save element object to entity for possible later use
entity._source_object = element
# Save receiving guid to object
if user and hasattr(user, "guid"):
entity._receiving_guid = user.guid
# If relayable, fetch sender key for validation
if issubclass(cls, DiasporaRelayableMixin):
entity._xml_tags = get_element_child_info(element, "tag")
@ -106,24 +110,25 @@ def element_to_objects(element, sender_key_fetcher=None):
return entities
def message_to_objects(message, sender_key_fetcher=None):
def message_to_objects(message, sender_key_fetcher=None, user=None):
"""Takes in a message extracted by a protocol and maps it to entities.
:param message: XML payload
:type message: str
:param sender_key_fetcher: Function to fetch sender public key. If not given, key will always be fetched
over network. The function should take sender handle as the only parameter.
:param user: Optional receiving user object. If given, should have a `handle`.
:returns: list of entities
"""
doc = etree.fromstring(message)
# Future Diaspora protocol version contains the element at top level
if doc.tag in TAGS:
return element_to_objects(doc, sender_key_fetcher)
return element_to_objects(doc, sender_key_fetcher, user)
# Legacy Diaspora protocol wraps the element in <XML><post></post></XML>, so find the right element
for tag in TAGS:
element = doc.find(".//%s" % tag)
if element is not None:
return element_to_objects(element, sender_key_fetcher)
return element_to_objects(element, sender_key_fetcher, user)
return []

Wyświetl plik

@ -23,7 +23,8 @@ def handle_receive(payload, user=None, sender_key_fetcher=None, skip_author_veri
could actually be a different identity.
:arg payload: Payload blob (str)
:arg user: User that will be passed to `protocol.receive` (required on private encrypted content)
:arg user: User that will be passed to `protocol.receive` (only required on private encrypted content)
MUST have a `private_key` and `guid` if given.
:arg sender_key_fetcher: Function that accepts sender handle and returns public key (optional)
:arg skip_author_verification: Don't verify sender (test purposes, false default)
:returns: Tuple of sender handle, protocol name and list of entity objects
@ -47,7 +48,7 @@ def handle_receive(payload, user=None, sender_key_fetcher=None, skip_author_veri
raise NoSuitableProtocolFoundError()
mappers = importlib.import_module("federation.entities.%s.mappers" % found_protocol.PROTOCOL_NAME)
entities = mappers.message_to_objects(message, sender_key_fetcher)
entities = mappers.message_to_objects(message, sender_key_fetcher, user)
logger.debug("handle_receive: entities %s", entities)
return sender, found_protocol.PROTOCOL_NAME, entities

Wyświetl plik

@ -156,13 +156,14 @@ class TestDiasporaEntityMappersReceive():
assert entity.entity_type == "Post"
def test_message_to_objects_retraction_legacy_request(self):
entities = message_to_objects(DIASPORA_LEGACY_REQUEST_RETRACTION)
entities = message_to_objects(DIASPORA_LEGACY_REQUEST_RETRACTION, user=Mock(guid="swfeuihiwehuifhiwheiuf"))
assert len(entities) == 1
entity = entities[0]
assert isinstance(entity, Retraction)
assert entity.handle == "jaywink@iliketoast.net"
assert entity.target_guid == "7ed1555bc6ae03db"
assert entity.entity_type == "Profile"
assert entity._receiving_guid == "swfeuihiwehuifhiwheiuf"
def test_message_to_objects_contact(self):
entities = message_to_objects(DIASPORA_CONTACT)