Merge remote-tracking branch 'origin/main' into auto_mark_posts_as_read

This commit is contained in:
Dessalines 2024-11-13 08:46:49 -05:00
commit e0da787890
8 changed files with 86 additions and 88 deletions

View file

@ -122,5 +122,5 @@
} }
# Sets a response Access-Control-Allow-Origin CORS header # Sets a response Access-Control-Allow-Origin CORS header
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
cors_origin: "*" cors_origin: "lemmy.tld"
} }

View file

@ -16,9 +16,8 @@ use lemmy_api_common::{
}, },
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
impls::actor_language::default_post_language, impls::actor_language::validate_post_language,
source::{ source::{
actor_language::CommunityLanguage,
comment::{Comment, CommentInsertForm, CommentLike, CommentLikeForm}, comment::{Comment, CommentInsertForm, CommentLike, CommentLikeForm},
comment_reply::{CommentReply, CommentReplyUpdateForm}, comment_reply::{CommentReply, CommentReplyUpdateForm},
local_site::LocalSite, local_site::LocalSite,
@ -93,21 +92,13 @@ pub async fn create_comment(
check_comment_depth(parent)?; check_comment_depth(parent)?;
} }
// attempt to set default language if none was provided let language_id = validate_post_language(
let language_id = match data.language_id { &mut context.pool(),
Some(lid) => lid, data.language_id,
None => { community_id,
default_post_language( local_user_view.local_user.id,
&mut context.pool(), )
community_id, .await?;
local_user_view.local_user.id,
)
.await?
}
};
CommunityLanguage::is_allowed_community_language(&mut context.pool(), language_id, community_id)
.await?;
let comment_form = CommentInsertForm { let comment_form = CommentInsertForm {
language_id: Some(language_id), language_id: Some(language_id),

View file

@ -13,8 +13,8 @@ use lemmy_api_common::{
}, },
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
impls::actor_language::validate_post_language,
source::{ source::{
actor_language::CommunityLanguage,
comment::{Comment, CommentUpdateForm}, comment::{Comment, CommentUpdateForm},
local_site::LocalSite, local_site::LocalSite,
}, },
@ -55,14 +55,13 @@ pub async fn update_comment(
Err(LemmyErrorType::NoCommentEditAllowed)? Err(LemmyErrorType::NoCommentEditAllowed)?
} }
if let Some(language_id) = data.language_id { let language_id = validate_post_language(
CommunityLanguage::is_allowed_community_language( &mut context.pool(),
&mut context.pool(), data.language_id,
language_id, orig_comment.community.id,
orig_comment.community.id, local_user_view.local_user.id,
) )
.await?; .await?;
}
let slur_regex = local_site_to_slur_regex(&local_site); let slur_regex = local_site_to_slur_regex(&local_site);
let url_blocklist = get_url_blocklist(&context).await?; let url_blocklist = get_url_blocklist(&context).await?;
@ -74,7 +73,7 @@ pub async fn update_comment(
let comment_id = data.comment_id; let comment_id = data.comment_id;
let form = CommentUpdateForm { let form = CommentUpdateForm {
content, content,
language_id: data.language_id, language_id: Some(language_id),
updated: Some(Some(naive_now())), updated: Some(Some(naive_now())),
..Default::default() ..Default::default()
}; };

View file

@ -16,9 +16,8 @@ use lemmy_api_common::{
}, },
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
impls::actor_language::default_post_language, impls::actor_language::validate_post_language,
source::{ source::{
actor_language::CommunityLanguage,
community::Community, community::Community,
local_site::LocalSite, local_site::LocalSite,
post::{Post, PostInsertForm, PostLike, PostLikeForm, PostRead}, post::{Post, PostInsertForm, PostLike, PostLikeForm, PostRead},
@ -97,23 +96,13 @@ pub async fn create_post(
.await?; .await?;
} }
// attempt to set default language if none was provided let language_id = validate_post_language(
let language_id = match data.language_id { &mut context.pool(),
Some(lid) => lid, data.language_id,
None => { data.community_id,
default_post_language( local_user_view.local_user.id,
&mut context.pool(), )
community.id, .await?;
local_user_view.local_user.id,
)
.await?
}
};
// Only need to check if language is allowed in case user set it explicitly. When using default
// language, it already only returns allowed languages.
CommunityLanguage::is_allowed_community_language(&mut context.pool(), language_id, community.id)
.await?;
let scheduled_publish_time = let scheduled_publish_time =
convert_published_time(data.scheduled_publish_time, &local_user_view, &context).await?; convert_published_time(data.scheduled_publish_time, &local_user_view, &context).await?;

