Skip to content

Commit

Permalink
Improve webfinger and alternate-scheme handling
Browse files Browse the repository at this point in the history
Supports a raw acct: URI for webfinger in addition to a Mastodon-style webfinger address

Also properly handles unsupported URI schemes
  • Loading branch information
fluffy-critter committed Feb 25, 2023
1 parent 1917492 commit cfe6b18
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 14 deletions.
3 changes: 3 additions & 0 deletions authl/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ def request_url(url: str,
)
except requests.exceptions.MissingSchema:
LOGGER.info("Missing schema on URL %s", attempt)
except requests.exceptions.InvalidSchema:
LOGGER.info("Unsupported schema on URL %s", attempt)
return None
except Exception as err: # pylint:disable=broad-except
LOGGER.info("%s failed: %s", attempt, err)

Expand Down
4 changes: 2 additions & 2 deletions authl/webfinger.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ def get_profiles(url: str, timeout: int = 30) -> typing.Set[str]:
:returns: A :py:type:`set` of potential identity URLs
"""
webfinger = re.match(r'@([^@]+)@(.*)$', url)
webfinger = re.match(r'(@|acct:)([^@]+)@(.*)$', url)
if not webfinger:
return set()

try:
user, domain = webfinger.group(1, 2)
user, domain = webfinger.group(2, 3)
LOGGER.debug("webfinger: user=%s domain=%s", user, domain)

resource = html.escape(f'acct:{user}@{domain}')
Expand Down
3 changes: 3 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pytest]
log_cli = true
;log_cli_level = DEBUG
42 changes: 30 additions & 12 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,6 @@ def test_get_handler_for_url(requests_mock):
assert instance.get_handler_for_url('') == (None, '', '')


def test_webmention_url(mocker):
""" test handles_url on a webmention profile """
handler_1 = UrlHandler('test://foo', 'a')
handler_2 = UrlHandler('test://bar', 'b')
instance = Authl([handler_1, handler_2])

wgp = mocker.patch('authl.webfinger.get_profiles')
wgp.side_effect = lambda url: {'test://cat', 'test://bar'} if url == '@foo@bar.baz' else {}

assert instance.get_handler_for_url('@foo@bar.baz') == (handler_2, 'b', 'test://bar')


def test_from_config(mocker):
""" Ensure the main from_config function calls the appropriate proxied ones """
test_config = {
Expand Down Expand Up @@ -140,3 +128,33 @@ def test_redir_url(requests_mock):

assert instance.get_handler_for_url('http://foo') == \
(handler, 'foo', 'http://bar')


def test_webfinger_profiles(mocker):
""" test handles_url on a webfinger profile """
handler_1 = UrlHandler('test://foo', 'a')
handler_2 = UrlHandler('test://bar', 'b')
instance = Authl([handler_1, handler_2])

wgp = mocker.patch('authl.webfinger.get_profiles')
wgp.side_effect = lambda url: {'test://cat',
'test://bar'} if url == 'fake webfinger address' else {}

assert instance.get_handler_for_url('fake webfinger address') == (handler_2, 'b', 'test://bar')


def test_scheme_fallback(requests_mock):
""" Ensure that unknown and missing schemes fall back correctly """
requests_mock.get('https://foo/bar', text='blah')
requests_mock.get('http://foo/bar', text='blah')

handler_https = UrlHandler('https://foo/bar', 'secure')
handler_http = UrlHandler('http://foo/bar', 'insecure')
instance = Authl([handler_https, handler_http])

assert instance.get_handler_for_url(
'https://foo/bar') == (handler_https, 'secure', 'https://foo/bar')
assert instance.get_handler_for_url(
'http://foo/bar') == (handler_http, 'insecure', 'http://foo/bar')
assert instance.get_handler_for_url('foo/bar') == (handler_https, 'secure', 'https://foo/bar')
assert instance.get_handler_for_url('example://foo') == (None, '', '')
3 changes: 3 additions & 0 deletions tests/test_webfinger.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def test_resource(requests_mock):
assert webfinger.get_profiles(
"@profile@example.com") == {'https://profile.example.com/u/moo',
'https://self.example.com/u/moo'}
assert webfinger.get_profiles(
"acct:profile@example.com") == {'https://profile.example.com/u/moo',
'https://self.example.com/u/moo'}

requests_mock.get('https://example.com/.well-known/webfinger?resource=acct:empty@example.com',
json={
Expand Down

0 comments on commit cfe6b18

Please sign in to comment.