diff --git a/app/admin.py b/app/admin.py index d8a5ca4..85a0bc2 100644 --- a/app/admin.py +++ b/app/admin.py @@ -850,6 +850,30 @@ async def admin_profile( ) +@router.post("/actions/force_delete") +async def admin_actions_force_delete( + request: Request, + ap_object_id: str = Form(), + redirect_url: str = Form(), + csrf_check: None = Depends(verify_csrf_token), + db_session: AsyncSession = Depends(get_db_session), +) -> RedirectResponse: + ap_object_to_delete = await get_inbox_object_by_ap_id(db_session, ap_object_id) + if not ap_object_to_delete: + raise ValueError(f"Cannot find {ap_object_id}") + + logger.info(f"Deleting {ap_object_to_delete.ap_type}/{ap_object_to_delete.ap_id}") + await boxes._revert_side_effect_for_deleted_object( + db_session, + None, + ap_object_to_delete, + None, + ) + ap_object_to_delete.is_deleted = True + await db_session.commit() + return RedirectResponse(redirect_url, status_code=302) + + @router.post("/actions/follow") async def admin_actions_follow( request: Request, diff --git a/app/boxes.py b/app/boxes.py index ac56793..6b16b26 100644 --- a/app/boxes.py +++ b/app/boxes.py @@ -1186,7 +1186,7 @@ async def _get_replies_count( async def _revert_side_effect_for_deleted_object( db_session: AsyncSession, - delete_activity: models.InboxObject, + delete_activity: models.InboxObject | None, deleted_ap_object: models.InboxObject, forwarded_by_actor: models.Actor | None, ) -> None: @@ -1223,7 +1223,7 @@ async def _revert_side_effect_for_deleted_object( .where( models.OutboxObject.id == replied_object.id, ) - .values(replies_count=new_replies_count) + .values(replies_count=new_replies_count - 1) ) else: new_replies_count = await _get_replies_count( @@ -1235,7 +1235,7 @@ async def _revert_side_effect_for_deleted_object( .where( models.InboxObject.id == replied_object.id, ) - .values(replies_count=new_replies_count) + .values(replies_count=new_replies_count - 1) ) if deleted_ap_object.ap_type == "Like" and deleted_ap_object.activity_object_ap_id: @@ -1282,7 +1282,8 @@ async def _revert_side_effect_for_deleted_object( # If it's a local replies, it was forwarded, so we also need to forward # the Delete activity if possible if ( - delete_activity.activity_object_ap_id == deleted_ap_object.ap_id + delete_activity + and delete_activity.activity_object_ap_id == deleted_ap_object.ap_id and delete_activity.has_ld_signature and is_delete_needs_to_be_forwarded ): diff --git a/app/templates/utils.html b/app/templates/utils.html index ddd0af7..1205c6b 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -131,6 +131,17 @@ {% endblock %} {% endmacro %} +{% macro admin_force_delete_button(ap_object_id, permalink_id=None) %} +{% block admin_force_delete_button scoped %} +
+ {{ embed_csrf_token() }} + {{ embed_redirect_url(permalink_id) }} + + +
+{% endblock %} +{% endmacro %} + {% macro admin_announce_button(ap_object_id, permalink_id=None) %} {% block admin_announce_button scoped %}
@@ -682,6 +693,11 @@ {{ admin_expand_button(object) }} {% endif %} + {% if object.is_from_inbox %} +
  • + {{ admin_force_delete_button(object.ap_id) }} +
  • + {% endif %} {% endif %}