Skip to content

Commit b5a1f32

Browse files
committed
/convert/: when checking that author is bridged, handle cross-protocol reposts
for #1248, https://console.cloud.google.com/errors/detail/CJmhz9SqmcO6vQE;time=P7D;locations=global?project=bridgy-federated
1 parent 2adc661 commit b5a1f32

File tree

2 files changed

+31
-13
lines changed

2 files changed

+31
-13
lines changed

convert.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,14 @@ def convert(to, _, from_=None):
7474
if type == 'share':
7575
# TODO: should this be Source.base_object? That's broad
7676
# though, includes inReplyTo
77-
check_bridged_to(obj_obj, from_proto=from_proto,
78-
to_proto=to_proto)
77+
check_bridged_to(obj_obj, to_proto=to_proto)
7978
elif (type in as1.CRUD_VERBS
8079
and obj_obj.as1
8180
and obj_obj.as1.keys() - set(['id', 'url', 'objectType'])):
8281
logger.info(f'{type} activity, redirecting to Object {obj_id}')
8382
return redirect(f'/{path_prefix}{obj_id}', code=301)
8483

85-
check_bridged_to(obj, from_proto=from_proto, to_proto=to_proto)
84+
check_bridged_to(obj, to_proto=to_proto)
8685

8786
# convert and serve
8887
return to_proto.convert(obj), {
@@ -91,12 +90,11 @@ def convert(to, _, from_=None):
9190
}
9291

9392

94-
def check_bridged_to(obj, from_proto, to_proto):
93+
def check_bridged_to(obj, to_proto):
9594
"""If ``object`` or its owner isn't bridged to ``to_proto``, raises :class:`werkzeug.exceptions.HTTPException`.
9695
9796
Args:
9897
obj (models.Object)
99-
from_proto (subclass of protocol.Protocol)
10098
to_proto (subclass of protocol.Protocol)
10199
"""
102100
# don't serve deletes or deleted objects
@@ -109,9 +107,10 @@ def check_bridged_to(obj, from_proto, to_proto):
109107

110108
# check that owner has this protocol enabled
111109
if owner := as1.get_owner(obj.as1):
112-
user = from_proto.get_or_create(owner)
113-
if not user or not user.is_enabled(to_proto):
114-
error(f"{from_proto.LABEL} user {owner} isn't bridged to {to_proto.LABEL}", status=404)
110+
if from_proto := Protocol.for_id(owner):
111+
user = from_proto.get_or_create(owner)
112+
if not user or not user.is_enabled(to_proto):
113+
error(f"{from_proto.LABEL} user {owner} isn't bridged to {to_proto.LABEL}", status=404)
115114

116115

117116
@app.get('/render')

tests/test_convert.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def test_fake_to_other_no_copy(self):
127127
self.assertEqual(404, resp.status_code)
128128

129129
@patch.object(Fake, 'HAS_COPIES', new=False)
130-
def test_fake_to_other_user_not_enabled(self):
130+
def test_eefake_to_other_user_not_enabled(self):
131131
"""https://github.com/snarfed/bridgy-fed/issues/1248"""
132132
self.make_user('eefake:user', cls=ExplicitEnableFake, enabled_protocols=[])
133133
self.store_object(id='eefake:post', our_as1={'author': 'eefake:user'},
@@ -137,7 +137,7 @@ def test_fake_to_other_user_not_enabled(self):
137137
base_url='https://eefake.brid.gy/')
138138
self.assertEqual(404, resp.status_code)
139139

140-
def test_fake_to_other_repost_original_post_no_copy(self):
140+
def test_eefake_to_other_repost_original_post_no_copy(self):
141141
"""https://github.com/snarfed/bridgy-fed/issues/1248"""
142142
self.make_user('eefake:user', cls=ExplicitEnableFake,
143143
enabled_protocols=['other'])
@@ -153,12 +153,12 @@ def test_fake_to_other_repost_original_post_no_copy(self):
153153
'actor': 'eefake:user',
154154
})
155155

156-
resp = self.client.get(f'/convert/other/fake:repost',
157-
base_url='https://fa.brid.gy/')
156+
resp = self.client.get(f'/convert/other/eefake:repost',
157+
base_url='https://eefake.brid.gy/')
158158
self.assertEqual(404, resp.status_code)
159159

160160
@patch.object(Fake, 'HAS_COPIES', new=False)
161-
def test_fake_to_other_repost_original_author_not_enabled(self):
161+
def test_eefake_to_other_repost_original_author_not_enabled(self):
162162
"""https://github.com/snarfed/bridgy-fed/issues/1248"""
163163
self.make_user('eefake:user', cls=ExplicitEnableFake,
164164
enabled_protocols=['other'])
@@ -173,6 +173,24 @@ def test_fake_to_other_repost_original_author_not_enabled(self):
173173
'actor': 'eefake:user',
174174
})
175175

176+
resp = self.client.get(f'/convert/other/eefake:repost',
177+
base_url='https://eefake.brid.gy/')
178+
self.assertEqual(404, resp.status_code)
179+
180+
@patch.object(Fake, 'HAS_COPIES', new=False)
181+
def test_fake_to_other_repost_of_eefake_original_author_not_enabled(self):
182+
self.make_user('fake:user', cls=Fake, enabled_protocols=['other'])
183+
self.make_user('eefake:orig-user', cls=ExplicitEnableFake,
184+
enabled_protocols=['fake']) # not other
185+
186+
self.store_object(id='eefake:post', our_as1={'author': 'eefake:orig-user'})
187+
self.store_object(id='fake:repost', our_as1={
188+
'objectType': 'activity',
189+
'verb': 'share',
190+
'object': 'eefake:post',
191+
'actor': 'fake:user',
192+
})
193+
176194
resp = self.client.get(f'/convert/other/fake:repost',
177195
base_url='https://fa.brid.gy/')
178196
self.assertEqual(404, resp.status_code)
@@ -385,6 +403,7 @@ def test_web_to_activitypub_no_user(self, mock_get):
385403
hcard,
386404
hcard,
387405
hcard,
406+
requests_response(status=404), # webfinger for protocol inference
388407
requests_response('<html></html>'), # user for is_enabled protocol check
389408
]
390409

0 commit comments

Comments
 (0)