From 6b9d9dfaa518e10026c04e0192022b8d6b044517 Mon Sep 17 00:00:00 2001 From: Kroese Date: Wed, 24 Apr 2024 04:52:56 +0200 Subject: [PATCH 1/4] Fix broken thumbnails (#4661) * Check is_image_post flag * Keep cargo_fmt happy * Filter on is_image_post * Trigger CI * Keep cargo_fmt happy --- crates/api_common/src/request.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/api_common/src/request.rs b/crates/api_common/src/request.rs index ddb2a4551..abf99f670 100644 --- a/crates/api_common/src/request.rs +++ b/crates/api_common/src/request.rs @@ -105,7 +105,11 @@ pub fn generate_post_link_metadata( } // Generate local thumbnail if allowed else if allow_generate_thumbnail { - match post.url.or(metadata.opengraph_data.image) { + match post + .url + .filter(|_| is_image_post) + .or(metadata.opengraph_data.image) + { Some(url) => generate_pictrs_thumbnail(&url, &context).await.ok(), None => None, } From 66e06b39529d397693fd414d6e2bec8519e3415e Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 23 Apr 2024 23:15:20 -0400 Subject: [PATCH 2/4] Removing scheme from block urls. Fixes #4656 (#4659) * Removing scheme from block urls. Fixes #4656 * Fix comment. * Fixing domain checking. * Removing pointless URL building in url blocklist regex. * Remove trailing / --- crates/api_common/src/utils.rs | 21 +--------- crates/utils/src/utils/validation.rs | 63 ++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index 3cd7902e1..4ab587928 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -536,25 +536,8 @@ pub async fn get_url_blocklist(context: &LemmyContext) -> LemmyResult .try_get_with::<_, LemmyError>((), async { let urls = LocalSiteUrlBlocklist::get_all(&mut context.pool()).await?; - let regexes = urls.iter().map(|url| { - let url = &url.url; - let parsed = Url::parse(url).expect("Coundln't parse URL."); - if url.ends_with('/') { - format!( - "({}://)?{}{}?", - parsed.scheme(), - escape(parsed.domain().expect("No domain.")), - escape(parsed.path()) - ) - } else { - format!( - "({}://)?{}{}", - parsed.scheme(), - escape(parsed.domain().expect("No domain.")), - escape(parsed.path()) - ) - } - }); + // The urls are already validated on saving, so just escape them. + let regexes = urls.iter().map(|url| escape(&url.url)); let set = RegexSet::new(regexes)?; Ok(set) diff --git a/crates/utils/src/utils/validation.rs b/crates/utils/src/utils/validation.rs index 93d581327..a6539f1b1 100644 --- a/crates/utils/src/utils/validation.rs +++ b/crates/utils/src/utils/validation.rs @@ -309,21 +309,44 @@ pub fn is_url_blocked(url: &Option, blocklist: &RegexSet) -> LemmyResult<() Ok(()) } +/// Check that urls are valid, and also remove the scheme, and uniques pub fn check_urls_are_valid(urls: &Vec) -> LemmyResult> { let mut parsed_urls = vec![]; for url in urls { - let url = Url::parse(url).or_else(|e| { - if e == ParseError::RelativeUrlWithoutBase { - Url::parse(&format!("https://{url}")) - } else { - Err(e) - } - })?; + parsed_urls.push(build_url_str_without_scheme(url)?); + } - parsed_urls.push(url.to_string()); + let unique_urls = parsed_urls.into_iter().unique().collect(); + Ok(unique_urls) +} + +pub fn build_url_str_without_scheme(url_str: &str) -> LemmyResult { + // Parse and check for errors + let mut url = Url::parse(url_str).or_else(|e| { + if e == ParseError::RelativeUrlWithoutBase { + Url::parse(&format!("http://{url_str}")) + } else { + Err(e) + } + })?; + + // Set the scheme to http, then remove the http:// part + url + .set_scheme("http") + .map_err(|_| LemmyErrorType::InvalidUrl)?; + + let mut out = url + .to_string() + .get(7..) + .ok_or(LemmyErrorType::InvalidUrl)? + .to_string(); + + // Remove trailing / if necessary + if out.ends_with('/') { + out.pop(); } - Ok(parsed_urls) + Ok(out) } #[cfg(test)] @@ -600,17 +623,21 @@ mod tests { #[test] fn test_url_parsed() { + // Make sure the scheme is removed, and uniques also assert_eq!( - vec![String::from("https://example.com/")], - check_urls_are_valid(&vec![String::from("example.com")]).unwrap() + &check_urls_are_valid(&vec![ + "example.com".to_string(), + "http://example.com".to_string(), + "https://example.com".to_string(), + "https://example.com/test?q=test2&q2=test3#test4".to_string(), + ]) + .unwrap(), + &vec![ + "example.com".to_string(), + "example.com/test?q=test2&q2=test3#test4".to_string() + ], ); - assert!(check_urls_are_valid(&vec![ - String::from("example.com"), - String::from("https://example.blog") - ]) - .is_ok()); - - assert!(check_urls_are_valid(&vec![String::from("https://example .com"),]).is_err()); + assert!(check_urls_are_valid(&vec!["https://example .com".to_string()]).is_err()); } } From 8e3ff0408e63d481dfa1626e20735ffe00ae9e8e Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 25 Apr 2024 04:26:17 -0400 Subject: [PATCH 3/4] Fixing extra modlog entries when post_id or comment_id is given. (#4664) - Previously when given a post_id, it didn't filter out any other modlog entries, such as community removals. This fixes that problem. - Context: https://github.com/LemmyNet/lemmy-ui/pull/2437 Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com> --- crates/db_views_moderator/src/admin_purge_comment_view.rs | 5 +++++ crates/db_views_moderator/src/admin_purge_community_view.rs | 5 +++++ crates/db_views_moderator/src/admin_purge_person_view.rs | 5 +++++ crates/db_views_moderator/src/admin_purge_post_view.rs | 5 +++++ crates/db_views_moderator/src/mod_add_community_view.rs | 5 +++++ crates/db_views_moderator/src/mod_add_view.rs | 5 +++++ crates/db_views_moderator/src/mod_ban_from_community_view.rs | 5 +++++ crates/db_views_moderator/src/mod_ban_view.rs | 5 +++++ crates/db_views_moderator/src/mod_feature_post_view.rs | 5 +++++ crates/db_views_moderator/src/mod_hide_community_view.rs | 5 +++++ crates/db_views_moderator/src/mod_lock_post_view.rs | 5 +++++ crates/db_views_moderator/src/mod_remove_comment_view.rs | 5 +++++ crates/db_views_moderator/src/mod_remove_community_view.rs | 5 +++++ crates/db_views_moderator/src/mod_remove_post_view.rs | 5 +++++ crates/db_views_moderator/src/mod_transfer_community_view.rs | 5 +++++ 15 files changed, 75 insertions(+) diff --git a/crates/db_views_moderator/src/admin_purge_comment_view.rs b/crates/db_views_moderator/src/admin_purge_comment_view.rs index f62fe0f22..4c650b6fa 100644 --- a/crates/db_views_moderator/src/admin_purge_comment_view.rs +++ b/crates/db_views_moderator/src/admin_purge_comment_view.rs @@ -40,6 +40,11 @@ impl AdminPurgeCommentView { query = query.filter(admin_purge_comment::admin_person_id.eq(admin_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/admin_purge_community_view.rs b/crates/db_views_moderator/src/admin_purge_community_view.rs index 23967ee3b..5eadb8985 100644 --- a/crates/db_views_moderator/src/admin_purge_community_view.rs +++ b/crates/db_views_moderator/src/admin_purge_community_view.rs @@ -38,6 +38,11 @@ impl AdminPurgeCommunityView { query = query.filter(admin_purge_community::admin_person_id.eq(admin_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/admin_purge_person_view.rs b/crates/db_views_moderator/src/admin_purge_person_view.rs index 097785d25..b6dd834c5 100644 --- a/crates/db_views_moderator/src/admin_purge_person_view.rs +++ b/crates/db_views_moderator/src/admin_purge_person_view.rs @@ -38,6 +38,11 @@ impl AdminPurgePersonView { query = query.filter(admin_purge_person::admin_person_id.eq(admin_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/admin_purge_post_view.rs b/crates/db_views_moderator/src/admin_purge_post_view.rs index 8f5eb3a14..b77493c25 100644 --- a/crates/db_views_moderator/src/admin_purge_post_view.rs +++ b/crates/db_views_moderator/src/admin_purge_post_view.rs @@ -40,6 +40,11 @@ impl AdminPurgePostView { query = query.filter(admin_purge_post::admin_person_id.eq(admin_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_add_community_view.rs b/crates/db_views_moderator/src/mod_add_community_view.rs index f96a9b80b..1068aba75 100644 --- a/crates/db_views_moderator/src/mod_add_community_view.rs +++ b/crates/db_views_moderator/src/mod_add_community_view.rs @@ -52,6 +52,11 @@ impl ModAddCommunityView { query = query.filter(person_alias_1.field(person::id).eq(other_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_add_view.rs b/crates/db_views_moderator/src/mod_add_view.rs index 28fb0a2b6..c5612c4ad 100644 --- a/crates/db_views_moderator/src/mod_add_view.rs +++ b/crates/db_views_moderator/src/mod_add_view.rs @@ -44,6 +44,11 @@ impl ModAddView { query = query.filter(person_alias_1.field(person::id).eq(other_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_ban_from_community_view.rs b/crates/db_views_moderator/src/mod_ban_from_community_view.rs index 02f18099c..d2d6038f3 100644 --- a/crates/db_views_moderator/src/mod_ban_from_community_view.rs +++ b/crates/db_views_moderator/src/mod_ban_from_community_view.rs @@ -54,6 +54,11 @@ impl ModBanFromCommunityView { query = query.filter(mod_ban_from_community::other_person_id.eq(other_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_ban_view.rs b/crates/db_views_moderator/src/mod_ban_view.rs index 94ac360db..ca0723e83 100644 --- a/crates/db_views_moderator/src/mod_ban_view.rs +++ b/crates/db_views_moderator/src/mod_ban_view.rs @@ -44,6 +44,11 @@ impl ModBanView { query = query.filter(person_alias_1.field(person::id).eq(other_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_feature_post_view.rs b/crates/db_views_moderator/src/mod_feature_post_view.rs index 1bf83688d..4c0fdb4f7 100644 --- a/crates/db_views_moderator/src/mod_feature_post_view.rs +++ b/crates/db_views_moderator/src/mod_feature_post_view.rs @@ -55,6 +55,11 @@ impl ModFeaturePostView { query = query.filter(post::id.eq(post_id)); } + // If a comment ID is given, then don't find any results + if params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_hide_community_view.rs b/crates/db_views_moderator/src/mod_hide_community_view.rs index 36b549814..3c8a7e627 100644 --- a/crates/db_views_moderator/src/mod_hide_community_view.rs +++ b/crates/db_views_moderator/src/mod_hide_community_view.rs @@ -45,6 +45,11 @@ impl ModHideCommunityView { query = query.filter(mod_hide_community::mod_person_id.eq(admin_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_lock_post_view.rs b/crates/db_views_moderator/src/mod_lock_post_view.rs index 6f7e83ec7..5a6c753d9 100644 --- a/crates/db_views_moderator/src/mod_lock_post_view.rs +++ b/crates/db_views_moderator/src/mod_lock_post_view.rs @@ -56,6 +56,11 @@ impl ModLockPostView { query = query.filter(post::id.eq(post_id)); } + // If a comment ID is given, then don't find any results + if params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_remove_comment_view.rs b/crates/db_views_moderator/src/mod_remove_comment_view.rs index e7d695a5c..cf0ed325c 100644 --- a/crates/db_views_moderator/src/mod_remove_comment_view.rs +++ b/crates/db_views_moderator/src/mod_remove_comment_view.rs @@ -58,6 +58,11 @@ impl ModRemoveCommentView { query = query.filter(comment::id.eq(comment_id)); } + // If a post ID is given, then don't find any results + if params.post_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_remove_community_view.rs b/crates/db_views_moderator/src/mod_remove_community_view.rs index 2bc92acc8..ac620ebdb 100644 --- a/crates/db_views_moderator/src/mod_remove_community_view.rs +++ b/crates/db_views_moderator/src/mod_remove_community_view.rs @@ -39,6 +39,11 @@ impl ModRemoveCommunityView { query = query.filter(mod_remove_community::mod_person_id.eq(mod_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_remove_post_view.rs b/crates/db_views_moderator/src/mod_remove_post_view.rs index fb0b3e6c1..98504a8e7 100644 --- a/crates/db_views_moderator/src/mod_remove_post_view.rs +++ b/crates/db_views_moderator/src/mod_remove_post_view.rs @@ -56,6 +56,11 @@ impl ModRemovePostView { query = query.filter(post::id.eq(post_id)); } + // If a comment ID is given, then don't find any results + if params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query diff --git a/crates/db_views_moderator/src/mod_transfer_community_view.rs b/crates/db_views_moderator/src/mod_transfer_community_view.rs index 3d48b0f67..6d62d347a 100644 --- a/crates/db_views_moderator/src/mod_transfer_community_view.rs +++ b/crates/db_views_moderator/src/mod_transfer_community_view.rs @@ -54,6 +54,11 @@ impl ModTransferCommunityView { query = query.filter(person_alias_1.field(person::id).eq(other_person_id)); }; + // If a post or comment ID is given, then don't find any results + if params.post_id.is_some() || params.comment_id.is_some() { + return Ok(vec![]); + } + let (limit, offset) = limit_and_offset(params.page, params.limit)?; query From cf426493e1f4fd3364cacf65e3eec32b61c1e136 Mon Sep 17 00:00:00 2001 From: Nutomic Date: Thu, 25 Apr 2024 17:47:38 +0200 Subject: [PATCH 4/4] Fix community add mod check (fixes #4624) (#4667) --- Cargo.lock | 2 +- crates/api/src/community/add_mod.rs | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61fcb5cd4..a6f217bfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2588,7 +2588,7 @@ dependencies = [ "actix-web", "actix-web-httpauth", "anyhow", - "base64 0.21.7", + "base64 0.22.0", "bcrypt", "captcha", "chrono", diff --git a/crates/api/src/community/add_mod.rs b/crates/api/src/community/add_mod.rs index df6b3fbe4..5245f592e 100644 --- a/crates/api/src/community/add_mod.rs +++ b/crates/api/src/community/add_mod.rs @@ -36,8 +36,20 @@ pub async fn add_mod_to_community( let community = Community::read(&mut context.pool(), community_id) .await? .ok_or(LemmyErrorType::CouldntFindCommunity)?; + + // If user is admin and community is remote, explicitly check that he is a + // moderator. This is necessary because otherwise the action would be rejected + // by the community's home instance. if local_user_view.local_user.admin && !community.local { - Err(LemmyErrorType::NotAModerator)? + let is_mod = CommunityModeratorView::is_community_moderator( + &mut context.pool(), + community.id, + local_user_view.person.id, + ) + .await?; + if !is_mod { + Err(LemmyErrorType::NotAModerator)? + } } // Update in local database