Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def retrieve_and_parse_content(
id: str, guid: str, handle: str, entity_type: str, sender_key_fetcher: Callable[[str], str]=None,
):
"""Retrieve remote content and return an Entity class instance.
This is basically the inverse of receiving an entity. Instead, we fetch it, then call "handle_receive".
:param sender_key_fetcher: Function to use to fetch sender public key. If not given, network will be used
to fetch the profile and the key. Function must take handle as only parameter and return a public key.
:returns: Entity object instance or ``None``
"""
if not validate_handle(handle):
return
_username, domain = handle.split("@")
url = get_fetch_content_endpoint(domain, entity_type.lower(), guid)
document, status_code, error = fetch_document(url)
if status_code == 200:
request = RequestType(body=document)
_sender, _protocol, entities = handle_receive(request, sender_key_fetcher=sender_key_fetcher)
if len(entities) > 1:
logger.warning("retrieve_and_parse_content - more than one entity parsed from remote even though we"
"expected only one! ID %s", guid)
if entities:
return entities[0]
return
elif status_code == 404:
logger.warning("retrieve_and_parse_content - remote content %s not found", guid)
return
def retrieve_remote_profile(id: str) -> Optional[Profile]:
"""High level retrieve profile method.
Retrieve the profile from a remote location, using protocols based on the given ID.
"""
if validate_handle(id):
protocols = (activitypub_protocol, diaspora_protocol)
else:
protocols = (identify_protocol_by_id(id),)
for protocol in protocols:
utils = importlib.import_module(f"federation.utils.{protocol.PROTOCOL_NAME}")
profile = utils.retrieve_and_parse_profile(id)
if profile:
return profile
def retrieve_remote_content(
id: str, guid: str = None, handle: str = None, entity_type: str = None,
sender_key_fetcher: Callable[[str], str] = None,
):
"""Retrieve remote content and return an Entity object.
``sender_key_fetcher`` is an optional function to use to fetch sender public key. If not given, network will be used
to fetch the profile and the key. Function must take federation id as only parameter and return a public key.
"""
if handle and validate_handle(handle):
protocol_name = "diaspora"
if not guid:
guid = id
else:
protocol_name = identify_protocol_by_id(id).PROTOCOL_NAME
utils = importlib.import_module("federation.utils.%s" % protocol_name)
return utils.retrieve_and_parse_content(
id=id, guid=guid, handle=handle, entity_type=entity_type, sender_key_fetcher=sender_key_fetcher,
)
def identify_id(id: str) -> bool:
"""
Try to identify if this ID is a Diaspora ID.
"""
return validate_handle(id)
if len(self._children):
as2["object"]["attachment"] = []
for child in self._children:
as2["object"]["attachment"].append(child.to_as2())
if len(self._mentions):
mentions = list(self._mentions)
mentions.sort()
for mention in mentions:
if mention.startswith("http"):
as2["object"]["tag"].append({
'type': 'Mention',
'href': mention,
'name': mention,
})
elif validate_handle(mention):
# Look up via WebFinger
as2["object"]["tag"].append({
'type': 'Mention',
'href': mention, # TODO need to implement fetch via webfinger for AP handles first
'name': mention,
})
as2["object"]["tag"].extend(self.add_object_tags())
if self.guid:
as2["@context"].append(CONTEXT_DIASPORA)
as2["object"]["diaspora:guid"] = self.guid
return as2
def retrieve_and_parse_profile(fid: str) -> Optional[ActivitypubProfile]:
"""
Retrieve the remote fid and return a Profile object.
"""
if validate_handle(fid):
profile_id = get_profile_id_from_webfinger(fid)
if not profile_id:
return
else:
profile_id = fid
profile = retrieve_and_parse_document(profile_id)
if not profile:
return
try:
profile.validate()
except ValueError as ex:
logger.warning("retrieve_and_parse_profile - found profile %s but it didn't validate: %s",
profile, ex)
return
return profile