View file

@ -15,8 +15,8 @@ use lemmy_api_common::{
}, },
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
impls::actor_language::validate_post_language,
source::{ source::{
actor_language::CommunityLanguage,
community::Community, community::Community,
local_site::LocalSite, local_site::LocalSite,
post::{Post, PostUpdateForm}, post::{Post, PostUpdateForm},
@ -101,14 +101,13 @@ pub async fn update_post(
Err(LemmyErrorType::NoPostEditAllowed)? Err(LemmyErrorType::NoPostEditAllowed)?
} }
if let Some(language_id) = data.language_id { let language_id = validate_post_language(
CommunityLanguage::is_allowed_community_language( &mut context.pool(),
&mut context.pool(), data.language_id,
language_id, orig_post.post.community_id,
orig_post.community.id, local_user_view.local_user.id,
) )
.await?; .await?;
}
// handle changes to scheduled_publish_time // handle changes to scheduled_publish_time
let scheduled_publish_time = match ( let scheduled_publish_time = match (
@ -131,7 +130,7 @@ pub async fn update_post(
body, body,
alt_text, alt_text,
nsfw: data.nsfw, nsfw: data.nsfw,
language_id: data.language_id, language_id: Some(language_id),
updated: Some(Some(naive_now())), updated: Some(Some(naive_now())),
scheduled_publish_time, scheduled_publish_time,
..Default::default() ..Default::default()

View file

@ -197,7 +197,7 @@ impl SiteLanguage {
impl CommunityLanguage { impl CommunityLanguage {
/// Returns true if the given language is one of configured languages for given community /// Returns true if the given language is one of configured languages for given community
pub async fn is_allowed_community_language( async fn is_allowed_community_language(
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
for_language_id: LanguageId, for_language_id: LanguageId,
for_community_id: CommunityId, for_community_id: CommunityId,
@ -319,29 +319,38 @@ impl CommunityLanguage {
} }
} }
pub async fn default_post_language( pub async fn validate_post_language(
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
language_id: Option<LanguageId>,
community_id: CommunityId, community_id: CommunityId,
local_user_id: LocalUserId, local_user_id: LocalUserId,
) -> Result<LanguageId, Error> { ) -> LemmyResult<LanguageId> {
use crate::schema::{community_language::dsl as cl, local_user_language::dsl as ul}; use crate::schema::{community_language::dsl as cl, local_user_language::dsl as ul};
let conn = &mut get_conn(pool).await?; let conn = &mut get_conn(pool).await?;
let mut intersection = ul::local_user_language let language_id = match language_id {
.inner_join(cl::community_language.on(ul::language_id.eq(cl::language_id))) None | Some(LanguageId(0)) => {
.filter(ul::local_user_id.eq(local_user_id)) let mut intersection = ul::local_user_language
.filter(cl::community_id.eq(community_id)) .inner_join(cl::community_language.on(ul::language_id.eq(cl::language_id)))
.select(cl::language_id) .filter(ul::local_user_id.eq(local_user_id))
.get_results::<LanguageId>(conn) .filter(cl::community_id.eq(community_id))
.await?; .select(cl::language_id)
.get_results::<LanguageId>(conn)
.await?;
if intersection.len() == 1 { if intersection.len() == 1 {
Ok(intersection.pop().unwrap_or(UNDETERMINED_ID)) intersection.pop().unwrap_or(UNDETERMINED_ID)
} else if intersection.len() == 2 && intersection.contains(&UNDETERMINED_ID) { } else if intersection.len() == 2 && intersection.contains(&UNDETERMINED_ID) {
intersection.retain(|i| i != &UNDETERMINED_ID); intersection.retain(|i| i != &UNDETERMINED_ID);
Ok(intersection.pop().unwrap_or(UNDETERMINED_ID)) intersection.pop().unwrap_or(UNDETERMINED_ID)
} else { } else {
Ok(UNDETERMINED_ID) UNDETERMINED_ID
} }
}
Some(lid) => lid,
};
CommunityLanguage::is_allowed_community_language(pool, language_id, community_id).await?;
Ok(language_id)
} }
/// If no language is given, set all languages /// If no language is given, set all languages
@ -590,7 +599,7 @@ mod tests {
#[tokio::test] #[tokio::test]
#[serial] #[serial]
async fn test_default_post_language() -> Result<(), Error> { async fn test_validate_post_language() -> LemmyResult<()> {
let pool = &build_db_pool_for_tests(); let pool = &build_db_pool_for_tests();
let pool = &mut pool.into(); let pool = &mut pool.into();
let (site, instance) = create_test_site(pool).await?; let (site, instance) = create_test_site(pool).await?;
@ -613,8 +622,11 @@ mod tests {
LocalUserLanguage::update(pool, test_langs2, local_user.id).await?; LocalUserLanguage::update(pool, test_langs2, local_user.id).await?;
// no overlap in user/community languages, so defaults to undetermined // no overlap in user/community languages, so defaults to undetermined
let def1 = default_post_language(pool, community.id, local_user.id).await?; let def1 = validate_post_language(pool, None, community.id, local_user.id).await;
assert_eq!(UNDETERMINED_ID, def1); assert_eq!(
Some(LemmyErrorType::LanguageNotAllowed),
def1.err().map(|e| e.error_type)
);
let ru = Language::read_id_from_code(pool, "ru").await?; let ru = Language::read_id_from_code(pool, "ru").await?;
let test_langs3 = vec![ let test_langs3 = vec![
@ -626,7 +638,7 @@ mod tests {
LocalUserLanguage::update(pool, test_langs3, local_user.id).await?; LocalUserLanguage::update(pool, test_langs3, local_user.id).await?;
// this time, both have ru as common lang // this time, both have ru as common lang
let def2 = default_post_language(pool, community.id, local_user.id).await?; let def2 = validate_post_language(pool, None, community.id, local_user.id).await?;
assert_eq!(ru, def2); assert_eq!(ru, def2);
Person::delete(pool, person.id).await?; Person::delete(pool, person.id).await?;

View file

@ -52,7 +52,7 @@ pub struct Settings {
/// Sets a response Access-Control-Allow-Origin CORS header /// Sets a response Access-Control-Allow-Origin CORS header
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin /// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
#[default(None)] #[default(None)]
#[doku(example = "*")] #[doku(example = "lemmy.tld")]
cors_origin: Option<String>, cors_origin: Option<String>,
} }

View file

@ -339,23 +339,31 @@ fn create_http_server(
fn cors_config(settings: &Settings) -> Cors { fn cors_config(settings: &Settings) -> Cors {
let self_origin = settings.get_protocol_and_hostname(); let self_origin = settings.get_protocol_and_hostname();
let cors_origin_setting = settings.cors_origin(); let cors_origin_setting = settings.cors_origin();
// A default setting for either wildcard, or None
let cors_default = Cors::default()
.allow_any_origin()
.allow_any_method()
.allow_any_header()
.expose_any_header()
.max_age(3600);
match (cors_origin_setting.clone(), cfg!(debug_assertions)) { match (cors_origin_setting.clone(), cfg!(debug_assertions)) {
(Some(origin), false) => { (Some(origin), false) => {
// Need to call send_wildcard() explicitly, passing this into allowed_origin() results in // Need to call send_wildcard() explicitly, passing this into allowed_origin() results in
// error // error
if cors_origin_setting.as_deref() == Some("*") { if origin == "*" {
Cors::default().allow_any_origin().send_wildcard() cors_default
} else { } else {
Cors::default() Cors::default()
.allowed_origin(&origin) .allowed_origin(&origin)
.allowed_origin(&self_origin) .allowed_origin(&self_origin)
.allow_any_method()
.allow_any_header()
.expose_any_header()
.max_age(3600)
} }
} }
_ => Cors::default() _ => cors_default,
.allow_any_origin()
.allow_any_method()
.allow_any_header()
.expose_any_header()
.max_age(3600),
} }
} }