Update resolve_remote_post_from_search() to not require 'audience' field

This commit is contained in:
freamon 2025-01-18 17:25:54 +00:00
parent ac6f66e892
commit dc5c0fd7b4

View file

@ -2400,112 +2400,92 @@ def resolve_remote_post(uri: str, community_id: int, announce_actor=None, store_
return None return None
# called from UI, via 'search' option in navbar
def resolve_remote_post_from_search(uri: str) -> Union[Post, None]: def resolve_remote_post_from_search(uri: str) -> Union[Post, None]:
post = Post.query.filter_by(ap_id=uri).first() post = Post.query.filter_by(ap_id=uri).first()
if post: if post:
return post return post
site = Site.query.get(1)
parsed_url = urlparse(uri) parsed_url = urlparse(uri)
uri_domain = parsed_url.netloc uri_domain = parsed_url.netloc
actor_domain = None actor_domain = None
actor = None actor = None
post_request = get_request(uri, headers={'Accept': 'application/activity+json'})
if post_request.status_code == 200:
post_data = post_request.json()
post_request.close()
# check again that it doesn't already exist (can happen with different but equivalent URLs)
post = Post.query.filter_by(ap_id=post_data['id']).first()
if post:
return post
# find the author of the post. Make sure their domain matches the site hosting it to mitigate impersonation attempts try:
if 'attributedTo' in post_data: object_request = get_request(uri, headers={'Accept': 'application/activity+json'})
attributed_to = post_data['attributedTo'] except httpx.HTTPError:
if isinstance(attributed_to, str): time.sleep(3)
actor = attributed_to try:
parsed_url = urlparse(actor) object_request = get_request(uri, headers={'Accept': 'application/activity+json'})
actor_domain = parsed_url.netloc except httpx.HTTPError:
elif isinstance(attributed_to, list): return None
for a in attributed_to: if object_request.status_code == 200:
if isinstance(a, dict) and a.get('type') == 'Person': try:
actor = a.get('id') post_data = object_request.json()
if isinstance(actor, str): # Ensure `actor` is a valid string except:
parsed_url = urlparse(actor) object_request.close()
actor_domain = parsed_url.netloc return None
break object_request.close()
elif isinstance(a, str): elif object_request.status_code == 401:
actor = a try:
site = Site.query.get(1)
object_request = signed_get_request(uri, site.private_key, f"https://{current_app.config['SERVER_NAME']}/actor#main-key")
except httpx.HTTPError:
time.sleep(3)
try:
object_request = signed_get_request(uri, site.private_key, f"https://{current_app.config['SERVER_NAME']}/actor#main-key")
except httpx.HTTPError:
return None
try:
post_data = object_request.json()
except:
object_request.close()
return None
object_request.close()
else:
return None
# check again that it doesn't already exist (can happen with different but equivalent URLs)
post = Post.query.filter_by(ap_id=post_data['id']).first()
if post:
return post
# find the author of the post. Make sure their domain matches the site hosting it to mitigate impersonation attempts
if 'attributedTo' in post_data:
attributed_to = post_data['attributedTo']
if isinstance(attributed_to, str):
actor = attributed_to
parsed_url = urlparse(actor)
actor_domain = parsed_url.netloc
elif isinstance(attributed_to, list):
for a in attributed_to:
if isinstance(a, dict) and a.get('type') == 'Person':
actor = a.get('id')
if isinstance(actor, str): # Ensure `actor` is a valid string
parsed_url = urlparse(actor) parsed_url = urlparse(actor)
actor_domain = parsed_url.netloc actor_domain = parsed_url.netloc
break break
if uri_domain != actor_domain: elif isinstance(a, str):
return None actor = a
parsed_url = urlparse(actor)
actor_domain = parsed_url.netloc
break
if uri_domain != actor_domain:
return None
# find the community the post was submitted to # find the community the post was submitted to
community = None community = find_community(post_data)
if not community and post_data['type'] == 'Page': # lemmy # find the post's author
if 'audience' in post_data: user = find_actor_or_create(actor)
community_id = post_data['audience'] if user and community and post_data:
community = find_actor_or_create(community_id, community_only=True) request_json = {'id': f"https://{uri_domain}/activities/create/gibberish(15)", 'object': post_data}
post = create_post(False, community, request_json, user)
if not community and post_data['type'] == 'Video': # peertube if post:
if 'attributedTo' in post_data and isinstance(post_data['attributedTo'], list): if 'published' in post_data:
for a in post_data['attributedTo']: post.posted_at=post_data['published']
if a['type'] == 'Group': post.last_active=post_data['published']
community_id = a['id'] db.session.commit()
community = find_actor_or_create(community_id, community_only=True) return post
if community:
break
if not community: # mastodon, etc
if 'inReplyTo' not in post_data or post_data['inReplyTo'] != None:
return None
if not community and 'to' in post_data and isinstance(post_data['to'], str):
community_id = post_data['to'].lower()
if not community_id == 'https://www.w3.org/ns/activitystreams#Public' and not community_id.endswith('/followers'):
community = Community.query.filter_by(ap_profile_id=community_id).first()
if not community and 'cc' in post_data and isinstance(post_data['cc'], str):
community_id = post_data['cc'].lower()
if not community_id == 'https://www.w3.org/ns/activitystreams#Public' and not community_id.endswith('/followers'):
community = Community.query.filter_by(ap_profile_id=community_id).first()
if not community and 'to' in post_data and isinstance(post_data['to'], list):
for t in post_data['to']:
community_id = t.lower()
if not community_id == 'https://www.w3.org/ns/activitystreams#Public' and not community_id.endswith('/followers'):
community = Community.query.filter_by(ap_profile_id=community_id).first()
if community:
break
if not community and 'cc' in post_data and isinstance(post_data['to'], list):
for c in post_data['cc']:
community_id = c.lower()
if not community_id == 'https://www.w3.org/ns/activitystreams#Public' and not community_id.endswith('/followers'):
community = Community.query.filter_by(ap_profile_id=community_id).first()
if community:
break
if not community:
return None
activity_log = ActivityPubLog(direction='in', activity_id=post_data['id'], activity_type='Resolve Post', result='failure')
if site.log_activitypub_json:
activity_log.activity_json = json.dumps(post_data)
db.session.add(activity_log)
user = find_actor_or_create(actor)
if user and community and post_data:
request_json = {
'id': f"https://{uri_domain}/activities/create/gibberish(15)",
'object': post_data
}
post = create_post(activity_log, community, request_json, user)
if post:
if 'published' in post_data:
post.posted_at=post_data['published']
post.last_active=post_data['published']
db.session.commit()
return post
return None return None