kopia lustrzana https://github.com/snarfed/bridgy-fed
add webfinger.fetch_actor_url, use it in follow
also add a basic test for webfinger.fetchpull/646/head
rodzic
0d33b6422d
commit
e97270b344
13
follow.py
13
follow.py
|
@ -96,19 +96,8 @@ class FollowCallback(indieauth.Callback):
|
|||
addr = state
|
||||
if not state:
|
||||
error('Missing state')
|
||||
elif util.is_web(state):
|
||||
as2_url = state
|
||||
else:
|
||||
resp = webfinger.fetch(addr)
|
||||
if resp is None:
|
||||
return redirect(g.user.user_page_path('following'))
|
||||
|
||||
as2_url = None
|
||||
for link in resp.get('links', []):
|
||||
type = link.get('type', '').split(';')[0]
|
||||
if link.get('rel') == 'self' and type in as2.CONTENT_TYPES:
|
||||
as2_url = link.get('href')
|
||||
|
||||
as2_url = state if util.is_web(state) else webfinger.fetch_actor_url(addr)
|
||||
if not as2_url:
|
||||
flash(f"Couldn't find ActivityPub profile link for {addr}")
|
||||
return redirect(g.user.user_page_path('following'))
|
||||
|
|
|
@ -10,6 +10,7 @@ from oauth_dropins.webutil.testutil import requests_response
|
|||
from .testutil import Fake, TestCase
|
||||
|
||||
from web import Web
|
||||
from webfinger import fetch, fetch_actor_url
|
||||
|
||||
from .test_web import ACTOR_HTML
|
||||
|
||||
|
@ -261,7 +262,7 @@ class WebfingerTest(TestCase):
|
|||
self.assertEqual(400, got.status_code, got.get_data(as_text=True))
|
||||
|
||||
@patch('requests.get')
|
||||
def test_fetch_create_user(self, mock_get):
|
||||
def test_serve_create_user(self, mock_get):
|
||||
self.user.key.delete()
|
||||
mock_get.return_value = requests_response(ACTOR_HTML)
|
||||
|
||||
|
@ -282,3 +283,22 @@ class WebfingerTest(TestCase):
|
|||
|
||||
got = self.client.get('/.well-known/webfinger?resource=acct%3A%40localhost')
|
||||
self.assertEqual(400, got.status_code, got.get_data(as_text=True))
|
||||
|
||||
@patch('requests.get', return_value=requests_response(
|
||||
WEBFINGER, content_type='application/jrd+json'))
|
||||
def test_fetch(self, mock_get):
|
||||
self.assertEqual(WEBFINGER, fetch('@foo@bar'))
|
||||
self.assert_req(mock_get,
|
||||
'https://bar/.well-known/webfinger?resource=acct:foo@bar')
|
||||
|
||||
@patch('requests.get', return_value=requests_response(WEBFINGER))
|
||||
def test_fetch_actor_url(self, mock_get):
|
||||
self.assertEqual('http://localhost/user.com', fetch_actor_url('@foo@bar'))
|
||||
self.assert_req(mock_get,
|
||||
'https://bar/.well-known/webfinger?resource=acct:foo@bar')
|
||||
|
||||
@patch('requests.get', return_value=requests_response({'links': []}))
|
||||
def test_fetch_actor_url_not_found(self, mock_get):
|
||||
self.assertIsNone(fetch_actor_url('@foo@bar'))
|
||||
self.assert_req(mock_get,
|
||||
'https://bar/.well-known/webfinger?resource=acct:foo@bar')
|
||||
|
|
32
webfinger.py
32
webfinger.py
|
@ -1,7 +1,7 @@
|
|||
"""Handles requests for WebFinger endpoints.
|
||||
|
||||
https://webfinger.net/
|
||||
https://tools.ietf.org/html/rfc7033
|
||||
* https://webfinger.net/
|
||||
* https://tools.ietf.org/html/rfc7033
|
||||
"""
|
||||
import logging
|
||||
import urllib.parse
|
||||
|
@ -172,17 +172,15 @@ def fetch(addr):
|
|||
|
||||
On failure, flashes a message and returns None.
|
||||
|
||||
TODO: unit tests. right now it's only tested indirectly, in test_follow.
|
||||
TODO: switch to raising exceptions instead of flashing messages and
|
||||
returning None
|
||||
|
||||
Args:
|
||||
addr: str, a Webfinger-compatible address, eg @x@y, acct:x@y, or
|
||||
addr (str): a Webfinger-compatible address, eg @x@y, acct:x@y, or
|
||||
https://x/y
|
||||
|
||||
Returns:
|
||||
dict, fetched Webfinger data, or None on error
|
||||
|
||||
dict: fetched Webfinger data, or None on error
|
||||
"""
|
||||
addr = addr.strip().strip('@')
|
||||
split = addr.split('@')
|
||||
|
@ -220,6 +218,28 @@ def fetch(addr):
|
|||
return data
|
||||
|
||||
|
||||
def fetch_actor_url(addr):
|
||||
"""Fetches and returns a WebFinger address's ActivityPub actor URL.
|
||||
|
||||
On failure, flashes a message and returns None.
|
||||
|
||||
Args:
|
||||
addr (str): a Webfinger-compatible address, eg ``@x@y``, ``acct:x@y``, or
|
||||
``https://x/y``
|
||||
|
||||
Returns:
|
||||
str: ActivityPub actor URL, or None on error or not fouund
|
||||
"""
|
||||
data = fetch(addr)
|
||||
if not data:
|
||||
return None
|
||||
|
||||
for link in data.get('links', []):
|
||||
type = link.get('type', '').split(';')[0]
|
||||
if link.get('rel') == 'self' and type in as2.CONTENT_TYPES:
|
||||
return link.get('href')
|
||||
|
||||
|
||||
app.add_url_rule('/.well-known/webfinger', view_func=Webfinger.as_view('webfinger'))
|
||||
app.add_url_rule('/.well-known/host-meta', view_func=HostMeta.as_view('hostmeta'))
|
||||
app.add_url_rule('/.well-known/host-meta.json', view_func=HostMeta.as_view('hostmeta-json'))
|
||||
|
|
Ładowanie…
Reference in New Issue