* Show deleted and removed posts for profile views. Fixes #2624 * Only showing non-deleted/removed posts for creator. * Add a admin or mod check to views, to show deleted and removed posts. - Also removed the pointless "blanking" functions * Fix clippy * Make hidden posts comment clearer. * Fixing federation tests. * Fixing fmt.
This commit is contained in:
parent
d9e7f0100a
commit
48f187188b
30 changed files with 215 additions and 243 deletions
|
@ -120,7 +120,6 @@ test("Delete a comment", async () => {
|
||||||
commentRes.comment_view.comment.id
|
commentRes.comment_view.comment.id
|
||||||
);
|
);
|
||||||
expect(deleteCommentRes.comment_view.comment.deleted).toBe(true);
|
expect(deleteCommentRes.comment_view.comment.deleted).toBe(true);
|
||||||
expect(deleteCommentRes.comment_view.comment.content).toBe("");
|
|
||||||
|
|
||||||
// Make sure that comment is undefined on beta
|
// Make sure that comment is undefined on beta
|
||||||
let betaCommentRes = (await resolveComment(
|
let betaCommentRes = (await resolveComment(
|
||||||
|
@ -159,7 +158,6 @@ test("Remove a comment from admin and community on the same instance", async ()
|
||||||
// The beta admin removes it (the community lives on beta)
|
// The beta admin removes it (the community lives on beta)
|
||||||
let removeCommentRes = await removeComment(beta, true, betaCommentId);
|
let removeCommentRes = await removeComment(beta, true, betaCommentId);
|
||||||
expect(removeCommentRes.comment_view.comment.removed).toBe(true);
|
expect(removeCommentRes.comment_view.comment.removed).toBe(true);
|
||||||
expect(removeCommentRes.comment_view.comment.content).toBe("");
|
|
||||||
|
|
||||||
// Make sure that comment is removed on alpha (it gets pushed since an admin from beta removed it)
|
// Make sure that comment is removed on alpha (it gets pushed since an admin from beta removed it)
|
||||||
let refetchedPostComments = await getComments(
|
let refetchedPostComments = await getComments(
|
||||||
|
|
|
@ -388,7 +388,7 @@ test("Enforce site ban for federated user", async () => {
|
||||||
|
|
||||||
// existing alpha post should be removed on beta
|
// existing alpha post should be removed on beta
|
||||||
let searchBeta2 = await searchPostLocal(beta, postRes1.post_view.post);
|
let searchBeta2 = await searchPostLocal(beta, postRes1.post_view.post);
|
||||||
expect(searchBeta2.posts[0]).toBeUndefined();
|
expect(searchBeta2.posts[0].post.removed).toBe(true);
|
||||||
|
|
||||||
// Unban alpha
|
// Unban alpha
|
||||||
let unBanAlpha = await banPersonFromSite(
|
let unBanAlpha = await banPersonFromSite(
|
||||||
|
@ -436,7 +436,7 @@ test("Enforce community ban for federated user", async () => {
|
||||||
|
|
||||||
// ensure that the post by alpha got removed
|
// ensure that the post by alpha got removed
|
||||||
let searchAlpha1 = await searchPostLocal(alpha, postRes1.post_view.post);
|
let searchAlpha1 = await searchPostLocal(alpha, postRes1.post_view.post);
|
||||||
expect(searchAlpha1.posts[0]).toBeUndefined();
|
expect(searchAlpha1.posts[0].post.removed).toBe(true);
|
||||||
|
|
||||||
// Alpha tries to make post on beta, but it fails because of ban
|
// Alpha tries to make post on beta, but it fails because of ban
|
||||||
let postRes2 = await createPost(alpha, betaCommunity.community.id);
|
let postRes2 = await createPost(alpha, betaCommunity.community.id);
|
||||||
|
|
|
@ -64,7 +64,6 @@ test("Delete a private message", async () => {
|
||||||
pmRes.private_message_view.private_message.id
|
pmRes.private_message_view.private_message.id
|
||||||
);
|
);
|
||||||
expect(deletedPmRes.private_message_view.private_message.deleted).toBe(true);
|
expect(deletedPmRes.private_message_view.private_message.deleted).toBe(true);
|
||||||
expect(deletedPmRes.private_message_view.private_message.content).toBe("");
|
|
||||||
|
|
||||||
// The GetPrivateMessages filters out deleted,
|
// The GetPrivateMessages filters out deleted,
|
||||||
// even though they are in the actual database.
|
// even though they are in the actual database.
|
||||||
|
|
|
@ -2363,10 +2363,10 @@ kleur@^3.0.3:
|
||||||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||||
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
||||||
|
|
||||||
lemmy-js-client@0.17.0-rc.61:
|
lemmy-js-client@0.17.2-rc.1:
|
||||||
version "0.17.0-rc.61"
|
version "0.17.2-rc.1"
|
||||||
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.61.tgz#c01e129a3d4c3483ecf337f1e4acf0ad91f9684f"
|
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.2-rc.1.tgz#fe8d1508311bbf245acc98c2c3e47e2165a95b14"
|
||||||
integrity sha512-xauBCD5i4vlUEWqsTMIXLCXeIjAK7ivVIN3C/g+RMAM7mD3CTcRkDZUerwnvLipIfr7V/4iYLWZW0orBaiV1CQ==
|
integrity sha512-YrOXuCofgkqp28krmPTQZAfUWL5zEDA0sRJ0abKcgf/I8YYkYkUkPS9TOORN5Lv3bc8RAAz4+2/zLHqYL/Tnow==
|
||||||
dependencies:
|
dependencies:
|
||||||
node-fetch "2.6.6"
|
node-fetch "2.6.6"
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,8 @@ impl Perform for BlockCommunity {
|
||||||
.map_err(|e| LemmyError::from_error_message(e, "community_block_already_exists"))?;
|
.map_err(|e| LemmyError::from_error_message(e, "community_block_already_exists"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let community_view = CommunityView::read(context.pool(), community_id, Some(person_id)).await?;
|
let community_view =
|
||||||
|
CommunityView::read(context.pool(), community_id, Some(person_id), None).await?;
|
||||||
|
|
||||||
Ok(BlockCommunityResponse {
|
Ok(BlockCommunityResponse {
|
||||||
blocked: data.block,
|
blocked: data.block,
|
||||||
|
|
|
@ -53,7 +53,8 @@ impl Perform for FollowCommunity {
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let community_view = CommunityView::read(context.pool(), community_id, Some(person_id)).await?;
|
let community_view =
|
||||||
|
CommunityView::read(context.pool(), community_id, Some(person_id), None).await?;
|
||||||
let discussion_languages = CommunityLanguage::read(context.pool(), community_id).await?;
|
let discussion_languages = CommunityLanguage::read(context.pool(), community_id).await?;
|
||||||
|
|
||||||
Ok(Self::Response {
|
Ok(Self::Response {
|
||||||
|
|
|
@ -83,7 +83,7 @@ impl Perform for TransferCommunity {
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let community_view = CommunityView::read(context.pool(), community_id, Some(person_id))
|
let community_view = CommunityView::read(context.pool(), community_id, Some(person_id), None)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
|
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl Perform for MarkPostAsRead {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch it
|
// Fetch it
|
||||||
let post_view = PostView::read(context.pool(), post_id, Some(person_id)).await?;
|
let post_view = PostView::read(context.pool(), post_id, Some(person_id), None).await?;
|
||||||
|
|
||||||
let res = Self::Response { post_view };
|
let res = Self::Response { post_view };
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl Perform for SavePost {
|
||||||
|
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let post_view = PostView::read(context.pool(), post_id, Some(person_id)).await?;
|
let post_view = PostView::read(context.pool(), post_id, Some(person_id), None).await?;
|
||||||
|
|
||||||
// Mark the post as read
|
// Mark the post as read
|
||||||
mark_post_as_read(person_id, post_id, context.pool()).await?;
|
mark_post_as_read(person_id, post_id, context.pool()).await?;
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl Perform for CreatePostReport {
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let post_view = PostView::read(context.pool(), post_id, None).await?;
|
let post_view = PostView::read(context.pool(), post_id, None, None).await?;
|
||||||
|
|
||||||
check_community_ban(person_id, post_view.community.id, context.pool()).await?;
|
check_community_ban(person_id, post_view.community.id, context.pool()).await?;
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,23 @@ pub async fn is_mod_or_admin(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
|
pub async fn is_mod_or_admin_opt(
|
||||||
|
pool: &DbPool,
|
||||||
|
local_user_view: Option<&LocalUserView>,
|
||||||
|
community_id: Option<CommunityId>,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
if let Some(local_user_view) = local_user_view {
|
||||||
|
if let Some(community_id) = community_id {
|
||||||
|
is_mod_or_admin(pool, local_user_view.person.id, community_id).await
|
||||||
|
} else {
|
||||||
|
is_admin(local_user_view)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(LemmyError::from_message("not_a_mod_or_admin"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn is_top_admin(pool: &DbPool, person_id: PersonId) -> Result<(), LemmyError> {
|
pub async fn is_top_admin(pool: &DbPool, person_id: PersonId) -> Result<(), LemmyError> {
|
||||||
let admins = PersonViewSafe::admins(pool).await?;
|
let admins = PersonViewSafe::admins(pool).await?;
|
||||||
let top_admin = admins
|
let top_admin = admins
|
||||||
|
|
|
@ -17,7 +17,7 @@ use lemmy_db_schema::{
|
||||||
person_mention::{PersonMention, PersonMentionInsertForm},
|
person_mention::{PersonMention, PersonMentionInsertForm},
|
||||||
post::Post,
|
post::Post,
|
||||||
},
|
},
|
||||||
traits::{Crud, DeleteableOrRemoveable},
|
traits::Crud,
|
||||||
SubscribedType,
|
SubscribedType,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{CommentView, LocalUserView, PostView, PrivateMessageView};
|
use lemmy_db_views::structs::{CommentView, LocalUserView, PostView, PrivateMessageView};
|
||||||
|
@ -32,7 +32,7 @@ pub async fn send_post_ws_message<OP: ToString + Send + OperationType + 'static>
|
||||||
person_id: Option<PersonId>,
|
person_id: Option<PersonId>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let post_view = PostView::read(context.pool(), post_id, person_id).await?;
|
let post_view = PostView::read(context.pool(), post_id, person_id, Some(true)).await?;
|
||||||
|
|
||||||
let res = PostResponse { post_view };
|
let res = PostResponse { post_view };
|
||||||
|
|
||||||
|
@ -65,11 +65,7 @@ pub async fn send_comment_ws_message<OP: ToString + Send + OperationType + 'stat
|
||||||
recipient_ids: Vec<LocalUserId>,
|
recipient_ids: Vec<LocalUserId>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<CommentResponse, LemmyError> {
|
) -> Result<CommentResponse, LemmyError> {
|
||||||
let mut view = CommentView::read(context.pool(), comment_id, person_id).await?;
|
let view = CommentView::read(context.pool(), comment_id, person_id).await?;
|
||||||
|
|
||||||
if view.comment.deleted || view.comment.removed {
|
|
||||||
view.comment = view.comment.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut res = CommentResponse {
|
let mut res = CommentResponse {
|
||||||
comment_view: view,
|
comment_view: view,
|
||||||
|
@ -98,7 +94,8 @@ pub async fn send_community_ws_message<OP: ToString + Send + OperationType + 'st
|
||||||
person_id: Option<PersonId>,
|
person_id: Option<PersonId>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<CommunityResponse, LemmyError> {
|
) -> Result<CommunityResponse, LemmyError> {
|
||||||
let community_view = CommunityView::read(context.pool(), community_id, person_id).await?;
|
let community_view =
|
||||||
|
CommunityView::read(context.pool(), community_id, person_id, Some(true)).await?;
|
||||||
let discussion_languages = CommunityLanguage::read(context.pool(), community_id).await?;
|
let discussion_languages = CommunityLanguage::read(context.pool(), community_id).await?;
|
||||||
|
|
||||||
let mut res = CommunityResponse {
|
let mut res = CommunityResponse {
|
||||||
|
@ -124,12 +121,7 @@ pub async fn send_pm_ws_message<OP: ToString + Send + OperationType + 'static>(
|
||||||
websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||||
let mut view = PrivateMessageView::read(context.pool(), private_message_id).await?;
|
let view = PrivateMessageView::read(context.pool(), private_message_id).await?;
|
||||||
|
|
||||||
// Blank out deleted or removed info
|
|
||||||
if view.private_message.deleted {
|
|
||||||
view.private_message = view.private_message.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = PrivateMessageResponse {
|
let res = PrivateMessageResponse {
|
||||||
private_message_view: view,
|
private_message_view: view,
|
||||||
|
|
|
@ -147,7 +147,7 @@ impl PerformCrud for CreateCommunity {
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let community_view =
|
let community_view =
|
||||||
CommunityView::read(context.pool(), inserted_community.id, Some(person_id)).await?;
|
CommunityView::read(context.pool(), inserted_community.id, Some(person_id), None).await?;
|
||||||
let discussion_languages =
|
let discussion_languages =
|
||||||
CommunityLanguage::read(context.pool(), inserted_community.id).await?;
|
CommunityLanguage::read(context.pool(), inserted_community.id).await?;
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ use actix_web::web::Data;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
community::{ListCommunities, ListCommunitiesResponse},
|
community::{ListCommunities, ListCommunitiesResponse},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
utils::{check_private_instance, get_local_user_view_from_jwt_opt},
|
utils::{check_private_instance, get_local_user_view_from_jwt_opt, is_admin},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{source::local_site::LocalSite, traits::DeleteableOrRemoveable};
|
use lemmy_db_schema::source::local_site::LocalSite;
|
||||||
use lemmy_db_views_actor::community_view::CommunityQuery;
|
use lemmy_db_views_actor::community_view::CommunityQuery;
|
||||||
use lemmy_utils::{error::LemmyError, ConnectionId};
|
use lemmy_utils::{error::LemmyError, ConnectionId};
|
||||||
|
|
||||||
|
@ -24,37 +24,27 @@ impl PerformCrud for ListCommunities {
|
||||||
get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
|
get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
|
||||||
.await?;
|
.await?;
|
||||||
let local_site = LocalSite::read(context.pool()).await?;
|
let local_site = LocalSite::read(context.pool()).await?;
|
||||||
|
let is_admin = local_user_view.as_ref().map(|luv| is_admin(luv).is_ok());
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
check_private_instance(&local_user_view, &local_site)?;
|
||||||
|
|
||||||
let person_id = local_user_view.clone().map(|l| l.person.id);
|
|
||||||
|
|
||||||
let sort = data.sort;
|
let sort = data.sort;
|
||||||
let listing_type = data.type_;
|
let listing_type = data.type_;
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let local_user = local_user_view.map(|l| l.local_user);
|
let local_user = local_user_view.map(|l| l.local_user);
|
||||||
let mut communities = CommunityQuery::builder()
|
let communities = CommunityQuery::builder()
|
||||||
.pool(context.pool())
|
.pool(context.pool())
|
||||||
.listing_type(listing_type)
|
.listing_type(listing_type)
|
||||||
.sort(sort)
|
.sort(sort)
|
||||||
.local_user(local_user.as_ref())
|
.local_user(local_user.as_ref())
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
.is_mod_or_admin(is_admin)
|
||||||
.build()
|
.build()
|
||||||
.list()
|
.list()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Blank out deleted or removed info for non-logged in users
|
|
||||||
if person_id.is_none() {
|
|
||||||
for cv in communities
|
|
||||||
.iter_mut()
|
|
||||||
.filter(|cv| cv.community.deleted || cv.community.removed)
|
|
||||||
{
|
|
||||||
cv.community = cv.clone().community.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(ListCommunitiesResponse { communities })
|
Ok(ListCommunitiesResponse { communities })
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,17 @@ use actix_web::web::Data;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
post::{GetPost, GetPostResponse},
|
post::{GetPost, GetPostResponse},
|
||||||
utils::{check_private_instance, get_local_user_view_from_jwt_opt, mark_post_as_read},
|
utils::{
|
||||||
|
check_private_instance,
|
||||||
|
get_local_user_view_from_jwt_opt,
|
||||||
|
is_mod_or_admin_opt,
|
||||||
|
mark_post_as_read,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm},
|
aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm},
|
||||||
source::{comment::Comment, local_site::LocalSite},
|
source::{comment::Comment, local_site::LocalSite, post::Post},
|
||||||
traits::{Crud, DeleteableOrRemoveable},
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::PostView;
|
use lemmy_db_views::structs::PostView;
|
||||||
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
||||||
|
@ -32,7 +37,7 @@ impl PerformCrud for GetPost {
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
check_private_instance(&local_user_view, &local_site)?;
|
||||||
|
|
||||||
let person_id = local_user_view.map(|u| u.person.id);
|
let person_id = local_user_view.as_ref().map(|u| u.person.id);
|
||||||
|
|
||||||
// I'd prefer fetching the post_view by a comment join, but it adds a lot of boilerplate
|
// I'd prefer fetching the post_view by a comment join, but it adds a lot of boilerplate
|
||||||
let post_id = if let Some(id) = data.id {
|
let post_id = if let Some(id) = data.id {
|
||||||
|
@ -46,7 +51,14 @@ impl PerformCrud for GetPost {
|
||||||
Err(LemmyError::from_message("couldnt_find_post"))?
|
Err(LemmyError::from_message("couldnt_find_post"))?
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut post_view = PostView::read(context.pool(), post_id, person_id)
|
// Check to see if the person is a mod or admin, to show deleted / removed
|
||||||
|
let community_id = Post::read(context.pool(), post_id).await?.community_id;
|
||||||
|
let is_mod_or_admin =
|
||||||
|
is_mod_or_admin_opt(context.pool(), local_user_view.as_ref(), Some(community_id))
|
||||||
|
.await
|
||||||
|
.is_ok();
|
||||||
|
|
||||||
|
let post_view = PostView::read(context.pool(), post_id, person_id, Some(is_mod_or_admin))
|
||||||
.await
|
.await
|
||||||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?;
|
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?;
|
||||||
|
|
||||||
|
@ -57,10 +69,14 @@ impl PerformCrud for GetPost {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Necessary for the sidebar subscribed
|
// Necessary for the sidebar subscribed
|
||||||
let community_id = post_view.community.id;
|
let community_view = CommunityView::read(
|
||||||
let mut community_view = CommunityView::read(context.pool(), community_id, person_id)
|
context.pool(),
|
||||||
.await
|
community_id,
|
||||||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
|
person_id,
|
||||||
|
Some(is_mod_or_admin),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
|
||||||
|
|
||||||
// Insert into PersonPostAggregates
|
// Insert into PersonPostAggregates
|
||||||
// to update the read_comments count
|
// to update the read_comments count
|
||||||
|
@ -77,17 +93,6 @@ impl PerformCrud for GetPost {
|
||||||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?;
|
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blank out deleted or removed info for non-logged in users
|
|
||||||
if person_id.is_none() {
|
|
||||||
if post_view.post.deleted || post_view.post.removed {
|
|
||||||
post_view.post = post_view.post.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
if community_view.community.deleted || community_view.community.removed {
|
|
||||||
community_view.community = community_view.community.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let moderators = CommunityModeratorView::for_community(context.pool(), community_id).await?;
|
let moderators = CommunityModeratorView::for_community(context.pool(), community_id).await?;
|
||||||
|
|
||||||
let online = context.chat_server().get_post_users_online(post_id)?;
|
let online = context.chat_server().get_post_users_online(post_id)?;
|
||||||
|
|
|
@ -5,7 +5,6 @@ use lemmy_api_common::{
|
||||||
private_message::{GetPrivateMessages, PrivateMessagesResponse},
|
private_message::{GetPrivateMessages, PrivateMessagesResponse},
|
||||||
utils::get_local_user_view_from_jwt,
|
utils::get_local_user_view_from_jwt,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::traits::DeleteableOrRemoveable;
|
|
||||||
use lemmy_db_views::private_message_view::PrivateMessageQuery;
|
use lemmy_db_views::private_message_view::PrivateMessageQuery;
|
||||||
use lemmy_utils::{error::LemmyError, ConnectionId};
|
use lemmy_utils::{error::LemmyError, ConnectionId};
|
||||||
|
|
||||||
|
@ -45,17 +44,6 @@ impl PerformCrud for GetPrivateMessages {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Blank out deleted or removed info
|
|
||||||
for pmv in messages
|
|
||||||
.iter_mut()
|
|
||||||
.filter(|pmv| pmv.private_message.deleted)
|
|
||||||
{
|
|
||||||
pmv.private_message = pmv
|
|
||||||
.clone()
|
|
||||||
.private_message
|
|
||||||
.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(PrivateMessagesResponse {
|
Ok(PrivateMessagesResponse {
|
||||||
private_messages: messages,
|
private_messages: messages,
|
||||||
})
|
})
|
||||||
|
|
|
@ -99,7 +99,8 @@ impl ActivityHandler for AcceptFollow {
|
||||||
|
|
||||||
// Send the Subscribed message over websocket
|
// Send the Subscribed message over websocket
|
||||||
// Re-read the community_view to get the new SubscribedType
|
// Re-read the community_view to get the new SubscribedType
|
||||||
let community_view = CommunityView::read(context.pool(), community_id, Some(person_id)).await?;
|
let community_view =
|
||||||
|
CommunityView::read(context.pool(), community_id, Some(person_id), None).await?;
|
||||||
|
|
||||||
// Get the local_user_id
|
// Get the local_user_id
|
||||||
let local_recipient_id = LocalUserView::read_person(context.pool(), person_id)
|
let local_recipient_id = LocalUserView::read_person(context.pool(), person_id)
|
||||||
|
|
|
@ -15,7 +15,7 @@ use lemmy_api_common::{
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{comment::Comment, community::Community, local_site::LocalSite},
|
source::{comment::Comment, community::Community, local_site::LocalSite},
|
||||||
traits::{Crud, DeleteableOrRemoveable},
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::comment_view::CommentQuery;
|
use lemmy_db_views::comment_view::CommentQuery;
|
||||||
use lemmy_utils::{error::LemmyError, ConnectionId};
|
use lemmy_utils::{error::LemmyError, ConnectionId};
|
||||||
|
@ -65,7 +65,7 @@ impl PerformApub for GetComments {
|
||||||
let parent_path_cloned = parent_path.clone();
|
let parent_path_cloned = parent_path.clone();
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let local_user = local_user_view.map(|l| l.local_user);
|
let local_user = local_user_view.map(|l| l.local_user);
|
||||||
let mut comments = CommentQuery::builder()
|
let comments = CommentQuery::builder()
|
||||||
.pool(context.pool())
|
.pool(context.pool())
|
||||||
.listing_type(Some(listing_type))
|
.listing_type(Some(listing_type))
|
||||||
.sort(sort)
|
.sort(sort)
|
||||||
|
@ -83,14 +83,6 @@ impl PerformApub for GetComments {
|
||||||
.await
|
.await
|
||||||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_get_comments"))?;
|
.map_err(|e| LemmyError::from_error_message(e, "couldnt_get_comments"))?;
|
||||||
|
|
||||||
// Blank out deleted or removed info
|
|
||||||
for cv in comments
|
|
||||||
.iter_mut()
|
|
||||||
.filter(|cv| cv.comment.deleted || cv.comment.removed)
|
|
||||||
{
|
|
||||||
cv.comment = cv.clone().comment.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(GetCommentsResponse { comments })
|
Ok(GetCommentsResponse { comments })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,11 @@ use lemmy_api_common::{
|
||||||
utils::{
|
utils::{
|
||||||
check_private_instance,
|
check_private_instance,
|
||||||
get_local_user_view_from_jwt_opt,
|
get_local_user_view_from_jwt_opt,
|
||||||
|
is_mod_or_admin_opt,
|
||||||
listing_type_with_site_default,
|
listing_type_with_site_default,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::source::{community::Community, local_site::LocalSite};
|
||||||
source::{community::Community, local_site::LocalSite},
|
|
||||||
traits::DeleteableOrRemoveable,
|
|
||||||
};
|
|
||||||
use lemmy_db_views::post_view::PostQuery;
|
use lemmy_db_views::post_view::PostQuery;
|
||||||
use lemmy_utils::{error::LemmyError, ConnectionId};
|
use lemmy_utils::{error::LemmyError, ConnectionId};
|
||||||
|
|
||||||
|
@ -38,8 +36,6 @@ impl PerformApub for GetPosts {
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
check_private_instance(&local_user_view, &local_site)?;
|
||||||
|
|
||||||
let is_logged_in = local_user_view.is_some();
|
|
||||||
|
|
||||||
let sort = data.sort;
|
let sort = data.sort;
|
||||||
let listing_type = listing_type_with_site_default(data.type_, &local_site)?;
|
let listing_type = listing_type_with_site_default(data.type_, &local_site)?;
|
||||||
|
|
||||||
|
@ -56,7 +52,12 @@ impl PerformApub for GetPosts {
|
||||||
};
|
};
|
||||||
let saved_only = data.saved_only;
|
let saved_only = data.saved_only;
|
||||||
|
|
||||||
let mut posts = PostQuery::builder()
|
let is_mod_or_admin =
|
||||||
|
is_mod_or_admin_opt(context.pool(), local_user_view.as_ref(), community_id)
|
||||||
|
.await
|
||||||
|
.is_ok();
|
||||||
|
|
||||||
|
let posts = PostQuery::builder()
|
||||||
.pool(context.pool())
|
.pool(context.pool())
|
||||||
.local_user(local_user_view.map(|l| l.local_user).as_ref())
|
.local_user(local_user_view.map(|l| l.local_user).as_ref())
|
||||||
.listing_type(Some(listing_type))
|
.listing_type(Some(listing_type))
|
||||||
|
@ -66,28 +67,12 @@ impl PerformApub for GetPosts {
|
||||||
.saved_only(saved_only)
|
.saved_only(saved_only)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
.is_mod_or_admin(Some(is_mod_or_admin))
|
||||||
.build()
|
.build()
|
||||||
.list()
|
.list()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_get_posts"))?;
|
.map_err(|e| LemmyError::from_error_message(e, "couldnt_get_posts"))?;
|
||||||
|
|
||||||
// Blank out deleted or removed info for non-logged in users
|
|
||||||
if !is_logged_in {
|
|
||||||
for pv in posts
|
|
||||||
.iter_mut()
|
|
||||||
.filter(|p| p.post.deleted || p.post.removed)
|
|
||||||
{
|
|
||||||
pv.post = pv.clone().post.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
for pv in posts
|
|
||||||
.iter_mut()
|
|
||||||
.filter(|p| p.community.deleted || p.community.removed)
|
|
||||||
{
|
|
||||||
pv.community = pv.clone().community.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(GetPostsResponse { posts })
|
Ok(GetPostsResponse { posts })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use actix_web::web::Data;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
community::{GetCommunity, GetCommunityResponse},
|
community::{GetCommunity, GetCommunityResponse},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
utils::{check_private_instance, get_local_user_view_from_jwt_opt},
|
utils::{check_private_instance, get_local_user_view_from_jwt_opt, is_mod_or_admin_opt},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
impls::actor_language::default_post_language,
|
impls::actor_language::default_post_language,
|
||||||
|
@ -17,7 +17,6 @@ use lemmy_db_schema::{
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
site::Site,
|
site::Site,
|
||||||
},
|
},
|
||||||
traits::DeleteableOrRemoveable,
|
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
||||||
use lemmy_utils::{error::LemmyError, ConnectionId};
|
use lemmy_utils::{error::LemmyError, ConnectionId};
|
||||||
|
@ -57,15 +56,19 @@ impl PerformApub for GetCommunity {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut community_view = CommunityView::read(context.pool(), community_id, person_id)
|
let is_mod_or_admin =
|
||||||
.await
|
is_mod_or_admin_opt(context.pool(), local_user_view.as_ref(), Some(community_id))
|
||||||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
|
.await
|
||||||
|
.is_ok();
|
||||||
|
|
||||||
// Blank out deleted or removed info for non-logged in users
|
let community_view = CommunityView::read(
|
||||||
if person_id.is_none() && (community_view.community.deleted || community_view.community.removed)
|
context.pool(),
|
||||||
{
|
community_id,
|
||||||
community_view.community = community_view.community.blank_out_deleted_or_removed_info();
|
person_id,
|
||||||
}
|
Some(is_mod_or_admin),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
|
||||||
|
|
||||||
let moderators = CommunityModeratorView::for_community(context.pool(), community_id)
|
let moderators = CommunityModeratorView::for_community(context.pool(), community_id)
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -3,7 +3,7 @@ use actix_web::web::Data;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{GetPersonDetails, GetPersonDetailsResponse},
|
person::{GetPersonDetails, GetPersonDetailsResponse},
|
||||||
utils::{check_private_instance, get_local_user_view_from_jwt_opt},
|
utils::{check_private_instance, get_local_user_view_from_jwt_opt, is_admin},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{local_site::LocalSite, person::Person},
|
source::{local_site::LocalSite, person::Person},
|
||||||
|
@ -34,6 +34,7 @@ impl PerformApub for GetPersonDetails {
|
||||||
get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
|
get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
|
||||||
.await?;
|
.await?;
|
||||||
let local_site = LocalSite::read(context.pool()).await?;
|
let local_site = LocalSite::read(context.pool()).await?;
|
||||||
|
let is_admin = local_user_view.as_ref().map(|luv| is_admin(luv).is_ok());
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
check_private_instance(&local_user_view, &local_site)?;
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ impl PerformApub for GetPersonDetails {
|
||||||
.saved_only(saved_only)
|
.saved_only(saved_only)
|
||||||
.local_user(local_user.as_ref())
|
.local_user(local_user.as_ref())
|
||||||
.community_id(community_id)
|
.community_id(community_id)
|
||||||
|
.is_mod_or_admin(is_admin)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit);
|
.limit(limit);
|
||||||
|
|
||||||
|
|
|
@ -56,11 +56,11 @@ async fn convert_response(
|
||||||
}
|
}
|
||||||
Community(c) => {
|
Community(c) => {
|
||||||
removed_or_deleted = c.deleted || c.removed;
|
removed_or_deleted = c.deleted || c.removed;
|
||||||
res.community = Some(CommunityView::read(pool, c.id, user_id).await?)
|
res.community = Some(CommunityView::read(pool, c.id, user_id, None).await?)
|
||||||
}
|
}
|
||||||
Post(p) => {
|
Post(p) => {
|
||||||
removed_or_deleted = p.deleted || p.removed;
|
removed_or_deleted = p.deleted || p.removed;
|
||||||
res.post = Some(PostView::read(pool, p.id, user_id).await?)
|
res.post = Some(PostView::read(pool, p.id, user_id, None).await?)
|
||||||
}
|
}
|
||||||
Comment(c) => {
|
Comment(c) => {
|
||||||
removed_or_deleted = c.deleted || c.removed;
|
removed_or_deleted = c.deleted || c.removed;
|
||||||
|
|
|
@ -7,11 +7,10 @@ use actix_web::web::Data;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
site::{Search, SearchResponse},
|
site::{Search, SearchResponse},
|
||||||
utils::{check_private_instance, get_local_user_view_from_jwt_opt},
|
utils::{check_private_instance, get_local_user_view_from_jwt_opt, is_admin},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{community::Community, local_site::LocalSite},
|
source::{community::Community, local_site::LocalSite},
|
||||||
traits::DeleteableOrRemoveable,
|
|
||||||
utils::post_to_comment_sort_type,
|
utils::post_to_comment_sort_type,
|
||||||
SearchType,
|
SearchType,
|
||||||
};
|
};
|
||||||
|
@ -38,7 +37,8 @@ impl PerformApub for Search {
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
check_private_instance(&local_user_view, &local_site)?;
|
||||||
|
|
||||||
let person_id = local_user_view.as_ref().map(|u| u.person.id);
|
let is_admin = local_user_view.as_ref().map(|luv| is_admin(luv).is_ok());
|
||||||
|
|
||||||
let local_user = local_user_view.map(|l| l.local_user);
|
let local_user = local_user_view.map(|l| l.local_user);
|
||||||
|
|
||||||
let mut posts = Vec::new();
|
let mut posts = Vec::new();
|
||||||
|
@ -75,6 +75,7 @@ impl PerformApub for Search {
|
||||||
.creator_id(creator_id)
|
.creator_id(creator_id)
|
||||||
.local_user(local_user.as_ref())
|
.local_user(local_user.as_ref())
|
||||||
.search_term(Some(q))
|
.search_term(Some(q))
|
||||||
|
.is_mod_or_admin(is_admin)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.build()
|
.build()
|
||||||
|
@ -104,6 +105,7 @@ impl PerformApub for Search {
|
||||||
.listing_type(listing_type)
|
.listing_type(listing_type)
|
||||||
.search_term(Some(q))
|
.search_term(Some(q))
|
||||||
.local_user(local_user.as_ref())
|
.local_user(local_user.as_ref())
|
||||||
|
.is_mod_or_admin(is_admin)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.build()
|
.build()
|
||||||
|
@ -137,6 +139,7 @@ impl PerformApub for Search {
|
||||||
.creator_id(creator_id)
|
.creator_id(creator_id)
|
||||||
.local_user(local_user_.as_ref())
|
.local_user(local_user_.as_ref())
|
||||||
.search_term(Some(q))
|
.search_term(Some(q))
|
||||||
|
.is_mod_or_admin(is_admin)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.build()
|
.build()
|
||||||
|
@ -173,6 +176,7 @@ impl PerformApub for Search {
|
||||||
.listing_type(listing_type)
|
.listing_type(listing_type)
|
||||||
.search_term(Some(q))
|
.search_term(Some(q))
|
||||||
.local_user(local_user.as_ref())
|
.local_user(local_user.as_ref())
|
||||||
|
.is_mod_or_admin(is_admin)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.build()
|
.build()
|
||||||
|
@ -205,6 +209,7 @@ impl PerformApub for Search {
|
||||||
.community_actor_id(community_actor_id)
|
.community_actor_id(community_actor_id)
|
||||||
.creator_id(creator_id)
|
.creator_id(creator_id)
|
||||||
.url_search(Some(q))
|
.url_search(Some(q))
|
||||||
|
.is_mod_or_admin(is_admin)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.build()
|
.build()
|
||||||
|
@ -213,30 +218,6 @@ impl PerformApub for Search {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Blank out deleted or removed info for non logged in users
|
|
||||||
if person_id.is_none() {
|
|
||||||
for cv in communities
|
|
||||||
.iter_mut()
|
|
||||||
.filter(|cv| cv.community.deleted || cv.community.removed)
|
|
||||||
{
|
|
||||||
cv.community = cv.clone().community.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
for pv in posts
|
|
||||||
.iter_mut()
|
|
||||||
.filter(|p| p.post.deleted || p.post.removed)
|
|
||||||
{
|
|
||||||
pv.post = pv.clone().post.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
for cv in comments
|
|
||||||
.iter_mut()
|
|
||||||
.filter(|cv| cv.comment.deleted || cv.comment.removed)
|
|
||||||
{
|
|
||||||
cv.comment = cv.clone().comment.blank_out_deleted_or_removed_info();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(SearchResponse {
|
Ok(SearchResponse {
|
||||||
type_: search_type.to_string(),
|
type_: search_type.to_string(),
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
CommentSavedForm,
|
CommentSavedForm,
|
||||||
CommentUpdateForm,
|
CommentUpdateForm,
|
||||||
},
|
},
|
||||||
traits::{Crud, DeleteableOrRemoveable, Likeable, Saveable},
|
traits::{Crud, Likeable, Saveable},
|
||||||
utils::{get_conn, naive_now, DbPool},
|
utils::{get_conn, naive_now, DbPool},
|
||||||
};
|
};
|
||||||
use diesel::{
|
use diesel::{
|
||||||
|
@ -240,13 +240,6 @@ impl Saveable for CommentSaved {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeleteableOrRemoveable for Comment {
|
|
||||||
fn blank_out_deleted_or_removed_info(mut self) -> Self {
|
|
||||||
self.content = String::new();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
|
@ -12,11 +12,10 @@ use crate::{
|
||||||
CommunityModeratorForm,
|
CommunityModeratorForm,
|
||||||
CommunityPersonBan,
|
CommunityPersonBan,
|
||||||
CommunityPersonBanForm,
|
CommunityPersonBanForm,
|
||||||
CommunitySafe,
|
|
||||||
CommunityUpdateForm,
|
CommunityUpdateForm,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
traits::{ApubActor, Bannable, Crud, DeleteableOrRemoveable, Followable, Joinable},
|
traits::{ApubActor, Bannable, Crud, Followable, Joinable},
|
||||||
utils::{functions::lower, get_conn, DbPool},
|
utils::{functions::lower, get_conn, DbPool},
|
||||||
SubscribedType,
|
SubscribedType,
|
||||||
};
|
};
|
||||||
|
@ -174,26 +173,6 @@ impl Joinable for CommunityModerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeleteableOrRemoveable for CommunitySafe {
|
|
||||||
fn blank_out_deleted_or_removed_info(mut self) -> Self {
|
|
||||||
self.title = String::new();
|
|
||||||
self.description = None;
|
|
||||||
self.icon = None;
|
|
||||||
self.banner = None;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeleteableOrRemoveable for Community {
|
|
||||||
fn blank_out_deleted_or_removed_info(mut self) -> Self {
|
|
||||||
self.title = String::new();
|
|
||||||
self.description = None;
|
|
||||||
self.icon = None;
|
|
||||||
self.banner = None;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum CollectionType {
|
pub enum CollectionType {
|
||||||
Moderators,
|
Moderators,
|
||||||
Featured,
|
Featured,
|
||||||
|
|
|
@ -26,7 +26,7 @@ use crate::{
|
||||||
PostSavedForm,
|
PostSavedForm,
|
||||||
PostUpdateForm,
|
PostUpdateForm,
|
||||||
},
|
},
|
||||||
traits::{Crud, DeleteableOrRemoveable, Likeable, Readable, Saveable},
|
traits::{Crud, Likeable, Readable, Saveable},
|
||||||
utils::{get_conn, naive_now, DbPool, FETCH_LIMIT_MAX},
|
utils::{get_conn, naive_now, DbPool, FETCH_LIMIT_MAX},
|
||||||
};
|
};
|
||||||
use ::url::Url;
|
use ::url::Url;
|
||||||
|
@ -317,20 +317,6 @@ impl Readable for PostRead {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeleteableOrRemoveable for Post {
|
|
||||||
fn blank_out_deleted_or_removed_info(mut self) -> Self {
|
|
||||||
self.name = String::new();
|
|
||||||
self.url = None;
|
|
||||||
self.body = None;
|
|
||||||
self.embed_title = None;
|
|
||||||
self.embed_description = None;
|
|
||||||
self.embed_video_url = None;
|
|
||||||
self.thumbnail_url = None;
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
newtypes::{DbUrl, PersonId, PrivateMessageId},
|
newtypes::{DbUrl, PersonId, PrivateMessageId},
|
||||||
schema::private_message::dsl::{ap_id, private_message, read, recipient_id},
|
schema::private_message::dsl::{ap_id, private_message, read, recipient_id},
|
||||||
source::private_message::{PrivateMessage, PrivateMessageInsertForm, PrivateMessageUpdateForm},
|
source::private_message::{PrivateMessage, PrivateMessageInsertForm, PrivateMessageUpdateForm},
|
||||||
traits::{Crud, DeleteableOrRemoveable},
|
traits::Crud,
|
||||||
utils::{get_conn, DbPool},
|
utils::{get_conn, DbPool},
|
||||||
};
|
};
|
||||||
use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl};
|
use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl};
|
||||||
|
@ -86,13 +86,6 @@ impl PrivateMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeleteableOrRemoveable for PrivateMessage {
|
|
||||||
fn blank_out_deleted_or_removed_info(mut self) -> Self {
|
|
||||||
self.content = String::new();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
|
@ -140,11 +140,6 @@ pub trait Reportable {
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO these should be removed, there should be another way to do this
|
|
||||||
pub trait DeleteableOrRemoveable {
|
|
||||||
fn blank_out_deleted_or_removed_info(self) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ToSafe {
|
pub trait ToSafe {
|
||||||
type SafeColumns;
|
type SafeColumns;
|
||||||
fn safe_columns_tuple() -> Self::SafeColumns;
|
fn safe_columns_tuple() -> Self::SafeColumns;
|
||||||
|
|
|
@ -68,24 +68,14 @@ impl PostView {
|
||||||
pool: &DbPool,
|
pool: &DbPool,
|
||||||
post_id: PostId,
|
post_id: PostId,
|
||||||
my_person_id: Option<PersonId>,
|
my_person_id: Option<PersonId>,
|
||||||
|
is_mod_or_admin: Option<bool>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
|
||||||
// The left join below will return None in this case
|
// The left join below will return None in this case
|
||||||
let person_id_join = my_person_id.unwrap_or(PersonId(-1));
|
let person_id_join = my_person_id.unwrap_or(PersonId(-1));
|
||||||
let (
|
let person_alias_1 = diesel::alias!(person as person1);
|
||||||
post,
|
let mut query = post::table
|
||||||
creator,
|
|
||||||
community,
|
|
||||||
creator_banned_from_community,
|
|
||||||
counts,
|
|
||||||
follower,
|
|
||||||
saved,
|
|
||||||
read,
|
|
||||||
creator_blocked,
|
|
||||||
post_like,
|
|
||||||
unread_comments,
|
|
||||||
) = post::table
|
|
||||||
.find(post_id)
|
.find(post_id)
|
||||||
.inner_join(person::table)
|
.inner_join(person::table)
|
||||||
.inner_join(community::table)
|
.inner_join(community::table)
|
||||||
|
@ -144,6 +134,14 @@ impl PostView {
|
||||||
.and(person_post_aggregates::person_id.eq(person_id_join)),
|
.and(person_post_aggregates::person_id.eq(person_id_join)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
// Used to check if you are the post creator
|
||||||
|
.left_join(
|
||||||
|
person_alias_1.on(
|
||||||
|
post::creator_id
|
||||||
|
.eq(person_alias_1.field(person::id))
|
||||||
|
.and(person_alias_1.field(person::id).eq(person_id_join)),
|
||||||
|
),
|
||||||
|
)
|
||||||
.select((
|
.select((
|
||||||
post::all_columns,
|
post::all_columns,
|
||||||
Person::safe_columns_tuple(),
|
Person::safe_columns_tuple(),
|
||||||
|
@ -160,8 +158,38 @@ impl PostView {
|
||||||
post_aggregates::comments,
|
post_aggregates::comments,
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
.first::<PostViewTuple>(conn)
|
.into_boxed();
|
||||||
.await?;
|
|
||||||
|
// If you are not a moderator, exclude deleted or removed content
|
||||||
|
if !is_mod_or_admin.unwrap_or(true) {
|
||||||
|
// If you are not the creator, then remove the other fields.
|
||||||
|
query = query
|
||||||
|
.filter(
|
||||||
|
person_alias_1.field(person::id).is_null().and(
|
||||||
|
post::removed
|
||||||
|
.eq(false)
|
||||||
|
.and(post::deleted.eq(false))
|
||||||
|
.and(community::removed.eq(false))
|
||||||
|
.and(community::deleted.eq(false)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
// If you are the creator, keep them
|
||||||
|
.or_filter(person_alias_1.field(person::id).is_not_null())
|
||||||
|
}
|
||||||
|
|
||||||
|
let (
|
||||||
|
post,
|
||||||
|
creator,
|
||||||
|
community,
|
||||||
|
creator_banned_from_community,
|
||||||
|
counts,
|
||||||
|
follower,
|
||||||
|
saved,
|
||||||
|
read,
|
||||||
|
creator_blocked,
|
||||||
|
post_like,
|
||||||
|
unread_comments,
|
||||||
|
) = query.first::<PostViewTuple>(conn).await?;
|
||||||
|
|
||||||
// If a person is given, then my_vote, if None, should be 0, not null
|
// If a person is given, then my_vote, if None, should be 0, not null
|
||||||
// Necessary to differentiate between other person's votes
|
// Necessary to differentiate between other person's votes
|
||||||
|
@ -201,6 +229,8 @@ pub struct PostQuery<'a> {
|
||||||
search_term: Option<String>,
|
search_term: Option<String>,
|
||||||
url_search: Option<String>,
|
url_search: Option<String>,
|
||||||
saved_only: Option<bool>,
|
saved_only: Option<bool>,
|
||||||
|
/// Used to show deleted or removed posts for admins
|
||||||
|
is_mod_or_admin: Option<bool>,
|
||||||
page: Option<i64>,
|
page: Option<i64>,
|
||||||
limit: Option<i64>,
|
limit: Option<i64>,
|
||||||
}
|
}
|
||||||
|
@ -212,6 +242,7 @@ impl<'a> PostQuery<'a> {
|
||||||
// The left join below will return None in this case
|
// The left join below will return None in this case
|
||||||
let person_id_join = self.local_user.map(|l| l.person_id).unwrap_or(PersonId(-1));
|
let person_id_join = self.local_user.map(|l| l.person_id).unwrap_or(PersonId(-1));
|
||||||
let local_user_id_join = self.local_user.map(|l| l.id).unwrap_or(LocalUserId(-1));
|
let local_user_id_join = self.local_user.map(|l| l.id).unwrap_or(LocalUserId(-1));
|
||||||
|
let person_alias_1 = diesel::alias!(person as person1);
|
||||||
|
|
||||||
let mut query = post::table
|
let mut query = post::table
|
||||||
.inner_join(person::table)
|
.inner_join(person::table)
|
||||||
|
@ -285,6 +316,14 @@ impl<'a> PostQuery<'a> {
|
||||||
.and(local_user_language::local_user_id.eq(local_user_id_join)),
|
.and(local_user_language::local_user_id.eq(local_user_id_join)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
// Used to check if you are the post creator
|
||||||
|
.left_join(
|
||||||
|
person_alias_1.on(
|
||||||
|
post::creator_id
|
||||||
|
.eq(person_alias_1.field(person::id))
|
||||||
|
.and(person_alias_1.field(person::id).eq(person_id_join)),
|
||||||
|
),
|
||||||
|
)
|
||||||
.select((
|
.select((
|
||||||
post::all_columns,
|
post::all_columns,
|
||||||
Person::safe_columns_tuple(),
|
Person::safe_columns_tuple(),
|
||||||
|
@ -303,6 +342,23 @@ impl<'a> PostQuery<'a> {
|
||||||
))
|
))
|
||||||
.into_boxed();
|
.into_boxed();
|
||||||
|
|
||||||
|
// If you are not a moderator, exclude deleted or removed content
|
||||||
|
if !self.is_mod_or_admin.unwrap_or(true) {
|
||||||
|
// If you are not the creator, then remove the other fields.
|
||||||
|
query = query
|
||||||
|
.filter(
|
||||||
|
person_alias_1.field(person::id).is_null().and(
|
||||||
|
post::removed
|
||||||
|
.eq(false)
|
||||||
|
.and(post::deleted.eq(false))
|
||||||
|
.and(community::removed.eq(false))
|
||||||
|
.and(community::deleted.eq(false)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
// If you are the creator, keep them
|
||||||
|
.or_filter(person_alias_1.field(person::id).is_not_null())
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(listing_type) = self.listing_type {
|
if let Some(listing_type) = self.listing_type {
|
||||||
match listing_type {
|
match listing_type {
|
||||||
ListingType::Subscribed => {
|
ListingType::Subscribed => {
|
||||||
|
@ -349,7 +405,6 @@ impl<'a> PostQuery<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If its for a specific person, show the removed / deleted
|
|
||||||
if let Some(creator_id) = self.creator_id {
|
if let Some(creator_id) = self.creator_id {
|
||||||
query = query.filter(post::creator_id.eq(creator_id));
|
query = query.filter(post::creator_id.eq(creator_id));
|
||||||
}
|
}
|
||||||
|
@ -424,13 +479,7 @@ impl<'a> PostQuery<'a> {
|
||||||
|
|
||||||
let (limit, offset) = limit_and_offset(self.page, self.limit)?;
|
let (limit, offset) = limit_and_offset(self.page, self.limit)?;
|
||||||
|
|
||||||
query = query
|
query = query.limit(limit).offset(offset);
|
||||||
.limit(limit)
|
|
||||||
.offset(offset)
|
|
||||||
.filter(post::removed.eq(false))
|
|
||||||
.filter(post::deleted.eq(false))
|
|
||||||
.filter(community::removed.eq(false))
|
|
||||||
.filter(community::deleted.eq(false));
|
|
||||||
|
|
||||||
debug!("Post View Query: {:?}", debug_query::<Pg, _>(&query));
|
debug!("Post View Query: {:?}", debug_query::<Pg, _>(&query));
|
||||||
|
|
||||||
|
@ -615,10 +664,14 @@ mod tests {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let post_listing_single_with_person =
|
let post_listing_single_with_person = PostView::read(
|
||||||
PostView::read(pool, data.inserted_post.id, Some(data.inserted_person.id))
|
pool,
|
||||||
.await
|
data.inserted_post.id,
|
||||||
.unwrap();
|
Some(data.inserted_person.id),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut expected_post_listing_with_user = expected_post_view(&data, pool).await;
|
let mut expected_post_listing_with_user = expected_post_view(&data, pool).await;
|
||||||
|
|
||||||
|
@ -670,9 +723,10 @@ mod tests {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let read_post_listing_single_no_person = PostView::read(pool, data.inserted_post.id, None)
|
let read_post_listing_single_no_person =
|
||||||
.await
|
PostView::read(pool, data.inserted_post.id, None, None)
|
||||||
.unwrap();
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let expected_post_listing_no_person = expected_post_view(&data, pool).await;
|
let expected_post_listing_no_person = expected_post_view(&data, pool).await;
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,13 @@ impl CommunityView {
|
||||||
pool: &DbPool,
|
pool: &DbPool,
|
||||||
community_id: CommunityId,
|
community_id: CommunityId,
|
||||||
my_person_id: Option<PersonId>,
|
my_person_id: Option<PersonId>,
|
||||||
|
is_mod_or_admin: Option<bool>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
// The left join below will return None in this case
|
// The left join below will return None in this case
|
||||||
let person_id_join = my_person_id.unwrap_or(PersonId(-1));
|
let person_id_join = my_person_id.unwrap_or(PersonId(-1));
|
||||||
|
|
||||||
let (community, counts, follower, blocked) = community::table
|
let mut query = community::table
|
||||||
.find(community_id)
|
.find(community_id)
|
||||||
.inner_join(community_aggregates::table)
|
.inner_join(community_aggregates::table)
|
||||||
.left_join(
|
.left_join(
|
||||||
|
@ -65,8 +66,16 @@ impl CommunityView {
|
||||||
community_follower::all_columns.nullable(),
|
community_follower::all_columns.nullable(),
|
||||||
community_block::all_columns.nullable(),
|
community_block::all_columns.nullable(),
|
||||||
))
|
))
|
||||||
.first::<CommunityViewTuple>(conn)
|
.into_boxed();
|
||||||
.await?;
|
|
||||||
|
// Hide deleted and removed for non-admins or mods
|
||||||
|
if !is_mod_or_admin.unwrap_or(true) {
|
||||||
|
query = query
|
||||||
|
.filter(community::removed.eq(false))
|
||||||
|
.filter(community::deleted.eq(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
let (community, counts, follower, blocked) = query.first::<CommunityViewTuple>(conn).await?;
|
||||||
|
|
||||||
Ok(CommunityView {
|
Ok(CommunityView {
|
||||||
community,
|
community,
|
||||||
|
@ -116,6 +125,7 @@ pub struct CommunityQuery<'a> {
|
||||||
sort: Option<SortType>,
|
sort: Option<SortType>,
|
||||||
local_user: Option<&'a LocalUser>,
|
local_user: Option<&'a LocalUser>,
|
||||||
search_term: Option<String>,
|
search_term: Option<String>,
|
||||||
|
is_mod_or_admin: Option<bool>,
|
||||||
page: Option<i64>,
|
page: Option<i64>,
|
||||||
limit: Option<i64>,
|
limit: Option<i64>,
|
||||||
}
|
}
|
||||||
|
@ -159,6 +169,13 @@ impl<'a> CommunityQuery<'a> {
|
||||||
.or_filter(community::title.ilike(searcher));
|
.or_filter(community::title.ilike(searcher));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hide deleted and removed for non-admins or mods
|
||||||
|
if !self.is_mod_or_admin.unwrap_or(true) {
|
||||||
|
query = query
|
||||||
|
.filter(community::removed.eq(false))
|
||||||
|
.filter(community::deleted.eq(false));
|
||||||
|
}
|
||||||
|
|
||||||
match self.sort.unwrap_or(SortType::Hot) {
|
match self.sort.unwrap_or(SortType::Hot) {
|
||||||
SortType::New => query = query.order_by(community::published.desc()),
|
SortType::New => query = query.order_by(community::published.desc()),
|
||||||
SortType::TopAll => query = query.order_by(community_aggregates::subscribers.desc()),
|
SortType::TopAll => query = query.order_by(community_aggregates::subscribers.desc()),
|
||||||
|
|
Loading…
Reference in a new issue