kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
9a75d10f54
commit
51c2773594
|
@ -328,7 +328,7 @@ def postprocess_as2(activity, target=None, wrap=True):
|
||||||
if not activity or isinstance(activity, str):
|
if not activity or isinstance(activity, str):
|
||||||
return activity
|
return activity
|
||||||
|
|
||||||
assert bool(g.user) ^ bool(g.external_user) # should have one but not both
|
assert g.user
|
||||||
type = activity.get('type')
|
type = activity.get('type')
|
||||||
|
|
||||||
# actor objects
|
# actor objects
|
||||||
|
@ -396,14 +396,10 @@ def postprocess_as2(activity, target=None, wrap=True):
|
||||||
obj['id'] = util.get_first(obj, 'url') or target_id
|
obj['id'] = util.get_first(obj, 'url') or target_id
|
||||||
elif g.user and g.user.is_web_url(id):
|
elif g.user and g.user.is_web_url(id):
|
||||||
obj['id'] = g.user.ap_actor()
|
obj['id'] = g.user.ap_actor()
|
||||||
elif g.external_user:
|
|
||||||
obj['id'] = redirect_wrap(g.external_user)
|
|
||||||
|
|
||||||
# for Accepts
|
# for Accepts
|
||||||
if g.user and g.user.is_web_url(obj.get('object')):
|
if g.user and g.user.is_web_url(obj.get('object')):
|
||||||
obj['object'] = g.user.ap_actor()
|
obj['object'] = g.user.ap_actor()
|
||||||
elif g.external_user and g.external_user == obj.get('object'):
|
|
||||||
obj['object'] = redirect_wrap(g.external_user)
|
|
||||||
|
|
||||||
# id is required for most things. default to url if it's not set.
|
# id is required for most things. default to url if it's not set.
|
||||||
if not activity.get('id'):
|
if not activity.get('id'):
|
||||||
|
@ -506,8 +502,6 @@ def postprocess_as2_actor(actor, wrap=True):
|
||||||
id = actor.get('id')
|
id = actor.get('id')
|
||||||
if g.user and (not id or g.user.is_web_url(id)):
|
if g.user and (not id or g.user.is_web_url(id)):
|
||||||
actor['id'] = g.user.ap_actor()
|
actor['id'] = g.user.ap_actor()
|
||||||
elif g.external_user and (not id or id == g.external_user):
|
|
||||||
actor['id'] = redirect_wrap(g.external_user)
|
|
||||||
|
|
||||||
actor.update({
|
actor.update({
|
||||||
'url': urls if len(urls) > 1 else urls[0],
|
'url': urls if len(urls) > 1 else urls[0],
|
||||||
|
|
|
@ -39,9 +39,8 @@ def init_globals():
|
||||||
"""Set request globals.
|
"""Set request globals.
|
||||||
|
|
||||||
* g.user: Current internal user we're operating on behalf of.
|
* g.user: Current internal user we're operating on behalf of.
|
||||||
* g.external_user: Current external user we're operating on behalf of.
|
|
||||||
"""
|
"""
|
||||||
g.user = g.external_user = None
|
g.user = None
|
||||||
|
|
||||||
# don't redirect API requests with blank path elements
|
# don't redirect API requests with blank path elements
|
||||||
app.url_map.merge_slashes = False
|
app.url_map.merge_slashes = False
|
||||||
|
|
11
redirect.py
11
redirect.py
|
@ -83,10 +83,7 @@ def redir(to):
|
||||||
logger.info(f'Found web user for domain {domain}')
|
logger.info(f'Found web user for domain {domain}')
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if accept_as2:
|
if not accept_as2:
|
||||||
g.external_user = urllib.parse.urljoin(to, '/')
|
|
||||||
logging.info(f'No web user for {g.external_user}')
|
|
||||||
else:
|
|
||||||
return f'No web user found for any of {domains}', 404
|
return f'No web user found for any of {domains}', 404
|
||||||
|
|
||||||
if accept_as2:
|
if accept_as2:
|
||||||
|
@ -94,6 +91,12 @@ def redir(to):
|
||||||
obj = Web.load(to, check_backlink=False)
|
obj = Web.load(to, check_backlink=False)
|
||||||
if not obj or obj.deleted:
|
if not obj or obj.deleted:
|
||||||
return f'Object not found: {to}', 404
|
return f'Object not found: {to}', 404
|
||||||
|
|
||||||
|
g.user = Web.get_or_create(util.domain_from_link(to), direct=False)
|
||||||
|
if g.user.is_web_url(to):
|
||||||
|
g.user.actor_as2 = as2.from_as1(obj.as1)
|
||||||
|
g.user.put()
|
||||||
|
|
||||||
ret, _ = ActivityPub.serve(obj)
|
ret, _ = ActivityPub.serve(obj)
|
||||||
logger.info(f'Returning: {json_dumps(ret, indent=2)}')
|
logger.info(f'Returning: {json_dumps(ret, indent=2)}')
|
||||||
return ret, {
|
return ret, {
|
||||||
|
|
|
@ -65,6 +65,15 @@ ACTOR_BASE = {
|
||||||
'publicKeyPem': 'populated in setUp()',
|
'publicKeyPem': 'populated in setUp()',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
ACTOR_BASE_FULL = {
|
||||||
|
**ACTOR_BASE,
|
||||||
|
'name': 'Ms. ☕ Baz',
|
||||||
|
'attachment': [{
|
||||||
|
'name': 'Web site',
|
||||||
|
'type': 'PropertyValue',
|
||||||
|
'value': '<a rel="me" href="https://user.com/">user.com</a>',
|
||||||
|
}],
|
||||||
|
}
|
||||||
REPLY_OBJECT = {
|
REPLY_OBJECT = {
|
||||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
'type': 'Note',
|
'type': 'Note',
|
||||||
|
@ -347,15 +356,7 @@ class ActivityPubTest(TestCase):
|
||||||
|
|
||||||
got = self.client.get('/user.com')
|
got = self.client.get('/user.com')
|
||||||
self.assertEqual(200, got.status_code)
|
self.assertEqual(200, got.status_code)
|
||||||
self.assert_equals({
|
self.assert_equals(ACTOR_BASE_FULL, got.json, ignore=['publicKeyPem'])
|
||||||
**ACTOR_BASE,
|
|
||||||
'name': 'Ms. ☕ Baz',
|
|
||||||
'attachment': [{
|
|
||||||
'name': 'Web site',
|
|
||||||
'type': 'PropertyValue',
|
|
||||||
'value': '<a rel="me" href="https://user.com/">user.com</a>',
|
|
||||||
}],
|
|
||||||
}, got.json, ignore=['publicKeyPem'])
|
|
||||||
|
|
||||||
def test_actor_new_user_fetch_no_mf2(self, _, mock_get, __):
|
def test_actor_new_user_fetch_no_mf2(self, _, mock_get, __):
|
||||||
self.user.key.delete()
|
self.user.key.delete()
|
||||||
|
|
|
@ -13,6 +13,9 @@ from . import testutil
|
||||||
from common import redirect_unwrap
|
from common import redirect_unwrap
|
||||||
from flask_app import app, cache
|
from flask_app import app, cache
|
||||||
from models import Object, User
|
from models import Object, User
|
||||||
|
from web import Web
|
||||||
|
|
||||||
|
from .test_activitypub import ACTOR_BASE_FULL
|
||||||
from .test_web import (
|
from .test_web import (
|
||||||
ACTOR_AS2,
|
ACTOR_AS2,
|
||||||
ACTOR_AS2_FULL,
|
ACTOR_AS2_FULL,
|
||||||
|
@ -27,9 +30,6 @@ REPOST_AS2 = {
|
||||||
}
|
}
|
||||||
del REPOST_AS2['cc']
|
del REPOST_AS2['cc']
|
||||||
|
|
||||||
EXTERNAL_REPOST_AS2 = copy.deepcopy(REPOST_AS2)
|
|
||||||
EXTERNAL_REPOST_AS2['actor']['id'] = 'http://localhost/r/https://user.com/'
|
|
||||||
|
|
||||||
|
|
||||||
class RedirectTest(testutil.TestCase):
|
class RedirectTest(testutil.TestCase):
|
||||||
|
|
||||||
|
@ -71,14 +71,16 @@ class RedirectTest(testutil.TestCase):
|
||||||
|
|
||||||
def test_as2_creates_user(self):
|
def test_as2_creates_user(self):
|
||||||
with self.request_context:
|
with self.request_context:
|
||||||
Object(id='https://user.com/repost', as2=EXTERNAL_REPOST_AS2).put()
|
Object(id='https://user.com/repost', as2=REPOST_AS2).put()
|
||||||
|
|
||||||
self.user.key.delete()
|
self.user.key.delete()
|
||||||
|
|
||||||
resp = self.client.get('/r/https://user.com/repost',
|
resp = self.client.get('/r/https://user.com/repost',
|
||||||
headers={'Accept': as2.CONTENT_TYPE})
|
headers={'Accept': as2.CONTENT_TYPE})
|
||||||
self.assertEqual(200, resp.status_code, resp.get_data(as_text=True))
|
self.assertEqual(200, resp.status_code, resp.get_data(as_text=True))
|
||||||
self.assert_equals(EXTERNAL_REPOST_AS2, resp.json)
|
self.assert_equals(REPOST_AS2, resp.json)
|
||||||
|
|
||||||
|
self.assert_user(Web, 'user.com', direct=False)
|
||||||
|
|
||||||
@patch('requests.get')
|
@patch('requests.get')
|
||||||
def test_as2_fetch_post(self, mock_get):
|
def test_as2_fetch_post(self, mock_get):
|
||||||
|
@ -107,16 +109,26 @@ class RedirectTest(testutil.TestCase):
|
||||||
resp = self.client.get('/r/https://user.com/',
|
resp = self.client.get('/r/https://user.com/',
|
||||||
headers={'Accept': as2.CONTENT_TYPE})
|
headers={'Accept': as2.CONTENT_TYPE})
|
||||||
self.assertEqual(200, resp.status_code, resp.get_data(as_text=True))
|
self.assertEqual(200, resp.status_code, resp.get_data(as_text=True))
|
||||||
self.assert_equals({
|
|
||||||
**ACTOR_AS2,
|
expected = copy.deepcopy(ACTOR_BASE_FULL)
|
||||||
'id': 'http://localhost/r/https://user.com/',
|
del expected['endpoints']
|
||||||
'summary': '',
|
del expected['followers']
|
||||||
|
del expected['following']
|
||||||
|
del expected['inbox']
|
||||||
|
del expected['outbox']
|
||||||
|
self.assert_equals(expected, resp.json, ignore=['publicKeyPem'])
|
||||||
|
|
||||||
|
self.assert_user(Web, 'user.com', direct=False, actor_as2={
|
||||||
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
|
'type': 'Person',
|
||||||
|
'url': 'https://user.com/',
|
||||||
|
'name': 'Ms. ☕ Baz',
|
||||||
'attachment': [{
|
'attachment': [{
|
||||||
'name': 'Ms. ☕ Baz',
|
|
||||||
'type': 'PropertyValue',
|
'type': 'PropertyValue',
|
||||||
|
'name': 'Ms. ☕ Baz',
|
||||||
'value': '<a rel="me" href="https://user.com/">user.com</a>',
|
'value': '<a rel="me" href="https://user.com/">user.com</a>',
|
||||||
}],
|
}],
|
||||||
}, resp.json)
|
})
|
||||||
|
|
||||||
def test_accept_header_cache_key(self):
|
def test_accept_header_cache_key(self):
|
||||||
app.config['CACHE_TYPE'] = 'SimpleCache'
|
app.config['CACHE_TYPE'] = 'SimpleCache'
|
||||||
|
|
|
@ -69,7 +69,6 @@ ACTOR_AS2_FULL = {
|
||||||
'https://www.w3.org/ns/activitystreams',
|
'https://www.w3.org/ns/activitystreams',
|
||||||
'https://w3id.org/security/v1',
|
'https://w3id.org/security/v1',
|
||||||
],
|
],
|
||||||
'preferredUsername': 'user.com',
|
|
||||||
'attachment': [{
|
'attachment': [{
|
||||||
'name': 'Web site',
|
'name': 'Web site',
|
||||||
'type': 'PropertyValue',
|
'type': 'PropertyValue',
|
||||||
|
|
|
@ -207,7 +207,7 @@ class WebfingerTest(testutil.TestCase):
|
||||||
self.assertEqual(404, got.status_code)
|
self.assertEqual(404, got.status_code)
|
||||||
|
|
||||||
@patch('requests.get')
|
@patch('requests.get')
|
||||||
def test_webfinger_external_user_fetch_create_user(self, mock_get):
|
def test_webfinger_fetch_create_user(self, mock_get):
|
||||||
self.user.key.delete()
|
self.user.key.delete()
|
||||||
mock_get.return_value = requests_response(ACTOR_HTML)
|
mock_get.return_value = requests_response(ACTOR_HTML)
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue