add User.verify(), checks redirects and home page representative h-card

for #276
pull/297/head
Ryan Barrett 2022-11-18 18:46:27 -08:00
rodzic 2d07ac358d
commit f384bf5529
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
2 zmienionych plików z 74 dodań i 0 usunięć

Wyświetl plik

@ -2,12 +2,16 @@
import logging
import urllib.parse
from werkzeug.exceptions import BadRequest, NotFound
from Crypto.PublicKey import RSA
from django_salmon import magicsigs
from flask import request
from google.cloud import ndb
from oauth_dropins.webutil.models import StringIdModel
import common
logger = logging.getLogger(__name__)
@ -27,6 +31,8 @@ class User(StringIdModel):
mod = ndb.StringProperty(required=True)
public_exponent = ndb.StringProperty(required=True)
private_exponent = ndb.StringProperty(required=True)
has_redirects = ndb.BooleanProperty()
has_hcard = ndb.BooleanProperty()
@classmethod
def _get_kind(cls):
@ -65,6 +71,27 @@ class User(StringIdModel):
magicsigs.base64_to_long(str(self.private_exponent))))
return rsa.exportKey(format='PEM')
def verify(self):
"""Fetches site a couple ways to check for redirects and h-card."""
domain = self.key.id()
site = f'https://{domain}/'
logger.info(f'Verifying {site}')
# check webfinger redirect
path = f'/.well-known/webfinger?resource=acct:{domain}@{domain}'
resp = common.requests_get(urllib.parse.urljoin(site, path),
allow_redirects=False)
expected = urllib.parse.urljoin(request.host_url, path)
if resp.is_redirect and resp.headers.get('Location') == expected:
self.has_redirects = True
# check home page
try:
common.actor(self.key.id())
self.has_hcard = True
except (BadRequest, NotFound):
pass
class Activity(StringIdModel):
"""A reply, like, repost, or other interaction that we've relayed.

Wyświetl plik

@ -1,5 +1,9 @@
# coding=utf-8
"""Unit tests for models.py."""
from unittest import mock
from oauth_dropins.webutil.testutil import requests_response
from app import app
from models import User, Activity
from . import testutil
@ -35,6 +39,49 @@ class UserTest(testutil.TestCase):
self.assertTrue(pem.decode().startswith('-----BEGIN RSA PRIVATE KEY-----\n'), pem)
self.assertTrue(pem.decode().endswith('-----END RSA PRIVATE KEY-----'), pem)
@mock.patch('requests.get')
def test_verify(self, mock_get):
self.assertFalse(self.user.has_redirects)
self.assertFalse(self.user.has_hcard)
def check(redirects, hcard):
with app.test_request_context('/'):
self.user.verify()
with self.subTest(redirects=redirects, hcard=hcard):
self.assertEqual(redirects, bool(self.user.has_redirects))
self.assertEqual(hcard, bool(self.user.has_hcard))
# both fail
empty = requests_response('')
mock_get.side_effect = [empty, empty]
check(False, False)
# redirect works but strips query params, no h-card
half_redir = requests_response(
status=302, redirected_url='http://localhost/.well-known/webfinger')
no_hcard = requests_response('<html><body></body></html>')
mock_get.side_effect = [half_redir, no_hcard]
check(False, False)
# redirect works, non-representative h-card
full_redir = requests_response(
status=302, allow_redirects=False,
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/">me</a></body></html>',
url='https://y.z/',
)
mock_get.side_effect = [full_redir, bad_hcard]
check(True, False)
# both work
hcard = requests_response(
'<html><body><a class="h-card u-url" href="/">me</a></body></html>',
url='https://y.z/',
)
mock_get.side_effect = [full_redir, hcard]
check(True, True)
class ActivityTest(testutil.TestCase):