-
-
Notifications
You must be signed in to change notification settings - Fork 936
Adding admin purging of DB items and pictures. #904 #1331 #1809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
377c5b2
1671eb6
4d3a210
47a2683
2175426
7bd0ff2
020b658
d011b7a
0886369
f1b0c23
06d51a2
3456da1
c57c5cb
01fb200
dbfbd2c
7de237e
a90fa0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| mod config; | ||
| mod leave_admin; | ||
| mod mod_log; | ||
| mod purge; | ||
| mod registration_applications; | ||
| mod resolve_object; | ||
| mod search; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| use crate::Perform; | ||
| use actix_web::web::Data; | ||
| use lemmy_api_common::{ | ||
| site::{PurgeComment, PurgeItemResponse}, | ||
| utils::{blocking, get_local_user_view_from_jwt, is_admin}, | ||
| }; | ||
| use lemmy_db_schema::{ | ||
| source::{ | ||
| comment::Comment, | ||
| moderator::{AdminPurgeComment, AdminPurgeCommentForm}, | ||
| }, | ||
| traits::Crud, | ||
| }; | ||
| use lemmy_utils::{ConnectionId, LemmyError}; | ||
| use lemmy_websocket::LemmyContext; | ||
|
|
||
| #[async_trait::async_trait(?Send)] | ||
| impl Perform for PurgeComment { | ||
| type Response = PurgeItemResponse; | ||
|
|
||
| #[tracing::instrument(skip(context, _websocket_id))] | ||
| async fn perform( | ||
| &self, | ||
| context: &Data<LemmyContext>, | ||
| _websocket_id: Option<ConnectionId>, | ||
| ) -> Result<Self::Response, LemmyError> { | ||
| let data: &Self = self; | ||
| let local_user_view = | ||
| get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; | ||
|
|
||
| // Only let admins purge an item | ||
| is_admin(&local_user_view)?; | ||
|
|
||
| let comment_id = data.comment_id; | ||
|
|
||
| // Read the comment to get the post_id | ||
| let comment = blocking(context.pool(), move |conn| Comment::read(conn, comment_id)).await??; | ||
|
|
||
| let post_id = comment.post_id; | ||
|
|
||
| // TODO read comments for pictrs images and purge them | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is about inline images in comments, right? And similarly for inline images in post body, community/user profile. Those are generally tricky to manage. Easiest option would be not to permit inline images, otherwise we will have to add some functionality to retrieve them sooner or later.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. We could have something that scans through every comment, post body, bio, community sidebar... ( there's probably a few others I'm not thinking of), does a regex search for pictrs URLs, and tries to remove them. IMO that's a little excessive, but it might be necessary later on. I'll just leave that TODO in there to remind us. |
||
|
|
||
| blocking(context.pool(), move |conn| { | ||
| Comment::delete(conn, comment_id) | ||
| }) | ||
| .await??; | ||
|
|
||
| // Mod tables | ||
| let reason = data.reason.to_owned(); | ||
| let form = AdminPurgeCommentForm { | ||
| admin_person_id: local_user_view.person.id, | ||
| reason, | ||
| post_id, | ||
| }; | ||
|
|
||
| blocking(context.pool(), move |conn| { | ||
| AdminPurgeComment::create(conn, &form) | ||
| }) | ||
| .await??; | ||
|
|
||
| Ok(PurgeItemResponse { success: true }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| use crate::Perform; | ||
| use actix_web::web::Data; | ||
| use lemmy_api_common::{ | ||
| request::purge_image_from_pictrs, | ||
| site::{PurgeCommunity, PurgeItemResponse}, | ||
| utils::{blocking, get_local_user_view_from_jwt, is_admin, purge_image_posts_for_community}, | ||
| }; | ||
| use lemmy_db_schema::{ | ||
| source::{ | ||
| community::Community, | ||
| moderator::{AdminPurgeCommunity, AdminPurgeCommunityForm}, | ||
| }, | ||
| traits::Crud, | ||
| }; | ||
| use lemmy_utils::{ConnectionId, LemmyError}; | ||
| use lemmy_websocket::LemmyContext; | ||
|
|
||
| #[async_trait::async_trait(?Send)] | ||
| impl Perform for PurgeCommunity { | ||
| type Response = PurgeItemResponse; | ||
|
|
||
| #[tracing::instrument(skip(context, _websocket_id))] | ||
| async fn perform( | ||
| &self, | ||
| context: &Data<LemmyContext>, | ||
| _websocket_id: Option<ConnectionId>, | ||
| ) -> Result<Self::Response, LemmyError> { | ||
| let data: &Self = self; | ||
| let local_user_view = | ||
| get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; | ||
|
|
||
| // Only let admins purge an item | ||
| is_admin(&local_user_view)?; | ||
|
|
||
| let community_id = data.community_id; | ||
|
|
||
| // Read the community to get its images | ||
| let community = blocking(context.pool(), move |conn| { | ||
| Community::read(conn, community_id) | ||
| }) | ||
| .await??; | ||
|
|
||
| if let Some(banner) = community.banner { | ||
| purge_image_from_pictrs(context.client(), &context.settings(), &banner) | ||
| .await | ||
| .ok(); | ||
| } | ||
|
|
||
| if let Some(icon) = community.icon { | ||
| purge_image_from_pictrs(context.client(), &context.settings(), &icon) | ||
| .await | ||
| .ok(); | ||
| } | ||
|
|
||
| purge_image_posts_for_community( | ||
| community_id, | ||
| context.pool(), | ||
| &context.settings(), | ||
| context.client(), | ||
| ) | ||
| .await?; | ||
|
|
||
| blocking(context.pool(), move |conn| { | ||
| Community::delete(conn, community_id) | ||
| }) | ||
| .await??; | ||
|
|
||
| // Mod tables | ||
| let reason = data.reason.to_owned(); | ||
| let form = AdminPurgeCommunityForm { | ||
| admin_person_id: local_user_view.person.id, | ||
| reason, | ||
| }; | ||
|
|
||
| blocking(context.pool(), move |conn| { | ||
| AdminPurgeCommunity::create(conn, &form) | ||
| }) | ||
| .await??; | ||
|
|
||
| Ok(PurgeItemResponse { success: true }) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| mod comment; | ||
| mod community; | ||
| mod person; | ||
| mod post; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| use crate::Perform; | ||
| use actix_web::web::Data; | ||
| use lemmy_api_common::{ | ||
| request::purge_image_from_pictrs, | ||
| site::{PurgeItemResponse, PurgePerson}, | ||
| utils::{blocking, get_local_user_view_from_jwt, is_admin, purge_image_posts_for_person}, | ||
| }; | ||
| use lemmy_db_schema::{ | ||
| source::{ | ||
| moderator::{AdminPurgePerson, AdminPurgePersonForm}, | ||
| person::Person, | ||
| }, | ||
| traits::Crud, | ||
| }; | ||
| use lemmy_utils::{ConnectionId, LemmyError}; | ||
| use lemmy_websocket::LemmyContext; | ||
|
|
||
| #[async_trait::async_trait(?Send)] | ||
| impl Perform for PurgePerson { | ||
| type Response = PurgeItemResponse; | ||
|
|
||
| #[tracing::instrument(skip(context, _websocket_id))] | ||
| async fn perform( | ||
| &self, | ||
| context: &Data<LemmyContext>, | ||
| _websocket_id: Option<ConnectionId>, | ||
| ) -> Result<Self::Response, LemmyError> { | ||
| let data: &Self = self; | ||
| let local_user_view = | ||
| get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; | ||
|
|
||
| // Only let admins purge an item | ||
| is_admin(&local_user_view)?; | ||
|
|
||
| // Read the person to get their images | ||
| let person_id = data.person_id; | ||
| let person = blocking(context.pool(), move |conn| Person::read(conn, person_id)).await??; | ||
|
|
||
| if let Some(banner) = person.banner { | ||
| purge_image_from_pictrs(context.client(), &context.settings(), &banner) | ||
| .await | ||
| .ok(); | ||
| } | ||
|
|
||
| if let Some(avatar) = person.avatar { | ||
| purge_image_from_pictrs(context.client(), &context.settings(), &avatar) | ||
| .await | ||
| .ok(); | ||
| } | ||
|
|
||
| purge_image_posts_for_person( | ||
| person_id, | ||
| context.pool(), | ||
| &context.settings(), | ||
| context.client(), | ||
| ) | ||
| .await?; | ||
|
|
||
| blocking(context.pool(), move |conn| Person::delete(conn, person_id)).await??; | ||
|
|
||
| // Mod tables | ||
| let reason = data.reason.to_owned(); | ||
| let form = AdminPurgePersonForm { | ||
| admin_person_id: local_user_view.person.id, | ||
| reason, | ||
| }; | ||
|
|
||
| blocking(context.pool(), move |conn| { | ||
| AdminPurgePerson::create(conn, &form) | ||
| }) | ||
| .await??; | ||
|
|
||
| Ok(PurgeItemResponse { success: true }) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should work with simply Default::Default()