Fixing not being able to create comments on local community posts. (#4854)

* Fixing not being able to create comments on local community posts.

- This was caused by not passing my_person_id into various
  `CommentView::read` functions.
- Fixes #4853

* Refactoring views to use local_user, rather than person

* Addressing PR comments.

* Fixing API tests.
This commit is contained in:
Dessalines 2024-07-07 12:28:42 -04:00 committed by GitHub
parent 78702b59fd
commit 32cee9cbca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 242 additions and 234 deletions

View file

@ -17,9 +17,13 @@ pub async fn distinguish_comment(
context: Data<LemmyContext>, context: Data<LemmyContext>,
local_user_view: LocalUserView, local_user_view: LocalUserView,
) -> LemmyResult<Json<CommentResponse>> { ) -> LemmyResult<Json<CommentResponse>> {
let orig_comment = CommentView::read(&mut context.pool(), data.comment_id, None) let orig_comment = CommentView::read(
.await? &mut context.pool(),
.ok_or(LemmyErrorType::CouldntFindComment)?; data.comment_id,
Some(&local_user_view.local_user),
)
.await?
.ok_or(LemmyErrorType::CouldntFindComment)?;
check_community_user_action( check_community_user_action(
&local_user_view.person, &local_user_view.person,
@ -54,7 +58,7 @@ pub async fn distinguish_comment(
let comment_view = CommentView::read( let comment_view = CommentView::read(
&mut context.pool(), &mut context.pool(),
data.comment_id, data.comment_id,
Some(local_user_view.person.id), Some(&local_user_view.local_user),
) )
.await? .await?
.ok_or(LemmyErrorType::CouldntFindComment)?; .ok_or(LemmyErrorType::CouldntFindComment)?;

View file

@ -35,9 +35,13 @@ pub async fn like_comment(
check_bot_account(&local_user_view.person)?; check_bot_account(&local_user_view.person)?;
let comment_id = data.comment_id; let comment_id = data.comment_id;
let orig_comment = CommentView::read(&mut context.pool(), comment_id, None) let orig_comment = CommentView::read(
.await? &mut context.pool(),
.ok_or(LemmyErrorType::CouldntFindComment)?; comment_id,
Some(&local_user_view.local_user),
)
.await?
.ok_or(LemmyErrorType::CouldntFindComment)?;
check_community_user_action( check_community_user_action(
&local_user_view.person, &local_user_view.person,

View file

@ -17,7 +17,7 @@ pub async fn list_comment_likes(
let comment_view = CommentView::read( let comment_view = CommentView::read(
&mut context.pool(), &mut context.pool(),
data.comment_id, data.comment_id,
Some(local_user_view.person.id), Some(&local_user_view.local_user),
) )
.await? .await?
.ok_or(LemmyErrorType::CouldntFindComment)?; .ok_or(LemmyErrorType::CouldntFindComment)?;

View file

@ -32,10 +32,13 @@ pub async fn save_comment(
} }
let comment_id = data.comment_id; let comment_id = data.comment_id;
let person_id = local_user_view.person.id; let comment_view = CommentView::read(
let comment_view = CommentView::read(&mut context.pool(), comment_id, Some(person_id)) &mut context.pool(),
.await? comment_id,
.ok_or(LemmyErrorType::CouldntFindComment)?; Some(&local_user_view.local_user),
)
.await?
.ok_or(LemmyErrorType::CouldntFindComment)?;
Ok(Json(CommentResponse { Ok(Json(CommentResponse {
comment_view, comment_view,

View file

@ -35,9 +35,13 @@ pub async fn create_comment_report(
let person_id = local_user_view.person.id; let person_id = local_user_view.person.id;
let comment_id = data.comment_id; let comment_id = data.comment_id;
let comment_view = CommentView::read(&mut context.pool(), comment_id, None) let comment_view = CommentView::read(
.await? &mut context.pool(),
.ok_or(LemmyErrorType::CouldntFindComment)?; comment_id,
Some(&local_user_view.local_user),
)
.await?
.ok_or(LemmyErrorType::CouldntFindComment)?;
check_community_user_action( check_community_user_action(
&local_user_view.person, &local_user_view.person,

View file

@ -50,10 +50,14 @@ pub async fn block_community(
.with_lemmy_type(LemmyErrorType::CommunityBlockAlreadyExists)?; .with_lemmy_type(LemmyErrorType::CommunityBlockAlreadyExists)?;
} }
let community_view = let community_view = CommunityView::read(
CommunityView::read(&mut context.pool(), community_id, Some(person_id), false) &mut context.pool(),
.await? community_id,
.ok_or(LemmyErrorType::CouldntFindCommunity)?; Some(&local_user_view.local_user),
false,
)
.await?
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
ActivityChannel::submit_activity( ActivityChannel::submit_activity(
SendActivityData::FollowCommunity( SendActivityData::FollowCommunity(

View file

@ -62,11 +62,14 @@ pub async fn follow_community(
} }
let community_id = data.community_id; let community_id = data.community_id;
let person_id = local_user_view.person.id; let community_view = CommunityView::read(
let community_view = &mut context.pool(),
CommunityView::read(&mut context.pool(), community_id, Some(person_id), false) community_id,
.await? Some(&local_user_view.local_user),
.ok_or(LemmyErrorType::CouldntFindCommunity)?; false,
)
.await?
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?; let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?;

View file

@ -76,11 +76,14 @@ pub async fn transfer_community(
ModTransferCommunity::create(&mut context.pool(), &form).await?; ModTransferCommunity::create(&mut context.pool(), &form).await?;
let community_id = data.community_id; let community_id = data.community_id;
let person_id = local_user_view.person.id; let community_view = CommunityView::read(
let community_view = &mut context.pool(),
CommunityView::read(&mut context.pool(), community_id, Some(person_id), false) community_id,
.await? Some(&local_user_view.local_user),
.ok_or(LemmyErrorType::CouldntFindCommunity)?; false,
)
.await?
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
let community_id = data.community_id; let community_id = data.community_id;
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id) let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id)

View file

@ -72,11 +72,5 @@ pub async fn feature_post(
) )
.await?; .await?;
build_post_response( build_post_response(&context, orig_post.community_id, local_user_view, post_id).await
&context,
orig_post.community_id,
&local_user_view.person,
post_id,
)
.await
} }

View file

@ -85,11 +85,5 @@ pub async fn like_post(
) )
.await?; .await?;
build_post_response( build_post_response(context.deref(), post.community_id, local_user_view, post_id).await
context.deref(),
post.community_id,
&local_user_view.person,
post_id,
)
.await
} }

View file

@ -63,11 +63,5 @@ pub async fn lock_post(
) )
.await?; .await?;
build_post_response( build_post_response(&context, orig_post.community_id, local_user_view, post_id).await
&context,
orig_post.community_id,
&local_user_view.person,
post_id,
)
.await
} }

View file

@ -34,9 +34,14 @@ pub async fn save_post(
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(&mut context.pool(), post_id, Some(person_id), false) let post_view = PostView::read(
.await? &mut context.pool(),
.ok_or(LemmyErrorType::CouldntFindPost)?; post_id,
Some(&local_user_view.local_user),
false,
)
.await?
.ok_or(LemmyErrorType::CouldntFindPost)?;
mark_post_as_read(person_id, post_id, &mut context.pool()).await?; mark_post_as_read(person_id, post_id, &mut context.pool()).await?;

View file

@ -29,9 +29,13 @@ pub async fn purge_comment(
let comment_id = data.comment_id; let comment_id = data.comment_id;
// Read the comment to get the post_id and community // Read the comment to get the post_id and community
let comment_view = CommentView::read(&mut context.pool(), comment_id, None) let comment_view = CommentView::read(
.await? &mut context.pool(),
.ok_or(LemmyErrorType::CouldntFindComment)?; comment_id,
Some(&local_user_view.local_user),
)
.await?
.ok_or(LemmyErrorType::CouldntFindComment)?;
let post_id = comment_view.comment.post_id; let post_id = comment_view.comment.post_id;

View file

@ -36,8 +36,8 @@ pub async fn build_comment_response(
local_user_view: Option<LocalUserView>, local_user_view: Option<LocalUserView>,
recipient_ids: Vec<LocalUserId>, recipient_ids: Vec<LocalUserId>,
) -> LemmyResult<CommentResponse> { ) -> LemmyResult<CommentResponse> {
let person_id = local_user_view.map(|l| l.person.id); let local_user = local_user_view.map(|l| l.local_user);
let comment_view = CommentView::read(&mut context.pool(), comment_id, person_id) let comment_view = CommentView::read(&mut context.pool(), comment_id, local_user.as_ref())
.await? .await?
.ok_or(LemmyErrorType::CouldntFindComment)?; .ok_or(LemmyErrorType::CouldntFindComment)?;
Ok(CommentResponse { Ok(CommentResponse {
@ -54,11 +54,11 @@ pub async fn build_community_response(
let is_mod_or_admin = is_mod_or_admin(&mut context.pool(), &local_user_view.person, community_id) let is_mod_or_admin = is_mod_or_admin(&mut context.pool(), &local_user_view.person, community_id)
.await .await
.is_ok(); .is_ok();
let person_id = local_user_view.person.id; let local_user = local_user_view.local_user;
let community_view = CommunityView::read( let community_view = CommunityView::read(
&mut context.pool(), &mut context.pool(),
community_id, community_id,
Some(person_id), Some(&local_user),
is_mod_or_admin, is_mod_or_admin,
) )
.await? .await?
@ -74,16 +74,17 @@ pub async fn build_community_response(
pub async fn build_post_response( pub async fn build_post_response(
context: &LemmyContext, context: &LemmyContext,
community_id: CommunityId, community_id: CommunityId,
person: &Person, local_user_view: LocalUserView,
post_id: PostId, post_id: PostId,
) -> LemmyResult<Json<PostResponse>> { ) -> LemmyResult<Json<PostResponse>> {
let is_mod_or_admin = is_mod_or_admin(&mut context.pool(), person, community_id) let local_user = local_user_view.local_user;
let is_mod_or_admin = is_mod_or_admin(&mut context.pool(), &local_user_view.person, community_id)
.await .await
.is_ok(); .is_ok();
let post_view = PostView::read( let post_view = PostView::read(
&mut context.pool(), &mut context.pool(),
post_id, post_id,
Some(person.id), Some(&local_user),
is_mod_or_admin, is_mod_or_admin,
) )
.await? .await?
@ -103,6 +104,7 @@ pub async fn send_local_notifs(
let mut recipient_ids = Vec::new(); let mut recipient_ids = Vec::new();
let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname()); let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
// let person = my_local_user.person;
// Read the comment view to get extra info // Read the comment view to get extra info
let comment_view = CommentView::read(&mut context.pool(), comment_id, None) let comment_view = CommentView::read(&mut context.pool(), comment_id, None)
.await? .await?

View file

@ -54,7 +54,7 @@ pub async fn create_comment(
let post_view = PostView::read( let post_view = PostView::read(
&mut context.pool(), &mut context.pool(),
post_id, post_id,
Some(local_user_view.person.id), Some(&local_user_view.local_user),
true, true,
) )
.await? .await?

View file

@ -21,9 +21,13 @@ pub async fn delete_comment(
local_user_view: LocalUserView, local_user_view: LocalUserView,
) -> LemmyResult<Json<CommentResponse>> { ) -> LemmyResult<Json<CommentResponse>> {
let comment_id = data.comment_id; let comment_id = data.comment_id;
let orig_comment = CommentView::read(&mut context.pool(), comment_id, None) let orig_comment = CommentView::read(
.await? &mut context.pool(),
.ok_or(LemmyErrorType::CouldntFindComment)?; comment_id,
Some(&local_user_view.local_user),
)
.await?
.ok_or(LemmyErrorType::CouldntFindComment)?;
// Dont delete it if its already been deleted. // Dont delete it if its already been deleted.
if orig_comment.comment.deleted == data.deleted { if orig_comment.comment.deleted == data.deleted {

View file

@ -25,9 +25,13 @@ pub async fn remove_comment(
local_user_view: LocalUserView, local_user_view: LocalUserView,
) -> LemmyResult<Json<CommentResponse>> { ) -> LemmyResult<Json<CommentResponse>> {
let comment_id = data.comment_id; let comment_id = data.comment_id;
let orig_comment = CommentView::read(&mut context.pool(), comment_id, None) let orig_comment = CommentView::read(
.await? &mut context.pool(),
.ok_or(LemmyErrorType::CouldntFindComment)?; comment_id,
Some(&local_user_view.local_user),
)
.await?
.ok_or(LemmyErrorType::CouldntFindComment)?;
check_community_mod_action( check_community_mod_action(
&local_user_view.person, &local_user_view.person,
@ -68,14 +72,8 @@ pub async fn remove_comment(
}; };
ModRemoveComment::create(&mut context.pool(), &form).await?; ModRemoveComment::create(&mut context.pool(), &form).await?;
let recipient_ids = send_local_notifs( let recipient_ids =
vec![], send_local_notifs(vec![], comment_id, &local_user_view.person, false, &context).await?;
comment_id,
&local_user_view.person.clone(),
false,
&context,
)
.await?;
let updated_comment_id = updated_comment.id; let updated_comment_id = updated_comment.id;
ActivityChannel::submit_activity( ActivityChannel::submit_activity(

View file

@ -36,9 +36,13 @@ pub async fn update_comment(
let local_site = LocalSite::read(&mut context.pool()).await?; let local_site = LocalSite::read(&mut context.pool()).await?;
let comment_id = data.comment_id; let comment_id = data.comment_id;
let orig_comment = CommentView::read(&mut context.pool(), comment_id, None) let orig_comment = CommentView::read(
.await? &mut context.pool(),
.ok_or(LemmyErrorType::CouldntFindComment)?; comment_id,
Some(&local_user_view.local_user),
)
.await?
.ok_or(LemmyErrorType::CouldntFindComment)?;
check_community_user_action( check_community_user_action(
&local_user_view.person, &local_user_view.person,

View file

@ -188,5 +188,5 @@ pub async fn create_post(
} }
}; };
build_post_response(&context, community_id, &local_user_view.person, post_id).await build_post_response(&context, community_id, local_user_view, post_id).await
} }

View file

@ -62,7 +62,7 @@ pub async fn delete_post(
build_post_response( build_post_response(
&context, &context,
orig_post.community_id, orig_post.community_id,
&local_user_view.person, local_user_view,
data.post_id, data.post_id,
) )
.await .await

View file

@ -55,9 +55,15 @@ pub async fn get_post(
.await .await
.is_ok(); .is_ok();
let post_view = PostView::read(&mut context.pool(), post_id, person_id, is_mod_or_admin) let local_user = local_user_view.map(|l| l.local_user);
.await? let post_view = PostView::read(
.ok_or(LemmyErrorType::CouldntFindPost)?; &mut context.pool(),
post_id,
local_user.as_ref(),
is_mod_or_admin,
)
.await?
.ok_or(LemmyErrorType::CouldntFindPost)?;
let post_id = post_view.post.id; let post_id = post_view.post.id;
if let Some(person_id) = person_id { if let Some(person_id) = person_id {
@ -76,20 +82,19 @@ pub async fn get_post(
let community_view = CommunityView::read( let community_view = CommunityView::read(
&mut context.pool(), &mut context.pool(),
community_id, community_id,
person_id, local_user.as_ref(),
is_mod_or_admin, is_mod_or_admin,
) )
.await? .await?
.ok_or(LemmyErrorType::CouldntFindCommunity)?; .ok_or(LemmyErrorType::CouldntFindCommunity)?;
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?; let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
let local_user = local_user_view.as_ref().map(|u| &u.local_user);
// Fetch the cross_posts // Fetch the cross_posts
let cross_posts = if let Some(url) = &post_view.post.url { let cross_posts = if let Some(url) = &post_view.post.url {
let mut x_posts = PostQuery { let mut x_posts = PostQuery {
url_search: Some(url.inner().as_str().into()), url_search: Some(url.inner().as_str().into()),
local_user, local_user: local_user.as_ref(),
..Default::default() ..Default::default()
} }
.list(&local_site.site, &mut context.pool()) .list(&local_site.site, &mut context.pool())

View file

@ -73,11 +73,5 @@ pub async fn remove_post(
) )
.await?; .await?;
build_post_response( build_post_response(&context, orig_post.community_id, local_user_view, post_id).await
&context,
orig_post.community_id,
&local_user_view.person,
post_id,
)
.await
} }

View file

@ -137,7 +137,7 @@ pub async fn update_post(
build_post_response( build_post_response(
context.deref(), context.deref(),
orig_post.community_id, orig_post.community_id,
&local_user_view.person, local_user_view,
post_id, post_id,
) )
.await .await

View file

@ -29,7 +29,7 @@ pub async fn get_community(
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 local_user = local_user_view.as_ref().map(|u| &u.local_user);
let community_id = match data.id { let community_id = match data.id {
Some(id) => id, Some(id) => id,
@ -53,7 +53,7 @@ pub async fn get_community(
let community_view = CommunityView::read( let community_view = CommunityView::read(
&mut context.pool(), &mut context.pool(),
community_id, community_id,
person_id, local_user,
is_mod_or_admin, is_mod_or_admin,
) )
.await? .await?

View file

@ -10,7 +10,7 @@ use lemmy_api_common::{
site::{ResolveObject, ResolveObjectResponse}, site::{ResolveObject, ResolveObjectResponse},
utils::check_private_instance, utils::check_private_instance,
}; };
use lemmy_db_schema::{newtypes::PersonId, source::local_site::LocalSite, utils::DbPool}; use lemmy_db_schema::{source::local_site::LocalSite, utils::DbPool};
use lemmy_db_views::structs::{CommentView, LocalUserView, PostView}; use lemmy_db_views::structs::{CommentView, LocalUserView, PostView};
use lemmy_db_views_actor::structs::{CommunityView, PersonView}; use lemmy_db_views_actor::structs::{CommunityView, PersonView};
use lemmy_utils::error::{LemmyErrorExt2, LemmyErrorType, LemmyResult}; use lemmy_utils::error::{LemmyErrorExt2, LemmyErrorType, LemmyResult};
@ -23,10 +23,9 @@ pub async fn resolve_object(
) -> LemmyResult<Json<ResolveObjectResponse>> { ) -> LemmyResult<Json<ResolveObjectResponse>> {
let local_site = LocalSite::read(&mut context.pool()).await?; let local_site = LocalSite::read(&mut context.pool()).await?;
check_private_instance(&local_user_view, &local_site)?; check_private_instance(&local_user_view, &local_site)?;
let person_id = local_user_view.map(|v| v.person.id);
// If we get a valid personId back we can safely assume that the user is authenticated, // If we get a valid personId back we can safely assume that the user is authenticated,
// if there's no personId then the JWT was missing or invalid. // if there's no personId then the JWT was missing or invalid.
let is_authenticated = person_id.is_some(); let is_authenticated = local_user_view.is_some();
let res = if is_authenticated { let res = if is_authenticated {
// user is fully authenticated; allow remote lookups as well. // user is fully authenticated; allow remote lookups as well.
@ -37,24 +36,26 @@ pub async fn resolve_object(
} }
.with_lemmy_type(LemmyErrorType::CouldntFindObject)?; .with_lemmy_type(LemmyErrorType::CouldntFindObject)?;
convert_response(res, person_id, &mut context.pool()) convert_response(res, local_user_view, &mut context.pool())
.await .await
.with_lemmy_type(LemmyErrorType::CouldntFindObject) .with_lemmy_type(LemmyErrorType::CouldntFindObject)
} }
async fn convert_response( async fn convert_response(
object: SearchableObjects, object: SearchableObjects,
user_id: Option<PersonId>, local_user_view: Option<LocalUserView>,
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
) -> LemmyResult<Json<ResolveObjectResponse>> { ) -> LemmyResult<Json<ResolveObjectResponse>> {
use SearchableObjects::*; use SearchableObjects::*;
let removed_or_deleted; let removed_or_deleted;
let mut res = ResolveObjectResponse::default(); let mut res = ResolveObjectResponse::default();
let local_user = local_user_view.map(|l| l.local_user);
match object { match object {
Post(p) => { Post(p) => {
removed_or_deleted = p.deleted || p.removed; removed_or_deleted = p.deleted || p.removed;
res.post = Some( res.post = Some(
PostView::read(pool, p.id, user_id, false) PostView::read(pool, p.id, local_user.as_ref(), false)
.await? .await?
.ok_or(LemmyErrorType::CouldntFindPost)?, .ok_or(LemmyErrorType::CouldntFindPost)?,
) )
@ -62,7 +63,7 @@ async fn convert_response(
Comment(c) => { Comment(c) => {
removed_or_deleted = c.deleted || c.removed; removed_or_deleted = c.deleted || c.removed;
res.comment = Some( res.comment = Some(
CommentView::read(pool, c.id, user_id) CommentView::read(pool, c.id, local_user.as_ref())
.await? .await?
.ok_or(LemmyErrorType::CouldntFindComment)?, .ok_or(LemmyErrorType::CouldntFindComment)?,
) )
@ -79,7 +80,7 @@ async fn convert_response(
UserOrCommunity::Community(c) => { UserOrCommunity::Community(c) => {
removed_or_deleted = c.deleted || c.removed; removed_or_deleted = c.deleted || c.removed;
res.community = Some( res.community = Some(
CommunityView::read(pool, c.id, user_id, false) CommunityView::read(pool, c.id, local_user.as_ref(), false)
.await? .await?
.ok_or(LemmyErrorType::CouldntFindCommunity)?, .ok_or(LemmyErrorType::CouldntFindCommunity)?,
) )

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
newtypes::{DbUrl, LanguageId, LocalUserId, PersonId}, newtypes::{DbUrl, LanguageId, LocalUserId, PersonId},
schema::{local_user, person, registration_application}, schema::{community, local_user, person, registration_application},
source::{ source::{
actor_language::LocalUserLanguage, actor_language::LocalUserLanguage,
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm}, local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
@ -13,6 +13,7 @@ use crate::{
now, now,
DbPool, DbPool,
}, },
CommunityVisibility,
}; };
use bcrypt::{hash, DEFAULT_COST}; use bcrypt::{hash, DEFAULT_COST};
use diesel::{ use diesel::{
@ -225,6 +226,12 @@ pub trait LocalUserOptionHelper {
fn show_read_posts(&self) -> bool; fn show_read_posts(&self) -> bool;
fn is_admin(&self) -> bool; fn is_admin(&self) -> bool;
fn show_nsfw(&self, site: &Site) -> bool; fn show_nsfw(&self, site: &Site) -> bool;
fn visible_communities_only<Q>(&self, query: Q) -> Q
where
Q: diesel::query_dsl::methods::FilterDsl<
diesel::dsl::Eq<community::visibility, CommunityVisibility>,
Output = Q,
>;
} }
impl LocalUserOptionHelper for Option<&LocalUser> { impl LocalUserOptionHelper for Option<&LocalUser> {
@ -253,6 +260,20 @@ impl LocalUserOptionHelper for Option<&LocalUser> {
.map(|l| l.show_nsfw) .map(|l| l.show_nsfw)
.unwrap_or(site.content_warning.is_some()) .unwrap_or(site.content_warning.is_some())
} }
fn visible_communities_only<Q>(&self, query: Q) -> Q
where
Q: diesel::query_dsl::methods::FilterDsl<
diesel::dsl::Eq<community::visibility, CommunityVisibility>,
Output = Q,
>,
{
if self.is_none() {
query.filter(community::visibility.eq(CommunityVisibility::Public))
} else {
query
}
}
} }
impl LocalUserInsertForm { impl LocalUserInsertForm {

View file

@ -1,15 +1,7 @@
use crate::{ use crate::{newtypes::DbUrl, CommentSortType, SortType};
diesel::ExpressionMethods,
newtypes::{DbUrl, PersonId},
schema::community,
CommentSortType,
CommunityVisibility,
SortType,
};
use chrono::{DateTime, TimeDelta, Utc}; use chrono::{DateTime, TimeDelta, Utc};
use deadpool::Runtime; use deadpool::Runtime;
use diesel::{ use diesel::{
dsl,
helper_types::AsExprOf, helper_types::AsExprOf,
pg::Pg, pg::Pg,
query_builder::{Query, QueryFragment}, query_builder::{Query, QueryFragment},
@ -592,20 +584,6 @@ impl<RF, LF> Queries<RF, LF> {
} }
} }
pub fn visible_communities_only<Q>(my_person_id: Option<PersonId>, query: Q) -> Q
where
Q: diesel::query_dsl::methods::FilterDsl<
dsl::Eq<community::visibility, CommunityVisibility>,
Output = Q,
>,
{
if my_person_id.is_none() {
query.filter(community::visibility.eq(CommunityVisibility::Public))
} else {
query
}
}
#[cfg(test)] #[cfg(test)]
#[allow(clippy::indexing_slicing)] #[allow(clippy::indexing_slicing)]
mod tests { mod tests {

View file

@ -36,22 +36,13 @@ use lemmy_db_schema::{
post, post,
}, },
source::local_user::LocalUser, source::local_user::LocalUser,
utils::{ utils::{fuzzy_search, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn},
fuzzy_search,
limit_and_offset,
visible_communities_only,
DbConn,
DbPool,
ListFn,
Queries,
ReadFn,
},
CommentSortType, CommentSortType,
ListingType, ListingType,
}; };
fn queries<'a>() -> Queries< fn queries<'a>() -> Queries<
impl ReadFn<'a, CommentView, (CommentId, Option<PersonId>)>, impl ReadFn<'a, CommentView, (CommentId, Option<&'a LocalUser>)>,
impl ListFn<'a, CommentView, CommentQuery<'a>>, impl ListFn<'a, CommentView, CommentQuery<'a>>,
> { > {
let is_creator_banned_from_community = exists( let is_creator_banned_from_community = exists(
@ -182,9 +173,12 @@ fn queries<'a>() -> Queries<
}; };
let read = move |mut conn: DbConn<'a>, let read = move |mut conn: DbConn<'a>,
(comment_id, my_person_id): (CommentId, Option<PersonId>)| async move { (comment_id, my_local_user): (CommentId, Option<&'a LocalUser>)| async move {
let mut query = all_joins(comment::table.find(comment_id).into_boxed(), my_person_id); let mut query = all_joins(
query = visible_communities_only(my_person_id, query); comment::table.find(comment_id).into_boxed(),
my_local_user.person_id(),
);
query = my_local_user.visible_communities_only(query);
query.first(&mut conn).await query.first(&mut conn).await
}; };
@ -301,7 +295,7 @@ fn queries<'a>() -> Queries<
query = query.filter(not(is_creator_blocked(person_id_join))); query = query.filter(not(is_creator_blocked(person_id_join)));
}; };
query = visible_communities_only(options.local_user.person_id(), query); query = options.local_user.visible_communities_only(query);
// A Max depth given means its a tree fetch // A Max depth given means its a tree fetch
let (limit, offset) = if let Some(max_depth) = options.max_depth { let (limit, offset) = if let Some(max_depth) = options.max_depth {
@ -366,16 +360,16 @@ fn queries<'a>() -> Queries<
} }
impl CommentView { impl CommentView {
pub async fn read( pub async fn read<'a>(
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
comment_id: CommentId, comment_id: CommentId,
my_person_id: Option<PersonId>, my_local_user: Option<&'a LocalUser>,
) -> Result<Option<Self>, Error> { ) -> Result<Option<Self>, Error> {
// If a person is given, then my_vote (res.9), if None, should be 0, not null // If a person is given, then my_vote (res.9), if None, should be 0, not null
// Necessary to differentiate between other person's votes // Necessary to differentiate between other person's votes
if let Ok(Some(res)) = queries().read(pool, (comment_id, my_person_id)).await { if let Ok(Some(res)) = queries().read(pool, (comment_id, my_local_user)).await {
let mut new_view = res.clone(); let mut new_view = res.clone();
if my_person_id.is_some() && res.my_vote.is_none() { if my_local_user.is_some() && res.my_vote.is_none() {
new_view.my_vote = Some(0); new_view.my_vote = Some(0);
} }
if res.comment.deleted || res.comment.removed { if res.comment.deleted || res.comment.removed {
@ -676,7 +670,7 @@ mod tests {
let read_comment_from_blocked_person = CommentView::read( let read_comment_from_blocked_person = CommentView::read(
pool, pool,
data.inserted_comment_1.id, data.inserted_comment_1.id,
Some(data.timmy_local_user_view.person.id), Some(&data.timmy_local_user_view.local_user),
) )
.await? .await?
.ok_or(LemmyErrorType::CouldntFindComment)?; .ok_or(LemmyErrorType::CouldntFindComment)?;
@ -1171,7 +1165,7 @@ mod tests {
let authenticated_comment = CommentView::read( let authenticated_comment = CommentView::read(
pool, pool,
data.inserted_comment_0.id, data.inserted_comment_0.id,
Some(data.timmy_local_user_view.person.id), Some(&data.timmy_local_user_view.local_user),
) )
.await; .await;
assert!(authenticated_comment.is_ok()); assert!(authenticated_comment.is_ok());
@ -1211,7 +1205,7 @@ mod tests {
let comment_view = CommentView::read( let comment_view = CommentView::read(
pool, pool,
data.inserted_comment_0.id, data.inserted_comment_0.id,
Some(inserted_banned_from_comm_local_user.person_id), Some(&inserted_banned_from_comm_local_user),
) )
.await? .await?
.ok_or(LemmyErrorType::CouldntFindComment)?; .ok_or(LemmyErrorType::CouldntFindComment)?;
@ -1232,7 +1226,7 @@ mod tests {
let comment_view = CommentView::read( let comment_view = CommentView::read(
pool, pool,
data.inserted_comment_0.id, data.inserted_comment_0.id,
Some(data.timmy_local_user_view.person.id), Some(&data.timmy_local_user_view.local_user),
) )
.await? .await?
.ok_or(LemmyErrorType::CouldntFindComment)?; .ok_or(LemmyErrorType::CouldntFindComment)?;

View file

@ -49,7 +49,6 @@ use lemmy_db_schema::{
get_conn, get_conn,
limit_and_offset, limit_and_offset,
now, now,
visible_communities_only,
Commented, Commented,
DbConn, DbConn,
DbPool, DbPool,
@ -64,7 +63,7 @@ use lemmy_db_schema::{
use tracing::debug; use tracing::debug;
fn queries<'a>() -> Queries< fn queries<'a>() -> Queries<
impl ReadFn<'a, PostView, (PostId, Option<PersonId>, bool)>, impl ReadFn<'a, PostView, (PostId, Option<&'a LocalUser>, bool)>,
impl ListFn<'a, PostView, (PostQuery<'a>, &'a Site)>, impl ListFn<'a, PostView, (PostQuery<'a>, &'a Site)>,
> { > {
let is_creator_banned_from_community = exists( let is_creator_banned_from_community = exists(
@ -142,6 +141,7 @@ fn queries<'a>() -> Queries<
.single_value() .single_value()
}; };
// TODO maybe this should go to localuser also
let all_joins = move |query: post_aggregates::BoxedQuery<'a, Pg>, let all_joins = move |query: post_aggregates::BoxedQuery<'a, Pg>,
my_person_id: Option<PersonId>| { my_person_id: Option<PersonId>| {
let is_local_user_banned_from_community_selection: Box< let is_local_user_banned_from_community_selection: Box<
@ -250,52 +250,56 @@ fn queries<'a>() -> Queries<
)) ))
}; };
let read = let read = move |mut conn: DbConn<'a>,
move |mut conn: DbConn<'a>, (post_id, my_local_user, is_mod_or_admin): (
(post_id, my_person_id, is_mod_or_admin): (PostId, Option<PersonId>, bool)| async move { PostId,
// The left join below will return None in this case Option<&'a LocalUser>,
let person_id_join = my_person_id.unwrap_or(PersonId(-1)); bool,
)| async move {
// The left join below will return None in this case
let my_person_id = my_local_user.person_id();
let person_id_join = my_person_id.unwrap_or(PersonId(-1));
let mut query = all_joins( let mut query = all_joins(
post_aggregates::table post_aggregates::table
.filter(post_aggregates::post_id.eq(post_id)) .filter(post_aggregates::post_id.eq(post_id))
.into_boxed(), .into_boxed(),
my_person_id, my_person_id,
); );
// Hide deleted and removed for non-admins or mods // Hide deleted and removed for non-admins or mods
if !is_mod_or_admin { if !is_mod_or_admin {
query = query query = query
.filter( .filter(
community::removed community::removed
.eq(false) .eq(false)
.or(post::creator_id.eq(person_id_join)), .or(post::creator_id.eq(person_id_join)),
) )
.filter( .filter(
post::removed post::removed
.eq(false) .eq(false)
.or(post::creator_id.eq(person_id_join)), .or(post::creator_id.eq(person_id_join)),
) )
// users can see their own deleted posts // users can see their own deleted posts
.filter( .filter(
community::deleted community::deleted
.eq(false) .eq(false)
.or(post::creator_id.eq(person_id_join)), .or(post::creator_id.eq(person_id_join)),
) )
.filter( .filter(
post::deleted post::deleted
.eq(false) .eq(false)
.or(post::creator_id.eq(person_id_join)), .or(post::creator_id.eq(person_id_join)),
); );
} }
query = visible_communities_only(my_person_id, query); query = my_local_user.visible_communities_only(query);
Commented::new(query) Commented::new(query)
.text("PostView::read") .text("PostView::read")
.first(&mut conn) .first(&mut conn)
.await .await
}; };
let list = move |mut conn: DbConn<'a>, (options, site): (PostQuery<'a>, &'a Site)| async move { let list = move |mut conn: DbConn<'a>, (options, site): (PostQuery<'a>, &'a Site)| async move {
// The left join below will return None in this case // The left join below will return None in this case
@ -437,7 +441,7 @@ fn queries<'a>() -> Queries<
} }
}; };
query = visible_communities_only(options.local_user.person_id(), query); query = options.local_user.visible_communities_only(query);
// Dont filter blocks or missing languages for moderator view type // Dont filter blocks or missing languages for moderator view type
if let (Some(person_id), false) = ( if let (Some(person_id), false) = (
@ -552,14 +556,14 @@ fn queries<'a>() -> Queries<
} }
impl PostView { impl PostView {
pub async fn read( pub async fn read<'a>(
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
post_id: PostId, post_id: PostId,
my_person_id: Option<PersonId>, my_local_user: Option<&'a LocalUser>,
is_mod_or_admin: bool, is_mod_or_admin: bool,
) -> Result<Option<Self>, Error> { ) -> Result<Option<Self>, Error> {
queries() queries()
.read(pool, (post_id, my_person_id, is_mod_or_admin)) .read(pool, (post_id, my_local_user, is_mod_or_admin))
.await .await
} }
} }
@ -938,7 +942,7 @@ mod tests {
let post_listing_single_with_person = PostView::read( let post_listing_single_with_person = PostView::read(
pool, pool,
data.inserted_post.id, data.inserted_post.id,
Some(data.local_user_view.person.id), Some(&data.local_user_view.local_user),
false, false,
) )
.await? .await?
@ -1067,7 +1071,7 @@ mod tests {
let post_listing_single_with_person = PostView::read( let post_listing_single_with_person = PostView::read(
pool, pool,
data.inserted_post.id, data.inserted_post.id,
Some(data.local_user_view.person.id), Some(&data.local_user_view.local_user),
false, false,
) )
.await? .await?
@ -1755,7 +1759,7 @@ mod tests {
let authenticated_post = PostView::read( let authenticated_post = PostView::read(
pool, pool,
data.inserted_post.id, data.inserted_post.id,
Some(data.local_user_view.person.id), Some(&data.local_user_view.local_user),
false, false,
) )
.await; .await;
@ -1797,7 +1801,7 @@ mod tests {
let post_view = PostView::read( let post_view = PostView::read(
pool, pool,
data.inserted_post.id, data.inserted_post.id,
Some(inserted_banned_from_comm_local_user.person_id), Some(&inserted_banned_from_comm_local_user),
false, false,
) )
.await? .await?
@ -1819,7 +1823,7 @@ mod tests {
let post_view = PostView::read( let post_view = PostView::read(
pool, pool,
data.inserted_post.id, data.inserted_post.id,
Some(data.local_user_view.person.id), Some(&data.local_user_view.local_user),
false, false,
) )
.await? .await?

View file

@ -22,27 +22,18 @@ use lemmy_db_schema::{
instance_block, instance_block,
}, },
source::{community::CommunityFollower, local_user::LocalUser, site::Site}, source::{community::CommunityFollower, local_user::LocalUser, site::Site},
utils::{ utils::{fuzzy_search, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn},
fuzzy_search,
limit_and_offset,
visible_communities_only,
DbConn,
DbPool,
ListFn,
Queries,
ReadFn,
},
ListingType, ListingType,
SortType, SortType,
}; };
fn queries<'a>() -> Queries< fn queries<'a>() -> Queries<
impl ReadFn<'a, CommunityView, (CommunityId, Option<PersonId>, bool)>, impl ReadFn<'a, CommunityView, (CommunityId, Option<&'a LocalUser>, bool)>,
impl ListFn<'a, CommunityView, (CommunityQuery<'a>, &'a Site)>, impl ListFn<'a, CommunityView, (CommunityQuery<'a>, &'a Site)>,
> { > {
let all_joins = |query: community::BoxedQuery<'a, Pg>, my_person_id: Option<PersonId>| { let all_joins = |query: community::BoxedQuery<'a, Pg>, my_local_user: Option<&'a LocalUser>| {
// 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_local_user.person_id().unwrap_or(PersonId(-1));
query query
.inner_join(community_aggregates::table) .inner_join(community_aggregates::table)
@ -89,14 +80,14 @@ fn queries<'a>() -> Queries<
.and(community::deleted.eq(false)); .and(community::deleted.eq(false));
let read = move |mut conn: DbConn<'a>, let read = move |mut conn: DbConn<'a>,
(community_id, my_person_id, is_mod_or_admin): ( (community_id, my_local_user, is_mod_or_admin): (
CommunityId, CommunityId,
Option<PersonId>, Option<&'a LocalUser>,
bool, bool,
)| async move { )| async move {
let mut query = all_joins( let mut query = all_joins(
community::table.find(community_id).into_boxed(), community::table.find(community_id).into_boxed(),
my_person_id, my_local_user,
) )
.select(selection); .select(selection);
@ -105,7 +96,7 @@ fn queries<'a>() -> Queries<
query = query.filter(not_removed_or_deleted); query = query.filter(not_removed_or_deleted);
} }
query = visible_communities_only(my_person_id, query); query = my_local_user.visible_communities_only(query);
query.first(&mut conn).await query.first(&mut conn).await
}; };
@ -116,11 +107,7 @@ fn queries<'a>() -> Queries<
// The left join below will return None in this case // The left join below will return None in this case
let person_id_join = options.local_user.person_id().unwrap_or(PersonId(-1)); let person_id_join = options.local_user.person_id().unwrap_or(PersonId(-1));
let mut query = all_joins( let mut query = all_joins(community::table.into_boxed(), options.local_user).select(selection);
community::table.into_boxed(),
options.local_user.person_id(),
)
.select(selection);
if let Some(search_term) = options.search_term { if let Some(search_term) = options.search_term {
let searcher = fuzzy_search(&search_term); let searcher = fuzzy_search(&search_term);
@ -173,7 +160,7 @@ fn queries<'a>() -> Queries<
query = query.filter(community::nsfw.eq(false)); query = query.filter(community::nsfw.eq(false));
} }
query = visible_communities_only(options.local_user.person_id(), query); query = options.local_user.visible_communities_only(query);
let (limit, offset) = limit_and_offset(options.page, options.limit)?; let (limit, offset) = limit_and_offset(options.page, options.limit)?;
query query
@ -187,14 +174,14 @@ fn queries<'a>() -> Queries<
} }
impl CommunityView { impl CommunityView {
pub async fn read( pub async fn read<'a>(
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
community_id: CommunityId, community_id: CommunityId,
my_person_id: Option<PersonId>, my_local_user: Option<&'a LocalUser>,
is_mod_or_admin: bool, is_mod_or_admin: bool,
) -> Result<Option<Self>, Error> { ) -> Result<Option<Self>, Error> {
queries() queries()
.read(pool, (community_id, my_person_id, is_mod_or_admin)) .read(pool, (community_id, my_local_user, is_mod_or_admin))
.await .await
} }
@ -388,7 +375,7 @@ mod tests {
let authenticated_community = CommunityView::read( let authenticated_community = CommunityView::read(
pool, pool,
data.inserted_community.id, data.inserted_community.id,
Some(data.local_user.person_id), Some(&data.local_user),
false, false,
) )
.await; .await;