diff --git a/app/activitypub/routes.py b/app/activitypub/routes.py index 07b947a4..737335fb 100644 --- a/app/activitypub/routes.py +++ b/app/activitypub/routes.py @@ -902,36 +902,39 @@ def process_delete_request(request_json, activitypublog_id, ip_address): with current_app.app_context(): activity_log = ActivityPubLog.query.get(activitypublog_id) if 'type' in request_json and request_json['type'] == 'Delete': - actor_to_delete = request_json['object'].lower() - user = User.query.filter_by(ap_profile_id=actor_to_delete).first() - if user: - # check that the user really has been deleted, to avoid spoofing attacks - if not user.is_local(): - if user_removed_from_remote_server(actor_to_delete, is_piefed=user.instance.software == 'PieFed'): - # Delete all their images to save moderators from having to see disgusting stuff. - files = File.query.join(Post).filter(Post.user_id == user.id).all() - for file in files: - file.delete_from_disk() - file.source_url = '' - if user.avatar_id: - user.avatar.delete_from_disk() - user.avatar.source_url = '' - if user.cover_id: - user.cover.delete_from_disk() - user.cover.source_url = '' - user.banned = True - user.deleted = True - activity_log.result = 'success' + if isinstance(request_json['object'], dict): + current_app.logger.error('Cannot delete, dict provided: ' + str(request_json['object'])) + else: + actor_to_delete = request_json['object'].lower() + user = User.query.filter_by(ap_profile_id=actor_to_delete).first() + if user: + # check that the user really has been deleted, to avoid spoofing attacks + if not user.is_local(): + if user_removed_from_remote_server(actor_to_delete, is_piefed=user.instance.software == 'PieFed'): + # Delete all their images to save moderators from having to see disgusting stuff. + files = File.query.join(Post).filter(Post.user_id == user.id).all() + for file in files: + file.delete_from_disk() + file.source_url = '' + if user.avatar_id: + user.avatar.delete_from_disk() + user.avatar.source_url = '' + if user.cover_id: + user.cover.delete_from_disk() + user.cover.source_url = '' + user.banned = True + user.deleted = True + activity_log.result = 'success' + else: + activity_log.result = 'ignored' + activity_log.exception_message = 'User not actually deleted.' else: activity_log.result = 'ignored' - activity_log.exception_message = 'User not actually deleted.' + activity_log.exception_message = 'Only remote users can be deleted remotely' else: activity_log.result = 'ignored' - activity_log.exception_message = 'Only remote users can be deleted remotely' - else: - activity_log.result = 'ignored' - activity_log.exception_message = 'Does not exist here' - db.session.commit() + activity_log.exception_message = 'Does not exist here' + db.session.commit() def announce_activity_to_followers(community, creator, activity): diff --git a/app/activitypub/util.py b/app/activitypub/util.py index 26108d10..2ccef279 100644 --- a/app/activitypub/util.py +++ b/app/activitypub/util.py @@ -465,27 +465,32 @@ def refresh_community_profile_task(community_id): def actor_json_to_model(activity_json, address, server): if activity_json['type'] == 'Person': - user = User(user_name=activity_json['preferredUsername'], - title=activity_json['name'] if 'name' in activity_json else None, - email=f"{address}@{server}", - about_html=parse_summary(activity_json), - matrix_user_id=activity_json['matrixUserId'] if 'matrixUserId' in activity_json else '', - indexable=activity_json['indexable'] if 'indexable' in activity_json else False, - searchable=activity_json['discoverable'] if 'discoverable' in activity_json else True, - created=activity_json['published'] if 'published' in activity_json else utcnow(), - ap_id=f"{address}@{server}", - ap_public_url=activity_json['id'], - ap_profile_id=activity_json['id'].lower(), - ap_inbox_url=activity_json['endpoints']['sharedInbox'], - ap_followers_url=activity_json['followers'] if 'followers' in activity_json else None, - ap_preferred_username=activity_json['preferredUsername'], - ap_manually_approves_followers=activity_json['manuallyApprovesFollowers'] if 'manuallyApprovesFollowers' in activity_json else False, - ap_fetched_at=utcnow(), - ap_domain=server, - public_key=activity_json['publicKey']['publicKeyPem'], - instance_id=find_instance_id(server) - # language=community_json['language'][0]['identifier'] # todo: language - ) + try: + user = User(user_name=activity_json['preferredUsername'], + title=activity_json['name'] if 'name' in activity_json else None, + email=f"{address}@{server}", + about_html=parse_summary(activity_json), + matrix_user_id=activity_json['matrixUserId'] if 'matrixUserId' in activity_json else '', + indexable=activity_json['indexable'] if 'indexable' in activity_json else False, + searchable=activity_json['discoverable'] if 'discoverable' in activity_json else True, + created=activity_json['published'] if 'published' in activity_json else utcnow(), + ap_id=f"{address}@{server}", + ap_public_url=activity_json['id'], + ap_profile_id=activity_json['id'].lower(), + ap_inbox_url=activity_json['endpoints']['sharedInbox'], + ap_followers_url=activity_json['followers'] if 'followers' in activity_json else None, + ap_preferred_username=activity_json['preferredUsername'], + ap_manually_approves_followers=activity_json['manuallyApprovesFollowers'] if 'manuallyApprovesFollowers' in activity_json else False, + ap_fetched_at=utcnow(), + ap_domain=server, + public_key=activity_json['publicKey']['publicKeyPem'], + instance_id=find_instance_id(server) + # language=community_json['language'][0]['identifier'] # todo: language + ) + except KeyError as e: + current_app.logger.error(f'KeyError for {address}@{server} while parsing ' + str(activity_json)) + return None + if 'icon' in activity_json: avatar = File(source_url=activity_json['icon']['url']) user.avatar = avatar @@ -1271,7 +1276,9 @@ def notify_about_post(post: Post): def update_post_reply_from_activity(reply: PostReply, request_json: dict): - if 'source' in request_json['object'] and request_json['object']['source']['mediaType'] == 'text/markdown': + if 'source' in request_json['object'] and \ + isinstance(request_json['object']['source'], dict) and \ + request_json['object']['source']['mediaType'] == 'text/markdown': reply.body = request_json['object']['source']['content'] reply.body_html = markdown_to_html(reply.body) elif 'content' in request_json['object']: @@ -1283,7 +1290,9 @@ def update_post_reply_from_activity(reply: PostReply, request_json: dict): def update_post_from_activity(post: Post, request_json: dict): post.title = request_json['object']['name'] - if 'source' in request_json['object'] and request_json['object']['source']['mediaType'] == 'text/markdown': + if 'source' in request_json['object'] and \ + isinstance(request_json['object']['source'], dict) and \ + request_json['object']['source']['mediaType'] == 'text/markdown': post.body = request_json['object']['source']['content'] post.body_html = markdown_to_html(post.body) elif 'content' in request_json['object']: