noop: drop content type constants in common, use granary's instead

pull/356/head
Ryan Barrett 2023-01-06 21:01:33 -08:00
rodzic 7ac1006021
commit aa0dcbb222
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
8 zmienionych plików z 49 dodań i 68 usunięć

Wyświetl plik

@ -41,7 +41,7 @@ def actor(domain):
"""Fetches a domain's h-card and converts to AS2 actor."""
actor = common.actor(domain)
return (actor, {
'Content-Type': common.CONTENT_TYPE_AS2,
'Content-Type': as2.CONTENT_TYPE,
'Access-Control-Allow-Origin': '*',
})

Wyświetl plik

@ -32,23 +32,10 @@ TLD_BLOCKLIST = ('7z', 'asp', 'aspx', 'gif', 'html', 'ico', 'jpg', 'jpeg', 'js',
XML_UTF8 = "<?xml version='1.0' encoding='UTF-8'?>\n"
LINK_HEADER_RE = re.compile(r""" *< *([^ >]+) *> *; *rel=['"]([^'"]+)['"] *""")
# Content-Type values. All non-unicode strings because App Engine's wsgi.py
# requires header values to be str, not unicode.
#
# ActivityPub Content-Type details:
# https://www.w3.org/TR/activitypub/#retrieving-objects
CONTENT_TYPE_LD = 'application/ld+json'
CONTENT_TYPE_AS2_LD = f'{CONTENT_TYPE_LD};profile="https://www.w3.org/ns/activitystreams"'
CONTENT_TYPE_AS2 = 'application/activity+json'
CONTENT_TYPE_AS1 = 'application/stream+json'
CONTENT_TYPE_LD_PLAIN = 'application/ld+json'
CONTENT_TYPE_HTML = 'text/html; charset=utf-8'
CONTENT_TYPE_ATOM = 'application/atom+xml'
CONTENT_TYPE_MAGIC_ENVELOPE = 'application/magic-envelope+xml'
CONNEG_HEADERS_AS2 = {
'Accept': '%s; q=0.9, %s; q=0.8' % (CONTENT_TYPE_AS2, CONTENT_TYPE_AS2_LD),
}
CONNEG_HEADERS_AS2_HTML = copy.deepcopy(CONNEG_HEADERS_AS2)
CONNEG_HEADERS_AS2_HTML = copy.deepcopy(as2.CONNEG_HEADERS)
CONNEG_HEADERS_AS2_HTML['Accept'] += f', {CONTENT_TYPE_HTML}; q=0.7'
SUPPORTED_VERBS = (
@ -140,7 +127,7 @@ def signed_request(fn, url, data=None, user=None, headers=None, **kwargs):
# required by Mastodon
# https://github.com/tootsuite/mastodon/pull/14556#issuecomment-674077648
'Host': util.domain_from_link(url, minimize=False),
'Content-Type': CONTENT_TYPE_AS2,
'Content-Type': as2.CONTENT_TYPE,
# required for HTTP Signature and Mastodon
'Digest': f'SHA-256={b64encode(sha256(data or b"").digest()).decode()}',
})
@ -203,18 +190,18 @@ def get_as2(url, user=None):
raise err
resp = signed_get(url, user=user, headers=CONNEG_HEADERS_AS2_HTML)
if content_type(resp) in (CONTENT_TYPE_AS2, CONTENT_TYPE_LD):
if content_type(resp) in (as2.CONTENT_TYPE, CONTENT_TYPE_LD_PLAIN):
return resp
parsed = util.parse_html(resp)
as2 = parsed.find('link', rel=('alternate', 'self'), type=(
CONTENT_TYPE_AS2, CONTENT_TYPE_AS2_LD))
if not (as2 and as2['href']):
obj = parsed.find('link', rel=('alternate', 'self'), type=(
as2.CONTENT_TYPE, as2.CONTENT_TYPE_LD))
if not (obj and obj['href']):
_error(resp)
resp = signed_get(urllib.parse.urljoin(resp.url, as2['href']),
headers=CONNEG_HEADERS_AS2)
if content_type(resp) in (CONTENT_TYPE_AS2, CONTENT_TYPE_LD):
resp = signed_get(urllib.parse.urljoin(resp.url, obj['href']),
headers=as2.CONNEG_HEADERS)
if content_type(resp) in (as2.CONTENT_TYPE, CONTENT_TYPE_LD_PLAIN):
return resp
_error(resp)

Wyświetl plik

