Skip to content

Commit

Permalink
activitypub: move postprocess_as2_actor out of postprocess_as2
Browse files Browse the repository at this point in the history
...and into ActivityPub.convert and actor handler directly. for #690
  • Loading branch information
snarfed committed Nov 24, 2023
1 parent ee571e5 commit 69ac7ea
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 29 deletions.
52 changes: 28 additions & 24 deletions activitypub.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,18 +336,25 @@ def convert(cls, obj, **kwargs):
# AP implementations choke on objects.
# https://github.com/snarfed/bridgy-fed/issues/658
#
# TODO: expand this to general purpose compact() function and use elsewhere,
# eg in models.resolve_id
# TODO: expand this to general purpose compact() function and use
# elsewhere, eg in models.resolve_id
for o in translated, as1.get_object(translated):
for field in 'actor', 'attributedTo', 'author':
actors = as1.get_objects(o, field)
ids = [a['id'] for a in actors if a.get('id')]
o[field] = ids[0] if len(ids) == 1 else ids

converted = as2.from_as1(translated)

if obj.source_protocol in ('ap', 'activitypub'):
return converted

if converted.get('type') == 'Person':
return postprocess_as2_actor(converted)

if as1.get_object(converted).get('type') == 'Person':
converted['object'] = postprocess_as2_actor(converted['object'])

return postprocess_as2(converted, **kwargs)

@classmethod
Expand Down Expand Up @@ -549,25 +556,6 @@ def postprocess_as2(activity, orig_obj=None, wrap=True):

type = activity.get('type')

# actor objects
if type == 'Person':
postprocess_as2_actor(activity)
if g.user and not activity.get('publicKey'):
# underspecified, inferred from this issue and Mastodon's implementation:
# https://github.com/w3c/activitypub/issues/203#issuecomment-297553229
# https://github.com/tootsuite/mastodon/blob/bc2c263504e584e154384ecc2d804aeb1afb1ba3/app/services/activitypub/process_account_service.rb#L77
actor_url = g.user.ap_actor()
activity.update({
'publicKey': {
'id': f'{actor_url}#key',
'owner': actor_url,
'publicKeyPem': g.user.public_pem().decode(),
},
'@context': (util.get_list(activity, '@context') +
['https://w3id.org/security/v1']),
})
return activity

# inReplyTo: singly valued, prefer id over url
# TODO: ignore orig_obj, do for all inReplyTo
orig_id = orig_obj.get('id') if orig_obj else None
Expand Down Expand Up @@ -714,15 +702,15 @@ def postprocess_as2_actor(actor, wrap=True):
return g.user.ap_actor()
return redirect_wrap(actor)

url = g.user.web_url() if g.user else None
url = g.user.web_url()
urls = util.get_list(actor, 'url')
if not urls and url:
urls = [url]
if urls and wrap:
urls[0] = redirect_wrap(urls[0])

id = actor.get('id')
if g.user and (not id or g.user.is_web_url(id)):
if not id or g.user.is_web_url(id):
actor['id'] = g.user.ap_actor()

actor['url'] = urls[0] if len(urls) == 1 else urls
Expand Down Expand Up @@ -754,6 +742,22 @@ def postprocess_as2_actor(actor, wrap=True):

# required by pixelfed. https://github.com/snarfed/bridgy-fed/issues/39
actor.setdefault('summary', '')

if not actor.get('publicKey'):
# underspecified, inferred from this issue and Mastodon's implementation:
# https://github.com/w3c/activitypub/issues/203#issuecomment-297553229
# https://github.com/tootsuite/mastodon/blob/bc2c263504e584e154384ecc2d804aeb1afb1ba3/app/services/activitypub/process_account_service.rb#L77
actor_url = g.user.ap_actor()
actor.update({
'publicKey': {
'id': f'{actor_url}#key',
'owner': actor_url,
'publicKeyPem': g.user.public_pem().decode(),
},
'@context': (util.get_list(actor, '@context') +
['https://w3id.org/security/v1']),
})

return actor


Expand Down Expand Up @@ -799,7 +803,7 @@ def actor(handle_or_id):
'@context': [as2.CONTEXT],
'type': 'Person',
}
actor = postprocess_as2(actor)
actor = postprocess_as2_actor(actor)
actor.update({
'id': user.ap_actor(),
'inbox': user.ap_actor('inbox'),
Expand Down
15 changes: 10 additions & 5 deletions tests/test_activitypub.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@
from .testutil import Fake, TestCase

import activitypub
from activitypub import ActivityPub, default_signature_user, postprocess_as2
from activitypub import (
ActivityPub,
default_signature_user,
postprocess_as2,
postprocess_as2_actor,
)
from atproto import ATProto
import common
from models import Follower, Object
Expand Down Expand Up @@ -1773,9 +1778,9 @@ def test_postprocess_as2_hashtag(self):
],
}))

def test_postprocess_as2_url_attachments(self):
def test_postprocess_as2_actor_url_attachments(self):
g.user = self.user
got = postprocess_as2(as2.from_as1({
got = postprocess_as2_actor(as2.from_as1({
'objectType': 'person',
'urls': [
{
Expand Down Expand Up @@ -1813,12 +1818,12 @@ def test_postprocess_as2_url_attachments(self):
'value': '<a rel="me" href="https://two"><span class="invisible">https://</span>two</a>',
}], got['attachment'])

def test_postprocess_as2_preserves_preferredUsername(self):
def test_postprocess_as2_actor_preserves_preferredUsername(self):
# preferredUsername stays y.z despite user's username. since Mastodon
# queries Webfinger for [email protected]
# https://github.com/snarfed/bridgy-fed/issues/77#issuecomment-949955109
g.user = self.user
self.assertEqual('user.com', postprocess_as2({
self.assertEqual('user.com', postprocess_as2_actor({
'type': 'Person',
'url': 'https://user.com/about-me',
'preferredUsername': 'nick',
Expand Down
1 change: 1 addition & 0 deletions tests/test_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -1592,6 +1592,7 @@ def test_update_profile(self, mock_get, mock_post):
**ACTOR_AS2,
'attachment': ACTOR_AS2_FULL['attachment'],
'updated': NOW.isoformat(),
'to': ['https://www.w3.org/ns/activitystreams#Public'],
},
'to': ['https://www.w3.org/ns/activitystreams#Public'],
}
Expand Down

0 comments on commit 69ac7ea

Please sign in to comment.