Validate fetched remote profile

federation.utils.diaspora.retrieve_and_parse_profile will now return None if the Profile retrieved doesn't validate. This will affect also the output of federation.fetchers.retrieve_remote_profile which is the high level function to retrieve profiles.

Closes #54
merge-requests/130/head
Jason Robinson 2016-10-01 23:33:34 +03:00
rodzic 6d67fe05eb
commit ae717aefa8
4 zmienionych plików z 65 dodań i 3 usunięć

Wyświetl plik

@ -1,5 +1,8 @@
## [unreleased] ## [unreleased]
### Backwards incompatible changes
* `federation.utils.diaspora.retrieve_and_parse_profile` will now return `None` if the `Profile` retrieved doesn't validate. This will affect also the output of `federation.fetchers.retrieve_remote_profile` which is the high level function to retrieve profiles.
### Added ### Added
* Added `Retraction` entity with `DiasporaRetraction` counterpart. * Added `Retraction` entity with `DiasporaRetraction` counterpart.

Wyświetl plik

@ -13,6 +13,9 @@ def retrieve_remote_profile(handle, protocol=None):
Args: Args:
handle (str) - The profile handle in format username@domain.tld handle (str) - The profile handle in format username@domain.tld
Returns:
Profile or None
""" """
if protocol: if protocol:
warnings.warn("Currently retrieve_remote_profile doesn't use the protocol argument. Diaspora protocol" warnings.warn("Currently retrieve_remote_profile doesn't use the protocol argument. Diaspora protocol"

Wyświetl plik

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from unittest.mock import patch from unittest.mock import patch, Mock
from urllib.parse import quote from urllib.parse import quote
from lxml import html from lxml import html
from federation.entities.base import Profile
from federation.hostmeta.generators import DiasporaWebFinger, DiasporaHostMeta, DiasporaHCard, generate_hcard from federation.hostmeta.generators import DiasporaWebFinger, DiasporaHostMeta, DiasporaHCard, generate_hcard
from federation.utils.diaspora import retrieve_diaspora_hcard, retrieve_diaspora_webfinger, retrieve_diaspora_host_meta, \ from federation.utils.diaspora import retrieve_diaspora_hcard, retrieve_diaspora_webfinger, retrieve_diaspora_host_meta, \
_get_element_text_or_none, _get_element_attr_or_none, parse_profile_from_hcard, retrieve_and_parse_profile _get_element_text_or_none, _get_element_attr_or_none, parse_profile_from_hcard, retrieve_and_parse_profile
@ -163,3 +164,48 @@ class TestRetrieveAndParseProfile(object):
mock_retrieve.return_value = hcard mock_retrieve.return_value = hcard
retrieve_and_parse_profile("foo@bar") retrieve_and_parse_profile("foo@bar")
mock_parse.assert_called_with(hcard, "foo@bar") mock_parse.assert_called_with(hcard, "foo@bar")
@patch("federation.utils.diaspora.parse_profile_from_hcard")
@patch("federation.utils.diaspora.retrieve_diaspora_hcard")
def test_profile_that_doesnt_validate_returns_none(self, mock_retrieve, mock_parse):
hcard = generate_hcard(
"diaspora",
hostname="https://hostname",
fullname="fullname",
firstname="firstname",
lastname="lastname",
photo300="photo300",
photo100="photo100",
photo50="photo50",
searchable="true",
guid="guid",
public_key="public_key",
username="username",
)
mock_retrieve.return_value = hcard
mock_parse.return_value = Profile(guid="123")
profile = retrieve_and_parse_profile("foo@bar")
assert profile == None
@patch("federation.utils.diaspora.parse_profile_from_hcard")
@patch("federation.utils.diaspora.retrieve_diaspora_hcard")
def test_profile_validate_is_called(self, mock_retrieve, mock_parse):
hcard = generate_hcard(
"diaspora",
hostname="https://hostname",
fullname="fullname",
firstname="firstname",
lastname="lastname",
photo300="photo300",
photo100="photo100",
photo50="photo50",
searchable="true",
guid="guid",
public_key="public_key",
username="username",
)
mock_retrieve.return_value = hcard
mock_profile = Mock()
mock_parse.return_value = mock_profile
retrieve_and_parse_profile("foo@bar")
assert mock_profile.validate.called

Wyświetl plik

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging
from urllib.parse import quote from urllib.parse import quote
from lxml import html from lxml import html
@ -7,6 +8,8 @@ from xrd import XRD
from federation.entities.base import Profile from federation.entities.base import Profile
from federation.utils.network import fetch_document from federation.utils.network import fetch_document
logger = logging.getLogger("social-federation")
def retrieve_diaspora_hcard(handle): def retrieve_diaspora_hcard(handle):
""" """
@ -127,9 +130,16 @@ def retrieve_and_parse_profile(handle):
handle (str) - User handle in username@domain.tld format handle (str) - User handle in username@domain.tld format
Returns: Returns:
Profile Profile or None
""" """
hcard = retrieve_diaspora_hcard(handle) hcard = retrieve_diaspora_hcard(handle)
if not hcard: if not hcard:
return None return None
return parse_profile_from_hcard(hcard, handle) profile = parse_profile_from_hcard(hcard, handle)
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 None
return profile