From 01fd3fa2ea91c3423abf648fc7a3f118e7631ccb Mon Sep 17 00:00:00 2001 From: freamon Date: Wed, 22 May 2024 22:30:51 +0100 Subject: [PATCH] Process Site and Community bans where removeData=True --- app/activitypub/routes.py | 20 ++++++++++++++- app/activitypub/util.py | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/app/activitypub/routes.py b/app/activitypub/routes.py index f6a8acc7..a976f170 100644 --- a/app/activitypub/routes.py +++ b/app/activitypub/routes.py @@ -21,7 +21,7 @@ from app.activitypub.util import public_key, users_total, active_half_year, acti upvote_post, delete_post_or_comment, community_members, \ user_removed_from_remote_server, create_post, create_post_reply, update_post_reply_from_activity, \ update_post_from_activity, undo_vote, undo_downvote, post_to_page, get_redis_connection, find_reported_object, \ - process_report, ensure_domains_match, can_edit, can_delete + process_report, ensure_domains_match, can_edit, can_delete, remove_data_from_banned_user from app.utils import gibberish, get_setting, is_image_url, allowlist_html, render_template, \ domain_from_url, markdown_to_html, community_membership, ap_datetime, ip_address, can_downvote, \ can_upvote, can_create_post, awaken_dormant_instance, shorten_string, can_create_post_reply, sha256_digest, \ @@ -805,6 +805,15 @@ def process_inbox_request(request_json, activitypublog_id, ip_address): if existing_membership: existing_membership.is_moderator = False activity_log.result = 'success' + elif request_json['object']['type'] == 'Block' and 'target' in request_json['object']: + activity_log.activity_type = 'Community Ban' + mod_ap_id = request_json['object']['actor'] + user_ap_id = request_json['object']['object'] + target = request_json['object']['target'] + remove_data = request_json['object']['removeData'] + if target == request_json['actor'] and remove_data == True: + remove_data_from_banned_user(mod_ap_id, user_ap_id, target) + activity_log.result = 'success' else: activity_log.exception_message = 'Invalid type for Announce' @@ -1081,6 +1090,15 @@ def process_inbox_request(request_json, activitypublog_id, ip_address): activity_log.result = 'success' else: activity_log.exception_message = 'Report ignored due to missing user or content' + elif request_json['type'] == 'Block': + activity_log.activity_type = 'Site Ban' + admin_ap_id = request_json['actor'] + user_ap_id = request_json['object'] + target = request_json['target'] + remove_data = request_json['removeData'] + if remove_data == True: + remove_data_from_banned_user(admin_ap_id, user_ap_id, target) + activity_log.result = 'success' # Flush the caches of any major object that was created. To be sure. if 'user' in vars() and user is not None: diff --git a/app/activitypub/util.py b/app/activitypub/util.py index bf1d191c..1155c454 100644 --- a/app/activitypub/util.py +++ b/app/activitypub/util.py @@ -1329,6 +1329,57 @@ def delete_post_or_comment_task(user_ap_id, community_ap_id, to_be_deleted_ap_id db.session.commit() +def remove_data_from_banned_user(deletor_ap_id, user_ap_id, target): + if current_app.debug: + remove_data_from_banned_user_task(deletor_ap_id, user_ap_id, target) + else: + remove_data_from_banned_user_task.delay(deletor_ap_id, user_ap_id, target) + + +@celery.task +def remove_data_from_banned_user_task(deletor_ap_id, user_ap_id, target): + deletor = find_actor_or_create(deletor_ap_id, create_if_not_found=False) + user = find_actor_or_create(user_ap_id, create_if_not_found=False) + community = Community.query.filter_by(ap_profile_id=target).first() + + if not deletor and not user: + return + + # site bans by admins + if deletor.instance.user_is_admin(deletor.id) and target == f"https://{deletor.instance.domain}/" and deletor.instance_id == user.instance_id: + post_replies = PostReply.query.filter_by(user_id=user.id) + posts = Post.query.filter_by(user_id=user.id) + + # community bans by mods + elif community and community.is_moderator(deletor): + post_replies = PostReply.query.filter_by(user_id=user.id, community_id=community.id) + posts = Post.query.filter_by(user_id=user.id, community_id=community.id) + + else: + return + + for pr in post_replies: + pr.post.reply_count -= 1 + if pr.has_replies(): + pr.body = 'Banned' + pr.body_html = lemmy_markdown_to_html(pr.body) + else: + pr.delete_dependencies() + db.session.delete(pr) + db.session.commit() + + for p in posts: + if p.cross_posts: + old_cross_posts = Post.query.filter(Post.id.in_(p.cross_posts)).all() + for ocp in old_cross_posts: + if ocp.cross_posts is not None: + ocp.cross_posts.remove(p.id) + p.delete_dependencies() + db.session.delete(p) + p.community.post_count -= 1 + db.session.commit() + + def create_post_reply(activity_log: ActivityPubLog, community: Community, in_reply_to, request_json: dict, user: User, announce_id=None) -> Union[Post, None]: if community.local_only: activity_log.exception_message = 'Community is local only, reply discarded'