kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
fd1b9bddb9
commit
85b1a400ff
32
models.py
32
models.py
|
@ -20,22 +20,24 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
class User(StringIdModel):
|
||||
"""Stores a user's public/private key pair used for Magic Signatures.
|
||||
"""Stores a Bridgy Fed user.
|
||||
|
||||
The key name is the domain.
|
||||
The key name is the domain. The key pair is used for both ActivityPub HTTP
|
||||
Signatures and Salmon Magic Signatures.
|
||||
|
||||
The modulus and exponent properties are all encoded as base64url (ie URL-safe
|
||||
base64) strings as described in RFC 4648 and section 5.1 of the Magic
|
||||
Signatures spec.
|
||||
|
||||
Magic Signatures are used to sign Salmon slaps. Details:
|
||||
https://tools.ietf.org/html/draft-cavage-http-signatures-07
|
||||
http://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-magicsig-01.html
|
||||
http://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-salmon-00.html
|
||||
|
||||
The key pair's modulus and exponent properties are all encoded as base64url
|
||||
(ie URL-safe base64) strings as described in RFC 4648 and section 5.1 of the
|
||||
Magic Signatures spec.
|
||||
"""
|
||||
mod = ndb.StringProperty(required=True)
|
||||
public_exponent = ndb.StringProperty(required=True)
|
||||
private_exponent = ndb.StringProperty(required=True)
|
||||
has_redirects = ndb.BooleanProperty()
|
||||
redirects_error = ndb.TextProperty()
|
||||
has_hcard = ndb.BooleanProperty()
|
||||
actor_as2 = ndb.TextProperty()
|
||||
|
||||
|
@ -127,16 +129,22 @@ class User(StringIdModel):
|
|||
|
||||
# check webfinger redirect
|
||||
path = f'/.well-known/webfinger?resource=acct:{domain}@{domain}'
|
||||
self.has_redirects = False
|
||||
self.redirects_error = None
|
||||
try:
|
||||
resp = util.requests_get(urllib.parse.urljoin(site, path),
|
||||
allow_redirects=False, gateway=False)
|
||||
url = urllib.parse.urljoin(site, path)
|
||||
resp = util.requests_get(url, allow_redirects=False, gateway=False)
|
||||
domain_urls = ([f'https://{domain}/' for domain in common.DOMAINS] +
|
||||
[request.host_url])
|
||||
expected = [urllib.parse.urljoin(url, path) for url in domain_urls]
|
||||
self.has_redirects = (resp.is_redirect and
|
||||
resp.headers.get('Location') in expected)
|
||||
if resp.is_redirect:
|
||||
got = resp.headers.get('Location')
|
||||
if got in expected:
|
||||
self.has_redirects = True
|
||||
else:
|
||||
self.redirects_error = f'<code>{url}</code> redirects to <code>{got}</code> ; expected <code>{expected[0]}</code>'
|
||||
except requests.RequestException:
|
||||
self.has_redirects = False
|
||||
pass
|
||||
|
||||
# check home page
|
||||
try:
|
||||
|
|
|
@ -440,7 +440,6 @@ a img.shadow:hover
|
|||
box-shadow: 3px 3px 3px #06c !important;
|
||||
}
|
||||
|
||||
|
||||
.error, .warning {
|
||||
margin: 10px;
|
||||
padding: .2em;
|
||||
|
|
|
@ -7,25 +7,31 @@
|
|||
{% if user.has_redirects == False %}
|
||||
<div class="row promo warning">
|
||||
<form method="post" action="/web-site">
|
||||
Next step to set up your site:
|
||||
Next step:
|
||||
<a href="/docs#redirect+these+URL+paths">
|
||||
add the .well-known redirects.
|
||||
</a>
|
||||
<input type="hidden" name="url" value="https://{{ domain }}" />
|
||||
<input type="submit" class="retry" value="🔄" title="Check again" />
|
||||
<input type="submit" class="btn btn-default" value="Check now" />
|
||||
</form>
|
||||
|
||||
{% if user.redirects_error %}
|
||||
<details class="small">
|
||||
{{ user.redirects_error|safe }}
|
||||
</details>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if user.has_hcard == False %}
|
||||
<div class="row promo warning">
|
||||
<form method="post" action="/web-site">
|
||||
Next step to set up your site:
|
||||
Next step:
|
||||
<a href="https://indiewebify.me/validate-h-card/?url=https://{{ domain }}">
|
||||
add a representative h-card.
|
||||
</a>
|
||||
<input type="hidden" name="url" value="https://{{ domain }}" />
|
||||
<input type="submit" class="retry" value="🔄" title="Check again" />
|
||||
<input type="submit" class="btn btn-default" value="Check now" />
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -57,10 +57,11 @@ class UserTest(testutil.TestCase):
|
|||
self.assertFalse(self.user.has_redirects)
|
||||
self.assertFalse(self.user.has_hcard)
|
||||
|
||||
def check(redirects, hcard, actor):
|
||||
def check(redirects, hcard, actor, redirects_error=None):
|
||||
with app.test_request_context('/'):
|
||||
self.user.verify()
|
||||
with self.subTest(redirects=redirects, hcard=hcard, actor=actor):
|
||||
with self.subTest(redirects=redirects, hcard=hcard, actor=actor,
|
||||
redirects_error=redirects_error):
|
||||
self.assert_equals(redirects, bool(self.user.has_redirects))
|
||||
self.assert_equals(hcard, bool(self.user.has_hcard))
|
||||
if actor is None:
|
||||
|
@ -69,18 +70,21 @@ class UserTest(testutil.TestCase):
|
|||
got = {k: v for k, v in json_loads(self.user.actor_as2).items()
|
||||
if k in actor}
|
||||
self.assert_equals(actor, got)
|
||||
self.assert_equals(redirects_error, self.user.redirects_error)
|
||||
|
||||
# both fail
|
||||
empty = requests_response('')
|
||||
empty = requests_response('', allow_redirects=False)
|
||||
mock_get.side_effect = [empty, empty]
|
||||
check(False, False, None)
|
||||
|
||||
# redirect works but strips query params, no h-card
|
||||
# redirect strips query params, no h-card
|
||||
half_redir = requests_response(
|
||||
status=302, redirected_url='http://localhost/.well-known/webfinger')
|
||||
status=302, redirected_url='http://localhost/.well-known/webfinger',
|
||||
allow_redirects=False)
|
||||
no_hcard = requests_response('<html><body></body></html>')
|
||||
mock_get.side_effect = [half_redir, no_hcard]
|
||||
check(False, False, None)
|
||||
check(False, False, None,
|
||||
'<code>https://y.z/.well-known/webfinger?resource=acct:y.z@y.z</code> redirects to <code>http://localhost/.well-known/webfinger</code> ; expected <code>https://fed.brid.gy/.well-known/webfinger?resource=acct:y.z@y.z</code>')
|
||||
|
||||
# redirect works, non-representative h-card
|
||||
full_redir = requests_response(
|
||||
|
@ -88,7 +92,7 @@ class UserTest(testutil.TestCase):
|
|||
redirected_url='http://localhost/.well-known/webfinger?resource=acct:y.z@y.z')
|
||||
bad_hcard = requests_response(
|
||||
'<html><body><a class="h-card u-url" href="https://a.b/">acct:me@y.z</a></body></html>',
|
||||
url='https://y.z/',
|
||||
url='https://y.z/', allow_redirects=False,
|
||||
)
|
||||
mock_get.side_effect = [full_redir, bad_hcard]
|
||||
check(True, False, None)
|
||||
|
@ -99,7 +103,7 @@ class UserTest(testutil.TestCase):
|
|||
<a class="u-url p-name" href="/">me</a>
|
||||
<a class="u-url" href="acct:myself@y.z">Masto</a>
|
||||
</body></html>""",
|
||||
url='https://y.z/',
|
||||
url='https://y.z/', allow_redirects=False,
|
||||
)
|
||||
mock_get.side_effect = [full_redir, hcard]
|
||||
check(True, True, {
|
||||
|
|
Ładowanie…
Reference in New Issue