@ -27,8 +27,6 @@ from werkzeug.exceptions import abort
from app import app, cache
from common import (
CACHE_TIME,
CONTENT_TYPE_AS2,
CONTENT_TYPE_AS2_LD,
CONTENT_TYPE_HTML,
postprocess_as2,
)
@ -38,8 +36,8 @@ logger = logging.getLogger(__name__)
_negotiator = ContentNegotiator(acceptable=[
AcceptParameters(ContentType(CONTENT_TYPE_HTML)),
AcceptParameters(ContentType(CONTENT_TYPE_AS2)),
AcceptParameters(ContentType(CONTENT_TYPE_AS2_LD)),
AcceptParameters(ContentType(as2.CONTENT_TYPE)),
AcceptParameters(ContentType(as2.CONTENT_TYPE_LD)),
])
@ -83,7 +81,7 @@ def redir(to):
negotiated = None
if negotiated:
type = str(negotiated.content_type)
if type in (CONTENT_TYPE_AS2, CONTENT_TYPE_AS2_LD):
if type in (as2.CONTENT_TYPE, as2.CONTENT_TYPE_LD):
return convert_to_as2(to, user), {
'Content-Type': type,
'Access-Control-Allow-Origin': '*',

Wyświetl plik

@ -162,7 +162,7 @@ class ActivityPubTest(testutil.TestCase):
self.assert_req(mock_get, 'https://foo.com/')
self.assertEqual(200, got.status_code)
type = got.headers['Content-Type']
self.assertTrue(type.startswith(common.CONTENT_TYPE_AS2), type)
self.assertTrue(type.startswith(as2.CONTENT_TYPE), type)
self.assertEqual({
'@context': [
'https://www.w3.org/ns/activitystreams',
@ -296,7 +296,7 @@ class ActivityPubTest(testutil.TestCase):
mock_head.return_value = requests_response(url='http://target')
mock_get.return_value = requests_response( # source actor
ACTOR, headers={'Content-Type': common.CONTENT_TYPE_AS2})
ACTOR, headers={'Content-Type': as2.CONTENT_TYPE})
mock_post.return_value = requests_response()
with self.client:
@ -318,7 +318,7 @@ class ActivityPubTest(testutil.TestCase):
mock_head.return_value = requests_response(url='http://target')
mock_get.return_value = requests_response( # source actor
ACTOR, headers={'Content-Type': common.CONTENT_TYPE_AS2})
ACTOR, headers={'Content-Type': as2.CONTENT_TYPE})
not_public = copy.deepcopy(NOTE)
del not_public['object']['to']
@ -366,7 +366,7 @@ class ActivityPubTest(testutil.TestCase):
mock_head.return_value = requests_response(url='http://or.ig/post')
mock_get.side_effect = [
# source actor
requests_response(LIKE_WITH_ACTOR['actor'], headers={'Content-Type': common.CONTENT_TYPE_AS2}),
requests_response(LIKE_WITH_ACTOR['actor'], headers={'Content-Type': as2.CONTENT_TYPE}),
# target post webmention discovery
requests_response(
'<html><head><link rel="webmention" href="/webmention"></html>'),
@ -401,7 +401,7 @@ class ActivityPubTest(testutil.TestCase):
mock_get.side_effect = [
# source actor
requests_response(FOLLOW_WITH_ACTOR['actor'],
content_type=common.CONTENT_TYPE_AS2),
content_type=as2.CONTENT_TYPE),
# target post webmention discovery
requests_response(
'<html><head><link rel="webmention" href="/webmention"></html>'),
@ -448,7 +448,7 @@ class ActivityPubTest(testutil.TestCase):
mock_head.return_value = requests_response(url='https://www.realize.be/')
mock_get.side_effect = [
# source actor
requests_response(ACTOR, content_type=common.CONTENT_TYPE_AS2),
requests_response(ACTOR, content_type=as2.CONTENT_TYPE),
# target post webmention discovery
requests_response('<html></html>'),
]
@ -484,7 +484,7 @@ class ActivityPubTest(testutil.TestCase):
mock_get.side_effect = [
# source actor
requests_response(FOLLOW_WITH_ACTOR['actor'],
content_type=common.CONTENT_TYPE_AS2),
content_type=as2.CONTENT_TYPE),
# target post webmention discovery
requests_response(
'<html><head><link rel="webmention" href="/webmention"></html>'),
@ -525,7 +525,7 @@ class ActivityPubTest(testutil.TestCase):
# https://console.cloud.google.com/errors/detail/CMKn7tqbq-GIRA;time=P30D?project=bridgy-federated
mock_get.side_effect = [
# source actor
requests_response(ACTOR, content_type=common.CONTENT_TYPE_AS2),
requests_response(ACTOR, content_type=as2.CONTENT_TYPE),
]
got = self.client.post('/foo.com/inbox', json={
'@context': 'https://www.w3.org/ns/activitystreams',
@ -573,7 +573,7 @@ class ActivityPubTest(testutil.TestCase):
mock_get.side_effect = [
# source actor
requests_response(LIKE_WITH_ACTOR['actor'],
headers={'Content-Type': common.CONTENT_TYPE_AS2}),
headers={'Content-Type': as2.CONTENT_TYPE}),
# target post webmention discovery
ReadTimeoutError(None, None, None),
]
@ -585,7 +585,7 @@ class ActivityPubTest(testutil.TestCase):
mock_get.side_effect = [
# source actor
requests_response(LIKE_WITH_ACTOR['actor'],
headers={'Content-Type': common.CONTENT_TYPE_AS2}),
headers={'Content-Type': as2.CONTENT_TYPE}),
# target post webmention discovery
requests_response('<html><body>foo</body></html>'),
]

Wyświetl plik

@ -25,7 +25,7 @@ HTML_WITH_AS2 = requests_response("""\
})
AS2_OBJ = {'foo': ['bar']}
AS2 = requests_response(AS2_OBJ, headers={
'Content-Type': common.CONTENT_TYPE_AS2,
'Content-Type': as2.CONTENT_TYPE,
})
NOT_ACCEPTABLE = requests_response(status=406)
@ -54,7 +54,7 @@ class CommonTest(testutil.TestCase):
self.assertEqual(AS2, resp)
mock_get.assert_has_calls((
self.as2_req('http://orig'),
self.as2_req('http://as2', headers=common.CONNEG_HEADERS_AS2),
self.as2_req('http://as2', headers=common.as2.CONNEG_HEADERS),
))
@mock.patch('requests.get', return_value=HTML)

Wyświetl plik

@ -46,10 +46,10 @@ class RedirectTest(testutil.TestCase):
self.assertEqual(404, got.status_code)
def test_as2(self):
self._test_as2(common.CONTENT_TYPE_AS2)
self._test_as2(as2.CONTENT_TYPE)
def test_as2_ld(self):
self._test_as2(common.CONTENT_TYPE_AS2_LD)
self._test_as2(as2.CONTENT_TYPE_LD)
def test_accept_header_cache_key(self):
app.config['CACHE_TYPE'] = 'SimpleCache'
@ -60,7 +60,7 @@ class RedirectTest(testutil.TestCase):
self.assertEqual(301, got.status_code)
self.assertEqual('https://foo.com/bar', got.headers['Location'])
self._test_as2(common.CONTENT_TYPE_AS2)
self._test_as2(as2.CONTENT_TYPE)
got = self.client.get('/r/https://foo.com/bar',
headers={'Accept': 'text/html'})

Wyświetl plik

@ -19,12 +19,8 @@ import requests
import activitypub
from common import (
CONNEG_HEADERS_AS2,
CONNEG_HEADERS_AS2_HTML,
CONTENT_TYPE_AS2,
CONTENT_TYPE_ATOM,
CONTENT_TYPE_HTML,
CONTENT_TYPE_MAGIC_ENVELOPE,
default_signature_user,
)
from models import Follower, User, Activity
@ -95,7 +91,7 @@ class WebmentionTest(testutil.TestCase):
<link rel="salmon" href="http://orig/salmon"/>
<content type="html">baz baj</content>
</entry>
""", content_type=CONTENT_TYPE_ATOM)
""", content_type=atom.CONTENT_TYPE)
self.orig_as2_data = {
'@context': ['https://www.w3.org/ns/activitystreams'],
'type': 'Article',
@ -107,7 +103,7 @@ class WebmentionTest(testutil.TestCase):
}
self.orig_as2 = requests_response(
self.orig_as2_data, url='http://orig/as2',
content_type=CONTENT_TYPE_AS2 + '; charset=utf-8')
content_type=as2.CONTENT_TYPE + '; charset=utf-8')
self.reply_html = """\
<html>
@ -154,7 +150,7 @@ class WebmentionTest(testutil.TestCase):
'displayName': 'Mrs. ☕ Foo',
'url': 'https://foo.com/about-me',
'inbox': 'https://foo.com/inbox',
}, content_type=CONTENT_TYPE_AS2)
}, content_type=as2.CONTENT_TYPE)
self.as2_create = {
'@context': 'https://www.w3.org/ns/activitystreams',
@ -437,7 +433,7 @@ class WebmentionTest(testutil.TestCase):
self.assertEqual(self.as2_create, json_loads(kwargs['data']))
headers = kwargs['headers']
self.assertEqual(CONTENT_TYPE_AS2, headers['Content-Type'])
self.assertEqual(as2.CONTENT_TYPE, headers['Content-Type'])
rsa_key = kwargs['auth'].header_signer._rsa._key
self.assertEqual(self.user.private_pem(), rsa_key.exportKey())
@ -513,7 +509,7 @@ class WebmentionTest(testutil.TestCase):
'id': 'http://orig/author',
}]
orig_as2_resp = requests_response(
self.orig_as2_data, content_type=CONTENT_TYPE_AS2 + '; charset=utf-8')
self.orig_as2_data, content_type=as2.CONTENT_TYPE + '; charset=utf-8')
mock_get.side_effect = [self.reply, self.not_fediverse, orig_as2_resp,
self.actor]
@ -557,7 +553,7 @@ class WebmentionTest(testutil.TestCase):
self.assertEqual(self.repost_as2, json_loads(kwargs['data']))
headers = kwargs['headers']
self.assertEqual(CONTENT_TYPE_AS2, headers['Content-Type'])
self.assertEqual(as2.CONTENT_TYPE, headers['Content-Type'])
rsa_key = kwargs['auth'].header_signer._rsa._key
self.assertEqual(self.user.private_pem(), rsa_key.exportKey())
@ -590,7 +586,7 @@ class WebmentionTest(testutil.TestCase):
self.req('http://a/reply'),
self.as2_req('http://not/fediverse'),
self.as2_req('http://orig/post'),
self.req('http://orig/as2', auth=mock.ANY, headers=CONNEG_HEADERS_AS2),
self.req('http://orig/as2', auth=mock.ANY, headers=as2.CONNEG_HEADERS),
self.as2_req('http://orig/author'),
))
@ -809,7 +805,7 @@ class WebmentionTest(testutil.TestCase):
self.assertEqual(self.follow_as2, json_loads(kwargs['data']))
headers = kwargs['headers']
self.assertEqual(CONTENT_TYPE_AS2, headers['Content-Type'])
self.assertEqual(as2.CONTENT_TYPE, headers['Content-Type'])
rsa_key = kwargs['auth'].header_signer._rsa._key
self.assertEqual(self.user.private_pem(), rsa_key.exportKey())
@ -870,7 +866,7 @@ class WebmentionTest(testutil.TestCase):
self.assert_equals(self.follow_fragment_as2, json_loads(kwargs['data']))
headers = kwargs['headers']
self.assert_equals(CONTENT_TYPE_AS2, headers['Content-Type'])
self.assert_equals(as2.CONTENT_TYPE, headers['Content-Type'])
rsa_key = kwargs['auth'].header_signer._rsa._key
self.assert_equals(self.user.private_pem(), rsa_key.exportKey())
@ -922,7 +918,7 @@ class WebmentionTest(testutil.TestCase):
self.assertEqual(self.follow_as2, json_loads(kwargs['data']))
headers = kwargs['headers']
self.assertEqual(CONTENT_TYPE_AS2, headers['Content-Type'])
self.assertEqual(as2.CONTENT_TYPE, headers['Content-Type'])
rsa_key = kwargs['auth'].header_signer._rsa._key
self.assertEqual(self.user.private_pem(), rsa_key.exportKey())

