Refactor LocalUser settings conditions in database views (#4746)

* Create viewer.rs

* Rename viewer.rs to viewer.rs

* Update viewer.rs

* Update post_view.rs

* Update distinguish.rs

* Update like.rs

* Update viewer.rs

* Update list_comment_likes.rs

* Update like.rs

* Update save.rs

* Update like.rs

* revert changes in api crate

* Update post_view.rs

* Update post_view.rs

* Update comment_view.rs

* Update post_view.rs

* Update community_view.rs

* Update comment_view.rs

* Update post_view.rs

* Update viewer.rs

* Update post_view.rs

* Update community_view.rs

* Update local_user_view.rs

* Update viewer.rs

* Update community_view.rs

* Update viewer.rs

* Update lib.rs

* Update comment_view.rs

* Update post_view.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update local_user_view.rs

* Update viewer.rs

* Update viewer.rs

* Update local_user_view.rs

* Update community_view.rs

* Update viewer.rs

* Update crates/db_schema/src/viewer.rs

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update post_view.rs

* Update community_view.rs

* Update comment_view.rs

* Update viewer.rs

* Update post_view.rs

* Update save.rs

* Update resolve_object.rs

* Update viewer.rs

* Update save.rs

* Update resolve_object.rs

* Update comment_view.rs

* Update post_view.rs

* Update community_view.rs

* Update local_user_view.rs

* Update post_view.rs

* Update viewer.rs

* Update comment_view.rs

* Update post_view.rs

* Update community_view.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Some additions to localuser DB view helpers. (#39)

* Some additions to localuser DB view helpers.

- Getting rid of generics.
- Passing in only LocalUser to views.

* Formatting fixes.

* Getting rid of unecessary as_refs

* Fixing clippy.

---------

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: Dessalines <tyhou13@gmx.com>
This commit is contained in:
dullbananas 2024-06-14 18:51:24 -07:00 committed by GitHub
parent 65620913fc
commit 6497ec519e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 171 additions and 130 deletions

View file

@ -83,12 +83,13 @@ pub async fn get_post(
.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_view.as_ref(), local_user,
..Default::default() ..Default::default()
} }
.list(&local_site.site, &mut context.pool()) .list(&local_site.site, &mut context.pool())

View file

@ -70,6 +70,8 @@ pub async fn list_comments(
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.as_ref().map(|l| &l.local_user);
let comments = CommentQuery { let comments = CommentQuery {
listing_type, listing_type,
sort, sort,
@ -80,7 +82,7 @@ pub async fn list_comments(
community_id, community_id,
parent_path: parent_path_cloned, parent_path: parent_path_cloned,
post_id, post_id,
local_user: local_user_view.as_ref(), local_user,
page, page,
limit, limit,
..Default::default() ..Default::default()

View file

@ -49,17 +49,17 @@ pub async fn list_posts(
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters)); return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
} }
let local_user_ref = local_user_view.as_ref().map(|u| &u.local_user); let local_user = local_user_view.as_ref().map(|u| &u.local_user);
let listing_type = Some(listing_type_with_default( let listing_type = Some(listing_type_with_default(
data.type_, data.type_,
local_user_ref, local_user,
&local_site.local_site, &local_site.local_site,
community_id, community_id,
)); ));
let sort = Some(sort_type_with_default( let sort = Some(sort_type_with_default(
data.sort, data.sort,
local_user_ref, local_user,
&local_site.local_site, &local_site.local_site,
)); ));
@ -71,7 +71,7 @@ pub async fn list_posts(
}; };
let posts = PostQuery { let posts = PostQuery {
local_user: local_user_view.as_ref(), local_user,
listing_type, listing_type,
sort, sort,
community_id, community_id,

View file

@ -65,10 +65,12 @@ pub async fn read_person(
None None
}; };
let local_user = local_user_view.as_ref().map(|l| &l.local_user);
let posts = PostQuery { let posts = PostQuery {
sort, sort,
saved_only, saved_only,
local_user: local_user_view.as_ref(), local_user,
community_id, community_id,
page, page,
limit, limit,
@ -79,7 +81,7 @@ pub async fn read_person(
.await?; .await?;
let comments = CommentQuery { let comments = CommentQuery {
local_user: local_user_view.as_ref(), local_user,
sort: sort.map(post_to_comment_sort_type), sort: sort.map(post_to_comment_sort_type),
saved_only, saved_only,
community_id, community_id,

View file

@ -55,7 +55,7 @@ pub async fn search(
data.community_id data.community_id
}; };
let creator_id = data.creator_id; let creator_id = data.creator_id;
let local_user = local_user_view.as_ref().map(|luv| &luv.local_user); let local_user = local_user_view.as_ref().map(|l| &l.local_user);
match search_type { match search_type {
SearchType::Posts => { SearchType::Posts => {
@ -64,7 +64,7 @@ pub async fn search(
listing_type: (listing_type), listing_type: (listing_type),
community_id: (community_id), community_id: (community_id),
creator_id: (creator_id), creator_id: (creator_id),
local_user: (local_user_view.as_ref()), local_user,
search_term: (Some(q)), search_term: (Some(q)),
page: (page), page: (page),
limit: (limit), limit: (limit),
@ -80,7 +80,7 @@ pub async fn search(
search_term: (Some(q)), search_term: (Some(q)),
community_id: (community_id), community_id: (community_id),
creator_id: (creator_id), creator_id: (creator_id),
local_user: (local_user_view.as_ref()), local_user,
page: (page), page: (page),
limit: (limit), limit: (limit),
..Default::default() ..Default::default()
@ -125,7 +125,7 @@ pub async fn search(
listing_type: (listing_type), listing_type: (listing_type),
community_id: (community_id), community_id: (community_id),
creator_id: (creator_id), creator_id: (creator_id),
local_user: (local_user_view.as_ref()), local_user,
search_term: (Some(q)), search_term: (Some(q)),
page: (page), page: (page),
limit: (limit), limit: (limit),
@ -142,7 +142,7 @@ pub async fn search(
search_term: (Some(q)), search_term: (Some(q)),
community_id: (community_id), community_id: (community_id),
creator_id: (creator_id), creator_id: (creator_id),
local_user: (local_user_view.as_ref()), local_user,
page: (page), page: (page),
limit: (limit), limit: (limit),
..Default::default() ..Default::default()
@ -192,6 +192,7 @@ pub async fn search(
community_id: (community_id), community_id: (community_id),
creator_id: (creator_id), creator_id: (creator_id),
url_search: (Some(q)), url_search: (Some(q)),
local_user,
page: (page), page: (page),
limit: (limit), limit: (limit),
..Default::default() ..Default::default()

View file

@ -5,6 +5,7 @@ use crate::{
actor_language::LocalUserLanguage, actor_language::LocalUserLanguage,
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm}, local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
local_user_vote_display_mode::{LocalUserVoteDisplayMode, LocalUserVoteDisplayModeInsertForm}, local_user_vote_display_mode::{LocalUserVoteDisplayMode, LocalUserVoteDisplayModeInsertForm},
site::Site,
}, },
utils::{ utils::{
functions::{coalesce, lower}, functions::{coalesce, lower},
@ -216,6 +217,44 @@ impl LocalUser {
} }
} }
/// Adds some helper functions for an optional LocalUser
pub trait LocalUserOptionHelper {
fn person_id(&self) -> Option<PersonId>;
fn local_user_id(&self) -> Option<LocalUserId>;
fn show_bot_accounts(&self) -> bool;
fn show_read_posts(&self) -> bool;
fn is_admin(&self) -> bool;
fn show_nsfw(&self, site: &Site) -> bool;
}
impl LocalUserOptionHelper for Option<&LocalUser> {
fn person_id(&self) -> Option<PersonId> {
self.map(|l| l.person_id)
}
fn local_user_id(&self) -> Option<LocalUserId> {
self.map(|l| l.id)
}
fn show_bot_accounts(&self) -> bool {
self.map(|l| l.show_bot_accounts).unwrap_or(true)
}
fn show_read_posts(&self) -> bool {
self.map(|l| l.show_read_posts).unwrap_or(true)
}
fn is_admin(&self) -> bool {
self.map(|l| l.admin).unwrap_or(false)
}
fn show_nsfw(&self, site: &Site) -> bool {
self
.map(|l| l.show_nsfw)
.unwrap_or(site.content_warning.is_some())
}
}
impl LocalUserInsertForm { impl LocalUserInsertForm {
pub fn test_form(person_id: PersonId) -> Self { pub fn test_form(person_id: PersonId) -> Self {
Self::builder() Self::builder()

View file

@ -1,7 +1,15 @@
use crate::{newtypes::DbUrl, CommentSortType, SortType}; use crate::{
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},
@ -567,6 +575,20 @@ 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

@ -1,4 +1,4 @@
use crate::structs::{CommentView, LocalUserView}; use crate::structs::CommentView;
use diesel::{ use diesel::{
dsl::{exists, not}, dsl::{exists, not},
pg::Pg, pg::Pg,
@ -16,6 +16,7 @@ use diesel::{
use diesel_async::RunQueryDsl; use diesel_async::RunQueryDsl;
use diesel_ltree::{nlevel, subpath, Ltree, LtreeExtensions}; use diesel_ltree::{nlevel, subpath, Ltree, LtreeExtensions};
use lemmy_db_schema::{ use lemmy_db_schema::{
impls::local_user::LocalUserOptionHelper,
newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId}, newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId},
schema::{ schema::{
comment, comment,
@ -34,9 +35,18 @@ use lemmy_db_schema::{
person_block, person_block,
post, post,
}, },
utils::{fuzzy_search, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn}, source::local_user::LocalUser,
utils::{
fuzzy_search,
limit_and_offset,
visible_communities_only,
DbConn,
DbPool,
ListFn,
Queries,
ReadFn,
},
CommentSortType, CommentSortType,
CommunityVisibility,
ListingType, ListingType,
}; };
@ -174,22 +184,19 @@ 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_person_id): (CommentId, Option<PersonId>)| async move {
let mut query = all_joins(comment::table.find(comment_id).into_boxed(), my_person_id); let mut query = all_joins(comment::table.find(comment_id).into_boxed(), my_person_id);
// Hide local only communities from unauthenticated users query = visible_communities_only(my_person_id, query);
if my_person_id.is_none() {
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
}
query.first(&mut conn).await query.first(&mut conn).await
}; };
let list = move |mut conn: DbConn<'a>, options: CommentQuery<'a>| async move { let list = move |mut conn: DbConn<'a>, options: CommentQuery<'a>| async move {
let my_person_id = options.local_user.map(|l| l.person.id);
let my_local_user_id = options.local_user.map(|l| l.local_user.id);
// 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 = options.local_user.person_id().unwrap_or(PersonId(-1));
let local_user_id_join = my_local_user_id.unwrap_or(LocalUserId(-1)); let local_user_id_join = options
.local_user
.local_user_id()
.unwrap_or(LocalUserId(-1));
let mut query = all_joins(comment::table.into_boxed(), my_person_id); let mut query = all_joins(comment::table.into_boxed(), options.local_user.person_id());
if let Some(creator_id) = options.creator_id { if let Some(creator_id) = options.creator_id {
query = query.filter(comment::creator_id.eq(creator_id)); query = query.filter(comment::creator_id.eq(creator_id));
@ -251,7 +258,7 @@ fn queries<'a>() -> Queries<
.then_order_by(comment_saved::published.desc()); .then_order_by(comment_saved::published.desc());
} }
if let Some(my_id) = my_person_id { if let Some(my_id) = options.local_user.person_id() {
let not_creator_filter = comment::creator_id.ne(my_id); let not_creator_filter = comment::creator_id.ne(my_id);
if options.liked_only { if options.liked_only {
query = query.filter(not_creator_filter).filter(score(my_id).eq(1)); query = query.filter(not_creator_filter).filter(score(my_id).eq(1));
@ -260,11 +267,7 @@ fn queries<'a>() -> Queries<
} }
} }
if !options if !options.local_user.show_bot_accounts() {
.local_user
.map(|l| l.local_user.show_bot_accounts)
.unwrap_or(true)
{
query = query.filter(person::bot_account.eq(false)); query = query.filter(person::bot_account.eq(false));
}; };
@ -298,10 +301,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)));
}; };
// Hide comments in local only communities from unauthenticated users query = visible_communities_only(options.local_user.person_id(), query);
if options.local_user.is_none() {
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
}
// 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 {
@ -396,7 +396,7 @@ pub struct CommentQuery<'a> {
pub post_id: Option<PostId>, pub post_id: Option<PostId>,
pub parent_path: Option<Ltree>, pub parent_path: Option<Ltree>,
pub creator_id: Option<PersonId>, pub creator_id: Option<PersonId>,
pub local_user: Option<&'a LocalUserView>, pub local_user: Option<&'a LocalUser>,
pub search_term: Option<String>, pub search_term: Option<String>,
pub saved_only: bool, pub saved_only: bool,
pub liked_only: bool, pub liked_only: bool,
@ -659,7 +659,7 @@ mod tests {
let read_comment_views_with_person = CommentQuery { let read_comment_views_with_person = CommentQuery {
sort: (Some(CommentSortType::Old)), sort: (Some(CommentSortType::Old)),
post_id: (Some(data.inserted_post.id)), post_id: (Some(data.inserted_post.id)),
local_user: (Some(&data.timmy_local_user_view)), local_user: (Some(&data.timmy_local_user_view.local_user)),
..Default::default() ..Default::default()
} }
.list(pool) .list(pool)
@ -711,7 +711,7 @@ mod tests {
CommentLike::like(pool, &comment_like_form).await?; CommentLike::like(pool, &comment_like_form).await?;
let read_liked_comment_views = CommentQuery { let read_liked_comment_views = CommentQuery {
local_user: (Some(&data.timmy_local_user_view)), local_user: (Some(&data.timmy_local_user_view.local_user)),
liked_only: (true), liked_only: (true),
..Default::default() ..Default::default()
} }
@ -727,7 +727,7 @@ mod tests {
assert_length!(1, read_liked_comment_views); assert_length!(1, read_liked_comment_views);
let read_disliked_comment_views: Vec<CommentView> = CommentQuery { let read_disliked_comment_views: Vec<CommentView> = CommentQuery {
local_user: (Some(&data.timmy_local_user_view)), local_user: (Some(&data.timmy_local_user_view.local_user)),
disliked_only: (true), disliked_only: (true),
..Default::default() ..Default::default()
} }
@ -822,7 +822,7 @@ mod tests {
// by default, user has all languages enabled and should see all comments // by default, user has all languages enabled and should see all comments
// (except from blocked user) // (except from blocked user)
let all_languages = CommentQuery { let all_languages = CommentQuery {
local_user: (Some(&data.timmy_local_user_view)), local_user: (Some(&data.timmy_local_user_view.local_user)),
..Default::default() ..Default::default()
} }
.list(pool) .list(pool)
@ -840,7 +840,7 @@ mod tests {
) )
.await?; .await?;
let finnish_comments = CommentQuery { let finnish_comments = CommentQuery {
local_user: (Some(&data.timmy_local_user_view)), local_user: (Some(&data.timmy_local_user_view.local_user)),
..Default::default() ..Default::default()
} }
.list(pool) .list(pool)
@ -866,7 +866,7 @@ mod tests {
) )
.await?; .await?;
let undetermined_comment = CommentQuery { let undetermined_comment = CommentQuery {
local_user: (Some(&data.timmy_local_user_view)), local_user: (Some(&data.timmy_local_user_view.local_user)),
..Default::default() ..Default::default()
} }
.list(pool) .list(pool)
@ -979,7 +979,7 @@ mod tests {
// Fetch the saved comments // Fetch the saved comments
let comments = CommentQuery { let comments = CommentQuery {
local_user: Some(&data.timmy_local_user_view), local_user: Some(&data.timmy_local_user_view.local_user),
saved_only: true, saved_only: true,
..Default::default() ..Default::default()
} }
@ -1158,7 +1158,7 @@ mod tests {
assert_eq!(0, unauthenticated_query.len()); assert_eq!(0, unauthenticated_query.len());
let authenticated_query = CommentQuery { let authenticated_query = CommentQuery {
local_user: Some(&data.timmy_local_user_view), local_user: Some(&data.timmy_local_user_view.local_user),
..Default::default() ..Default::default()
} }
.list(pool) .list(pool)

View file

@ -1,4 +1,4 @@
use crate::structs::{LocalUserView, PaginationCursor, PostView}; use crate::structs::{PaginationCursor, PostView};
use diesel::{ use diesel::{
debug_query, debug_query,
dsl::{exists, not, IntervalDsl}, dsl::{exists, not, IntervalDsl},
@ -20,6 +20,7 @@ use diesel_async::RunQueryDsl;
use i_love_jesus::PaginatedQueryBuilder; use i_love_jesus::PaginatedQueryBuilder;
use lemmy_db_schema::{ use lemmy_db_schema::{
aggregates::structs::{post_aggregates_keys as key, PostAggregates}, aggregates::structs::{post_aggregates_keys as key, PostAggregates},
impls::local_user::LocalUserOptionHelper,
newtypes::{CommunityId, LocalUserId, PersonId, PostId}, newtypes::{CommunityId, LocalUserId, PersonId, PostId},
schema::{ schema::{
community, community,
@ -40,13 +41,14 @@ use lemmy_db_schema::{
post_read, post_read,
post_saved, post_saved,
}, },
source::site::Site, source::{local_user::LocalUser, site::Site},
utils::{ utils::{
functions::coalesce, functions::coalesce,
fuzzy_search, fuzzy_search,
get_conn, get_conn,
limit_and_offset, limit_and_offset,
now, now,
visible_communities_only,
Commented, Commented,
DbConn, DbConn,
DbPool, DbPool,
@ -55,7 +57,6 @@ use lemmy_db_schema::{
ReadFn, ReadFn,
ReverseTimestampKey, ReverseTimestampKey,
}, },
CommunityVisibility,
ListingType, ListingType,
SortType, SortType,
}; };
@ -285,10 +286,7 @@ fn queries<'a>() -> Queries<
); );
} }
// Hide posts in local only communities from unauthenticated users query = visible_communities_only(my_person_id, query);
if my_person_id.is_none() {
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
}
Commented::new(query) Commented::new(query)
.text("PostView::read") .text("PostView::read")
@ -297,31 +295,30 @@ fn queries<'a>() -> Queries<
}; };
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 {
let my_person_id = options.local_user.map(|l| l.person.id);
let my_local_user_id = options.local_user.map(|l| l.local_user.id);
// 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 = options.local_user.person_id().unwrap_or(PersonId(-1));
let local_user_id_join = my_local_user_id.unwrap_or(LocalUserId(-1)); let local_user_id_join = options
.local_user
.local_user_id()
.unwrap_or(LocalUserId(-1));
let mut query = all_joins(post_aggregates::table.into_boxed(), my_person_id); let mut query = all_joins(
post_aggregates::table.into_boxed(),
options.local_user.person_id(),
);
// hide posts from deleted communities // hide posts from deleted communities
query = query.filter(community::deleted.eq(false)); query = query.filter(community::deleted.eq(false));
// only show deleted posts to creator // only show deleted posts to creator
if let Some(person_id) = my_person_id { if let Some(person_id) = options.local_user.person_id() {
query = query.filter(post::deleted.eq(false).or(post::creator_id.eq(person_id))); query = query.filter(post::deleted.eq(false).or(post::creator_id.eq(person_id)));
} else { } else {
query = query.filter(post::deleted.eq(false)); query = query.filter(post::deleted.eq(false));
} }
let is_admin = options
.local_user
.map(|l| l.local_user.admin)
.unwrap_or(false);
// only show removed posts to admin when viewing user profile // only show removed posts to admin when viewing user profile
if !(options.creator_id.is_some() && is_admin) { if !(options.creator_id.is_some() && options.local_user.is_admin()) {
query = query query = query
.filter(community::removed.eq(false)) .filter(community::removed.eq(false))
.filter(post::removed.eq(false)); .filter(post::removed.eq(false));
@ -335,7 +332,7 @@ fn queries<'a>() -> Queries<
} }
if let Some(listing_type) = options.listing_type { if let Some(listing_type) = options.listing_type {
if let Some(person_id) = my_person_id { if let Some(person_id) = options.local_user.person_id() {
let is_subscribed = exists( let is_subscribed = exists(
community_follower::table.filter( community_follower::table.filter(
post_aggregates::community_id post_aggregates::community_id
@ -392,54 +389,40 @@ fn queries<'a>() -> Queries<
.filter(not(post::removed.or(post::deleted))); .filter(not(post::removed.or(post::deleted)));
} }
// If there is a content warning, show nsfw content by default. if !options.local_user.show_nsfw(site) {
let has_content_warning = site.content_warning.is_some();
if !options
.local_user
.map(|l| l.local_user.show_nsfw)
.unwrap_or(has_content_warning)
{
query = query query = query
.filter(post::nsfw.eq(false)) .filter(post::nsfw.eq(false))
.filter(community::nsfw.eq(false)); .filter(community::nsfw.eq(false));
}; };
if !options if !options.local_user.show_bot_accounts() {
.local_user
.map(|l| l.local_user.show_bot_accounts)
.unwrap_or(true)
{
query = query.filter(person::bot_account.eq(false)); query = query.filter(person::bot_account.eq(false));
}; };
// If its saved only, then filter, and order by the saved time, not the comment creation time. // If its saved only, then filter, and order by the saved time, not the comment creation time.
if let (true, Some(_person_id)) = (options.saved_only, my_person_id) { if options.saved_only {
query = query query = query
.filter(post_saved::person_id.is_not_null()) .filter(post_saved::person_id.is_not_null())
.then_order_by(post_saved::published.desc()); .then_order_by(post_saved::published.desc());
} }
// Only hide the read posts, if the saved_only is false. Otherwise ppl with the hide_read // Only hide the read posts, if the saved_only is false. Otherwise ppl with the hide_read
// setting wont be able to see saved posts. // setting wont be able to see saved posts.
else if !options else if !options.local_user.show_read_posts() {
.local_user
.map(|l| l.local_user.show_read_posts)
.unwrap_or(true)
{
// Do not hide read posts when it is a user profile view // Do not hide read posts when it is a user profile view
// Or, only hide read posts on non-profile views // Or, only hide read posts on non-profile views
if let (None, Some(person_id)) = (options.creator_id, my_person_id) { if let (None, Some(person_id)) = (options.creator_id, options.local_user.person_id()) {
query = query.filter(not(is_read(person_id))); query = query.filter(not(is_read(person_id)));
} }
} }
if !options.show_hidden { if !options.show_hidden {
// If a creator id isn't given (IE its on home or community pages), hide the hidden posts // If a creator id isn't given (IE its on home or community pages), hide the hidden posts
if let (None, Some(person_id)) = (options.creator_id, my_person_id) { if let (None, Some(person_id)) = (options.creator_id, options.local_user.person_id()) {
query = query.filter(not(is_hidden(person_id))); query = query.filter(not(is_hidden(person_id)));
} }
} }
if let Some(my_id) = my_person_id { if let Some(my_id) = options.local_user.person_id() {
let not_creator_filter = post_aggregates::creator_id.ne(my_id); let not_creator_filter = post_aggregates::creator_id.ne(my_id);
if options.liked_only { if options.liked_only {
query = query.filter(not_creator_filter).filter(score(my_id).eq(1)); query = query.filter(not_creator_filter).filter(score(my_id).eq(1));
@ -448,14 +431,11 @@ fn queries<'a>() -> Queries<
} }
}; };
// Hide posts in local only communities from unauthenticated users query = visible_communities_only(options.local_user.person_id(), query);
if options.local_user.is_none() {
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
}
// 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) = (
my_person_id, options.local_user.person_id(),
options.listing_type.unwrap_or_default() == ListingType::ModeratorView, options.listing_type.unwrap_or_default() == ListingType::ModeratorView,
) { ) {
// Filter out the rows with missing languages // Filter out the rows with missing languages
@ -618,7 +598,7 @@ pub struct PostQuery<'a> {
// if true, the query should be handled as if community_id was not given except adding the // if true, the query should be handled as if community_id was not given except adding the
// literal filter // literal filter
pub community_id_just_for_prefetch: bool, pub community_id_just_for_prefetch: bool,
pub local_user: Option<&'a LocalUserView>, pub local_user: Option<&'a LocalUser>,
pub search_term: Option<String>, pub search_term: Option<String>,
pub url_search: Option<String>, pub url_search: Option<String>,
pub saved_only: bool, pub saved_only: bool,
@ -663,11 +643,7 @@ impl<'a> PostQuery<'a> {
"legacy pagination cannot be combined with v2 pagination".into(), "legacy pagination cannot be combined with v2 pagination".into(),
)); ));
} }
let self_person_id = self let self_person_id = self.local_user.expect("part of the above if").person_id;
.local_user
.expect("part of the above if")
.local_user
.person_id;
let largest_subscribed = { let largest_subscribed = {
let conn = &mut get_conn(pool).await?; let conn = &mut get_conn(pool).await?;
community_follower community_follower
@ -807,7 +783,7 @@ mod tests {
fn default_post_query(&self) -> PostQuery<'_> { fn default_post_query(&self) -> PostQuery<'_> {
PostQuery { PostQuery {
sort: Some(SortType::New), sort: Some(SortType::New),
local_user: Some(&self.local_user_view), local_user: Some(&self.local_user_view.local_user),
..Default::default() ..Default::default()
} }
} }
@ -1324,8 +1300,8 @@ mod tests {
// Deleted post is only shown to creator // Deleted post is only shown to creator
for (local_user, expect_contains_deleted) in [ for (local_user, expect_contains_deleted) in [
(None, false), (None, false),
(Some(&data.blocked_local_user_view), false), (Some(&data.blocked_local_user_view.local_user), false),
(Some(&data.local_user_view), true), (Some(&data.local_user_view.local_user), true),
] { ] {
let contains_deleted = PostQuery { let contains_deleted = PostQuery {
local_user, local_user,
@ -1563,7 +1539,7 @@ mod tests {
// Make sure it does come back with the show_hidden option // Make sure it does come back with the show_hidden option
let post_listings_show_hidden = PostQuery { let post_listings_show_hidden = PostQuery {
sort: Some(SortType::New), sort: Some(SortType::New),
local_user: Some(&data.local_user_view), local_user: Some(&data.local_user_view.local_user),
show_hidden: true, show_hidden: true,
..Default::default() ..Default::default()
} }
@ -1738,7 +1714,7 @@ mod tests {
assert_eq!(0, unauthenticated_query.len()); assert_eq!(0, unauthenticated_query.len());
let authenticated_query = PostQuery { let authenticated_query = PostQuery {
local_user: Some(&data.local_user_view), local_user: Some(&data.local_user_view.local_user),
..Default::default() ..Default::default()
} }
.list(&data.site, pool) .list(&data.site, pool)

View file

@ -11,6 +11,7 @@ use diesel::{
}; };
use diesel_async::RunQueryDsl; use diesel_async::RunQueryDsl;
use lemmy_db_schema::{ use lemmy_db_schema::{
impls::local_user::LocalUserOptionHelper,
newtypes::{CommunityId, PersonId}, newtypes::{CommunityId, PersonId},
schema::{ schema::{
community, community,
@ -19,11 +20,18 @@ use lemmy_db_schema::{
community_follower, community_follower,
community_person_ban, community_person_ban,
instance_block, instance_block,
local_user,
}, },
source::{community::CommunityFollower, local_user::LocalUser, site::Site}, source::{community::CommunityFollower, local_user::LocalUser, site::Site},
utils::{fuzzy_search, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn}, utils::{
CommunityVisibility, fuzzy_search,
limit_and_offset,
visible_communities_only,
DbConn,
DbPool,
ListFn,
Queries,
ReadFn,
},
ListingType, ListingType,
SortType, SortType,
}; };
@ -97,10 +105,7 @@ fn queries<'a>() -> Queries<
query = query.filter(not_removed_or_deleted); query = query.filter(not_removed_or_deleted);
} }
// Hide local only communities from unauthenticated users query = visible_communities_only(my_person_id, query);
if my_person_id.is_none() {
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
}
query.first(&mut conn).await query.first(&mut conn).await
}; };
@ -108,13 +113,13 @@ fn queries<'a>() -> Queries<
let list = move |mut conn: DbConn<'a>, (options, site): (CommunityQuery<'a>, &'a Site)| async move { let list = move |mut conn: DbConn<'a>, (options, site): (CommunityQuery<'a>, &'a Site)| async move {
use SortType::*; use SortType::*;
let my_person_id = options.local_user.map(|l| l.person_id);
// 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 = options.local_user.person_id().unwrap_or(PersonId(-1));
let mut query = all_joins(community::table.into_boxed(), my_person_id) let mut query = all_joins(
.left_join(local_user::table.on(local_user::person_id.eq(person_id_join))) community::table.into_boxed(),
options.local_user.person_id(),
)
.select(selection); .select(selection);
if let Some(search_term) = options.search_term { if let Some(search_term) = options.search_term {
@ -162,20 +167,13 @@ fn queries<'a>() -> Queries<
// Don't show blocked communities and communities on blocked instances. nsfw communities are // Don't show blocked communities and communities on blocked instances. nsfw communities are
// also hidden (based on profile setting) // also hidden (based on profile setting)
if options.local_user.is_some() {
query = query.filter(instance_block::person_id.is_null()); query = query.filter(instance_block::person_id.is_null());
query = query.filter(community_block::person_id.is_null()); query = query.filter(community_block::person_id.is_null());
query = query.filter(community::nsfw.eq(false).or(local_user::show_nsfw.eq(true))); if !(options.local_user.show_nsfw(site) || options.show_nsfw) {
} else {
// No person in request, only show nsfw communities if show_nsfw is passed into request or if
// site has content warning.
let has_content_warning = site.content_warning.is_some();
if !options.show_nsfw && !has_content_warning {
query = query.filter(community::nsfw.eq(false)); query = query.filter(community::nsfw.eq(false));
} }
// Hide local only communities from unauthenticated users
query = query.filter(community::visibility.eq(CommunityVisibility::Public)); query = visible_communities_only(options.local_user.person_id(), query);
}
let (limit, offset) = limit_and_offset(options.page, options.limit)?; let (limit, offset) = limit_and_offset(options.page, options.limit)?;
query query

View file

@ -355,7 +355,7 @@ async fn get_feed_front(
let posts = PostQuery { let posts = PostQuery {
listing_type: (Some(ListingType::Subscribed)), listing_type: (Some(ListingType::Subscribed)),
local_user: (Some(&local_user)), local_user: (Some(&local_user.local_user)),
sort: (Some(*sort_type)), sort: (Some(*sort_type)),
limit: (Some(*limit)), limit: (Some(*limit)),
page: (Some(*page)), page: (Some(*page)),