Wyświetl plik

@ -9,7 +9,7 @@ import re
import urllib.parse
from flask import render_template, request
from granary import as2, microformats2
from granary import as2, atom, microformats2
import mf2util
from oauth_dropins.webutil import flask_util, util
from oauth_dropins.webutil.flask_util import error
@ -74,11 +74,11 @@ class Actor(flask_util.XrdOrJrd):
user.put()
# discover atom feed, if any
atom = parsed.find('link', rel='alternate', type=common.CONTENT_TYPE_ATOM)
if atom and atom['href']:
atom = urllib.parse.urljoin(resp.url, atom['href'])
feed = parsed.find('link', rel='alternate', type=atom.CONTENT_TYPE)
if feed and feed['href']:
feed = urllib.parse.urljoin(resp.url, feed['href'])
else:
atom = 'https://granary.io/url?' + urllib.parse.urlencode({
feed = 'https://granary.io/url?' + urllib.parse.urlencode({
'input': 'html',
'output': 'atom',
'url': resp.url,
@ -114,29 +114,29 @@ class Actor(flask_util.XrdOrJrd):
# ActivityPub
{
'rel': 'self',
'type': common.CONTENT_TYPE_AS2,
'type': as2.CONTENT_TYPE,
# WARNING: in python 2 sometimes request.host_url lost port,
# http://localhost:8080 would become just http://localhost. no
# clue how or why. pay attention here if that happens again.
'href': common.host_url(domain),
}, {
'rel': 'inbox',
'type': common.CONTENT_TYPE_AS2,
'type': as2.CONTENT_TYPE,
'href': common.host_url(f'{domain}/inbox'),
}, {
# AP reads this from the AS2 actor, not webfinger, so strictly
# speaking, it's probably not needed here.
# https://www.w3.org/TR/activitypub/#sharedInbox
'rel': 'sharedInbox',
'type': common.CONTENT_TYPE_AS2,
'type': as2.CONTENT_TYPE,
'href': common.host_url('inbox'),
},
# OStatus
{
'rel': 'http://schemas.google.com/g/2010#updates-from',
'type': common.CONTENT_TYPE_ATOM,
'href': atom,
'type': atom.CONTENT_TYPE,
'href': feed,
}, {
'rel': 'hub',
'href': hub,