]> Untitled Git - lemmy.git/commitdiff
Moving settings and secrets to context.
authorDessalines <tyhou13@gmx.com>
Wed, 22 Sep 2021 15:57:09 +0000 (11:57 -0400)
committerFelix Ableitner <me@nutomic.com>
Mon, 27 Sep 2021 09:25:26 +0000 (11:25 +0200)
88 files changed:
crates/api/src/comment.rs
crates/api/src/comment_report.rs
crates/api/src/community.rs
crates/api/src/lib.rs
crates/api/src/local_user.rs
crates/api/src/post.rs
crates/api/src/post_report.rs
crates/api/src/private_message.rs
crates/api/src/site.rs
crates/api/src/websocket.rs
crates/api_common/src/lib.rs
crates/api_crud/src/comment/create.rs
crates/api_crud/src/comment/delete.rs
crates/api_crud/src/comment/read.rs
crates/api_crud/src/comment/update.rs
crates/api_crud/src/community/create.rs
crates/api_crud/src/community/delete.rs
crates/api_crud/src/community/read.rs
crates/api_crud/src/community/update.rs
crates/api_crud/src/post/create.rs
crates/api_crud/src/post/delete.rs
crates/api_crud/src/post/read.rs
crates/api_crud/src/post/update.rs
crates/api_crud/src/private_message/create.rs
crates/api_crud/src/private_message/delete.rs
crates/api_crud/src/private_message/read.rs
crates/api_crud/src/private_message/update.rs
crates/api_crud/src/site/create.rs
crates/api_crud/src/site/read.rs
crates/api_crud/src/site/update.rs
crates/api_crud/src/user/create.rs
crates/api_crud/src/user/delete.rs
crates/api_crud/src/user/read.rs
crates/apub/src/activities/comment/create_or_update.rs
crates/apub/src/activities/comment/mod.rs
crates/apub/src/activities/community/add_mod.rs
crates/apub/src/activities/community/announce.rs
crates/apub/src/activities/community/block_user.rs
crates/apub/src/activities/community/mod.rs
crates/apub/src/activities/community/remove_mod.rs
crates/apub/src/activities/community/undo_block_user.rs
crates/apub/src/activities/community/update.rs
crates/apub/src/activities/deletion/delete.rs
crates/apub/src/activities/deletion/undo_delete.rs
crates/apub/src/activities/following/accept.rs
crates/apub/src/activities/following/follow.rs
crates/apub/src/activities/following/undo.rs
crates/apub/src/activities/mod.rs
crates/apub/src/activities/post/create_or_update.rs
crates/apub/src/activities/private_message/create_or_update.rs
crates/apub/src/activities/private_message/delete.rs
crates/apub/src/activities/private_message/undo_delete.rs
crates/apub/src/activities/send/community.rs
crates/apub/src/activities/undo_remove.rs
crates/apub/src/activities/voting/undo_vote.rs
crates/apub/src/activities/voting/vote.rs
crates/apub/src/activity_queue.rs
crates/apub/src/fetcher/community.rs
crates/apub/src/fetcher/fetch.rs
crates/apub/src/fetcher/objects.rs [new file with mode: 0644]
crates/apub/src/fetcher/person.rs [new file with mode: 0644]
crates/apub/src/fetcher/search.rs
crates/apub/src/http/mod.rs
crates/apub/src/http/routes.rs
crates/apub/src/lib.rs
crates/apub/src/objects/comment.rs
crates/apub/src/objects/community.rs
crates/apub/src/objects/person.rs
crates/apub/src/objects/post.rs
crates/apub_lib/src/webfinger.rs
crates/db_queries/src/source/secret.rs
crates/routes/src/feeds.rs
crates/routes/src/images.rs
crates/routes/src/nodeinfo.rs
crates/routes/src/webfinger.rs
crates/utils/src/claims.rs
crates/utils/src/email.rs
crates/utils/src/lib.rs
crates/utils/src/rate_limit/mod.rs
crates/utils/src/request.rs
crates/utils/src/settings/mod.rs
crates/utils/src/settings/structs.rs
crates/utils/src/test.rs
crates/utils/src/utils.rs
crates/websocket/src/chat_server.rs
crates/websocket/src/lib.rs
src/code_migrations.rs
src/main.rs

index 0af3324fae0b082159496a614a384ff858081944..1d1d3088f087b01b577f16c6b0a8d9a07ccd5836 100644 (file)
@@ -32,7 +32,8 @@ impl Perform for MarkCommentAsRead {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<CommentResponse, LemmyError> {
     let data: &MarkCommentAsRead = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let comment_id = data.comment_id;
     let orig_comment = blocking(context.pool(), move |conn| {
@@ -88,7 +89,8 @@ impl Perform for SaveComment {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<CommentResponse, LemmyError> {
     let data: &SaveComment = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let comment_saved_form = CommentSavedForm {
       comment_id: data.comment_id,
@@ -132,7 +134,8 @@ impl Perform for CreateCommentLike {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CommentResponse, LemmyError> {
     let data: &CreateCommentLike = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let mut recipient_ids = Vec::<LocalUserId>::new();
 
index 83aebfc526f59638ce770ab58924492f09d94e0a..6d2e2280d456edd473d466ce69695d616ecfa9bc 100644 (file)
@@ -32,7 +32,8 @@ impl Perform for CreateCommentReport {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CreateCommentReportResponse, LemmyError> {
     let data: &CreateCommentReport = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // check size of report and check for whitespace
     let reason = data.reason.trim();
@@ -96,7 +97,8 @@ impl Perform for ResolveCommentReport {
     websocket_id: Option<ConnectionId>,
   ) -> Result<ResolveCommentReportResponse, LemmyError> {
     let data: &ResolveCommentReport = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let report_id = data.report_id;
     let report = blocking(context.pool(), move |conn| {
@@ -149,7 +151,8 @@ impl Perform for ListCommentReports {
     websocket_id: Option<ConnectionId>,
   ) -> Result<ListCommentReportsResponse, LemmyError> {
     let data: &ListCommentReports = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let person_id = local_user_view.person.id;
     let community_id = data.community;
index d68d27c2f7a2234aa872cdd50106509961b8cdc4..28a79c701f8b8ed650262c671d3d7ef66168dab4 100644 (file)
@@ -53,7 +53,8 @@ impl Perform for FollowCommunity {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<CommunityResponse, LemmyError> {
     let data: &FollowCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let community_id = data.community_id;
     let community = blocking(context.pool(), move |conn| {
@@ -121,7 +122,8 @@ impl Perform for BlockCommunity {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<BlockCommunityResponse, LemmyError> {
     let data: &BlockCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let community_id = data.community_id;
     let person_id = local_user_view.person.id;
@@ -181,7 +183,8 @@ impl Perform for BanFromCommunity {
     websocket_id: Option<ConnectionId>,
   ) -> Result<BanFromCommunityResponse, LemmyError> {
     let data: &BanFromCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let community_id = data.community_id;
     let banned_person_id = data.person_id;
@@ -314,7 +317,8 @@ impl Perform for AddModToCommunity {
     websocket_id: Option<ConnectionId>,
   ) -> Result<AddModToCommunityResponse, LemmyError> {
     let data: &AddModToCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let community_id = data.community_id;
 
@@ -397,7 +401,8 @@ impl Perform for TransferCommunity {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetCommunityResponse, LemmyError> {
     let data: &TransferCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let site_creator_id = blocking(context.pool(), move |conn| {
       Site::read(conn, 1).map(|s| s.creator_id)
index 1146975f0d9c3f6f11936a4bd00d3724e4ba936d..bfaceeb02ba6ac2f0450d652d67a2d771c52b07f 100644 (file)
@@ -190,7 +190,7 @@ mod tests {
   use lemmy_api_common::check_validator_time;
   use lemmy_db_queries::{
     establish_unpooled_connection,
-    source::{local_user::LocalUser_, secret::SecretSingleton},
+    source::{local_user::LocalUser_, secret::Secret_},
     Crud,
   };
   use lemmy_db_schema::source::{
@@ -198,11 +198,13 @@ mod tests {
     person::{Person, PersonForm},
     secret::Secret,
   };
-  use lemmy_utils::claims::Claims;
+  use lemmy_utils::{claims::Claims, settings::structs::Settings};
 
   #[test]
   fn test_should_not_validate_user_token_after_password_change() {
     let conn = establish_unpooled_connection();
+    let secret = Secret::init(&conn).unwrap();
+    let settings = Settings::init().unwrap();
 
     let new_person = PersonForm {
       name: "Gerry9812".into(),
@@ -219,9 +221,13 @@ mod tests {
 
     let inserted_local_user = LocalUser::create(&conn, &local_user_form).unwrap();
 
-    let jwt_secret = Secret::get().jwt_secret;
-    let jwt = Claims::jwt(inserted_local_user.id.0, &jwt_secret).unwrap();
-    let claims = Claims::decode(&jwt, jwt_secret.as_ref()).unwrap().claims;
+    let jwt = Claims::jwt(
+      inserted_local_user.id.0,
+      &secret.jwt_secret,
+      &settings.hostname,
+    )
+    .unwrap();
+    let claims = Claims::decode(&jwt, &secret.jwt_secret).unwrap().claims;
     let check = check_validator_time(&inserted_local_user.validator_time, &claims);
     assert!(check.is_ok());
 
index df03e30205d967283e138e60170a78feaee2e77e..c69ea48d3ee77710ca924639040fdb74e22611d2 100644 (file)
@@ -25,7 +25,6 @@ use lemmy_db_queries::{
     person_mention::PersonMention_,
     post::Post_,
     private_message::PrivateMessage_,
-    secret::SecretSingleton,
   },
   Blockable,
   Crud,
@@ -44,7 +43,6 @@ use lemmy_db_schema::{
     person_mention::*,
     post::Post,
     private_message::PrivateMessage,
-    secret::Secret,
     site::*,
   },
 };
@@ -63,7 +61,6 @@ use lemmy_utils::{
   claims::Claims,
   email::send_email,
   location_info,
-  settings::structs::Settings,
   utils::{generate_random_string, is_valid_display_name, is_valid_matrix_id, naive_from_unix},
   ApiError,
   ConnectionId,
@@ -105,9 +102,12 @@ impl Perform for Login {
     }
 
     // Return the jwt
-    let jwt_secret = Secret::get().jwt_secret;
     Ok(LoginResponse {
-      jwt: Claims::jwt(local_user_view.local_user.id.0, &jwt_secret)?,
+      jwt: Claims::jwt(
+        local_user_view.local_user.id.0,
+        &context.secret().jwt_secret,
+        &context.settings().hostname,
+      )?,
     })
   }
 }
@@ -121,7 +121,7 @@ impl Perform for GetCaptcha {
     context: &Data<LemmyContext>,
     _websocket_id: Option<ConnectionId>,
   ) -> Result<Self::Response, LemmyError> {
-    let captcha_settings = Settings::get().captcha;
+    let captcha_settings = context.settings().captcha;
 
     if !captcha_settings.enabled {
       return Ok(GetCaptchaResponse { ok: None });
@@ -167,7 +167,8 @@ impl Perform for SaveUserSettings {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<LoginResponse, LemmyError> {
     let data: &SaveUserSettings = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let avatar = diesel_option_overwrite_to_url(&data.avatar)?;
     let banner = diesel_option_overwrite_to_url(&data.banner)?;
@@ -184,7 +185,10 @@ impl Perform for SaveUserSettings {
     }
 
     if let Some(Some(display_name)) = &display_name {
-      if !is_valid_display_name(display_name.trim()) {
+      if !is_valid_display_name(
+        display_name.trim(),
+        context.settings().actor_name_max_length,
+      ) {
         return Err(ApiError::err("invalid_username").into());
       }
     }
@@ -271,9 +275,12 @@ impl Perform for SaveUserSettings {
     };
 
     // Return the jwt
-    let jwt_secret = Secret::get().jwt_secret;
     Ok(LoginResponse {
-      jwt: Claims::jwt(updated_local_user.id.0, &jwt_secret)?,
+      jwt: Claims::jwt(
+        updated_local_user.id.0,
+        &context.secret().jwt_secret,
+        &context.settings().hostname,
+      )?,
     })
   }
 }
@@ -288,7 +295,8 @@ impl Perform for ChangePassword {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<LoginResponse, LemmyError> {
     let data: &ChangePassword = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     password_length_check(&data.new_password)?;
 
@@ -315,9 +323,12 @@ impl Perform for ChangePassword {
     .await??;
 
     // Return the jwt
-    let jwt_secret = Secret::get().jwt_secret;
     Ok(LoginResponse {
-      jwt: Claims::jwt(updated_local_user.id.0, &jwt_secret)?,
+      jwt: Claims::jwt(
+        updated_local_user.id.0,
+        &context.secret().jwt_secret,
+        &context.settings().hostname,
+      )?,
     })
   }
 }
@@ -332,7 +343,8 @@ impl Perform for AddAdmin {
     websocket_id: Option<ConnectionId>,
   ) -> Result<AddAdminResponse, LemmyError> {
     let data: &AddAdmin = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Make sure user is an admin
     is_admin(&local_user_view)?;
@@ -394,7 +406,8 @@ impl Perform for BanPerson {
     websocket_id: Option<ConnectionId>,
   ) -> Result<BanPersonResponse, LemmyError> {
     let data: &BanPerson = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Make sure user is an admin
     is_admin(&local_user_view)?;
@@ -486,7 +499,8 @@ impl Perform for BlockPerson {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<BlockPersonResponse, LemmyError> {
     let data: &BlockPerson = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let target_id = data.person_id;
     let person_id = local_user_view.person.id;
@@ -539,7 +553,8 @@ impl Perform for GetReplies {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetRepliesResponse, LemmyError> {
     let data: &GetReplies = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
 
@@ -576,7 +591,8 @@ impl Perform for GetPersonMentions {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetPersonMentionsResponse, LemmyError> {
     let data: &GetPersonMentions = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
 
@@ -610,7 +626,8 @@ impl Perform for MarkPersonMentionAsRead {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<PersonMentionResponse, LemmyError> {
     let data: &MarkPersonMentionAsRead = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let person_mention_id = data.person_mention_id;
     let read_person_mention = blocking(context.pool(), move |conn| {
@@ -653,7 +670,8 @@ impl Perform for MarkAllAsRead {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetRepliesResponse, LemmyError> {
     let data: &MarkAllAsRead = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let person_id = local_user_view.person.id;
     let replies = blocking(context.pool(), move |conn| {
@@ -732,10 +750,16 @@ impl Perform for PasswordReset {
     // TODO no i18n support here.
     let email = &local_user_view.local_user.email.expect("email");
     let subject = &format!("Password reset for {}", local_user_view.person.name);
-    let hostname = &Settings::get().get_protocol_and_hostname();
-    let html = &format!("<h1>Password Reset Request for {}</h1><br><a href={}/password_change/{}>Click here to reset your password</a>", local_user_view.person.name, hostname, &token);
-    send_email(subject, email, &local_user_view.person.name, html)
-      .map_err(|e| ApiError::err(&e))?;
+    let protocol_and_hostname = &context.settings().get_protocol_and_hostname();
+    let html = &format!("<h1>Password Reset Request for {}</h1><br><a href={}/password_change/{}>Click here to reset your password</a>", local_user_view.person.name, protocol_and_hostname, &token);
+    send_email(
+      subject,
+      email,
+      &local_user_view.person.name,
+      html,
+      &context.settings(),
+    )
+    .map_err(|e| ApiError::err(&e))?;
 
     Ok(PasswordResetResponse {})
   }
@@ -775,9 +799,12 @@ impl Perform for PasswordChange {
     .map_err(|_| ApiError::err("couldnt_update_user"))?;
 
     // Return the jwt
-    let jwt_secret = Secret::get().jwt_secret;
     Ok(LoginResponse {
-      jwt: Claims::jwt(updated_local_user.id.0, &jwt_secret)?,
+      jwt: Claims::jwt(
+        updated_local_user.id.0,
+        &context.secret().jwt_secret,
+        &context.settings().hostname,
+      )?,
     })
   }
 }
@@ -792,7 +819,8 @@ impl Perform for GetReportCount {
     websocket_id: Option<ConnectionId>,
   ) -> Result<GetReportCountResponse, LemmyError> {
     let data: &GetReportCount = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let person_id = local_user_view.person.id;
     let community_id = data.community;
index 71b200141b47b465f100e17f18433193f4570132..da828725dbe3e327ce07d2ab4ce129879d0bb670 100644 (file)
@@ -38,7 +38,8 @@ impl Perform for CreatePostLike {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PostResponse, LemmyError> {
     let data: &CreatePostLike = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Don't do a downvote if site has downvotes disabled
     check_downvotes_enabled(data.score, context.pool()).await?;
@@ -120,7 +121,8 @@ impl Perform for LockPost {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PostResponse, LemmyError> {
     let data: &LockPost = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let post_id = data.post_id;
     let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
@@ -186,7 +188,8 @@ impl Perform for StickyPost {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PostResponse, LemmyError> {
     let data: &StickyPost = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let post_id = data.post_id;
     let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
@@ -256,7 +259,8 @@ impl Perform for SavePost {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<PostResponse, LemmyError> {
     let data: &SavePost = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let post_saved_form = PostSavedForm {
       post_id: data.post_id,
index e718b775a48cced4f3eb4851928ba4e546655e1c..e08a64b3f717087a94d3952fa8a33c5bece06b93 100644 (file)
@@ -39,7 +39,8 @@ impl Perform for CreatePostReport {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CreatePostReportResponse, LemmyError> {
     let data: &CreatePostReport = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // check size of report and check for whitespace
     let reason = data.reason.trim();
@@ -105,7 +106,8 @@ impl Perform for ResolvePostReport {
     websocket_id: Option<ConnectionId>,
   ) -> Result<ResolvePostReportResponse, LemmyError> {
     let data: &ResolvePostReport = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let report_id = data.report_id;
     let report = blocking(context.pool(), move |conn| {
@@ -157,7 +159,8 @@ impl Perform for ListPostReports {
     websocket_id: Option<ConnectionId>,
   ) -> Result<ListPostReportsResponse, LemmyError> {
     let data: &ListPostReports = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let person_id = local_user_view.person.id;
     let community_id = data.community;
index f23bf71cdc99fa400c411e1fcf3b6ede51098548..31f6901dc8ef46ad74cc22ba12f2f8360b1236be 100644 (file)
@@ -20,7 +20,8 @@ impl Perform for MarkPrivateMessageAsRead {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PrivateMessageResponse, LemmyError> {
     let data: &MarkPrivateMessageAsRead = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Checking permissions
     let private_message_id = data.private_message_id;
index 82c94cbbb13f5bfb6f0c569b7fc5b292155e959b..01f7b45f19ce787845a4d888e3e82a73976b75ec 100644 (file)
@@ -151,7 +151,8 @@ impl Perform for Search {
   ) -> Result<SearchResponse, LemmyError> {
     let data: &Search = self;
 
-    let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
 
     let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw);
     let show_bot_accounts = local_user_view
@@ -180,7 +181,7 @@ impl Perform for Search {
     let community_actor_id = data
       .community_name
       .as_ref()
-      .map(|t| build_actor_id_from_shortname(EndpointType::Community, t).ok())
+      .map(|t| build_actor_id_from_shortname(EndpointType::Community, t, &context.settings()).ok())
       .unwrap_or(None);
     let creator_id = data.creator_id;
     match search_type {
@@ -384,7 +385,8 @@ impl Perform for ResolveObject {
     context: &Data<LemmyContext>,
     _websocket_id: Option<ConnectionId>,
   ) -> Result<ResolveObjectResponse, LemmyError> {
-    let local_user_view = get_local_user_view_from_jwt_opt(&self.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&self.auth, context.pool(), context.secret()).await?;
     let res = search_by_apub_id(&self.q, context)
       .await
       .map_err(|_| ApiError::err("couldnt_find_object"))?;
@@ -443,7 +445,8 @@ impl Perform for TransferSite {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetSiteResponse, LemmyError> {
     let data: &TransferSite = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     is_admin(&local_user_view)?;
 
@@ -480,7 +483,12 @@ impl Perform for TransferSite {
     admins.insert(0, creator_person);
 
     let banned = blocking(context.pool(), move |conn| PersonViewSafe::banned(conn)).await??;
-    let federated_instances = build_federated_instances(context.pool()).await?;
+    let federated_instances = build_federated_instances(
+      context.pool(),
+      &context.settings().federation,
+      &context.settings().hostname,
+    )
+    .await?;
 
     Ok(GetSiteResponse {
       site_view: Some(site_view),
@@ -504,7 +512,8 @@ impl Perform for GetSiteConfig {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetSiteConfigResponse, LemmyError> {
     let data: &GetSiteConfig = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Only let admins read this
     is_admin(&local_user_view)?;
@@ -525,7 +534,8 @@ impl Perform for SaveSiteConfig {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetSiteConfigResponse, LemmyError> {
     let data: &SaveSiteConfig = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Only let admins read this
     is_admin(&local_user_view)?;
index e69ffdd2421ce4c73d6765bf9c18620ce6e28c6e..fa03e4ecf4ed081695369337d87be6082170f301 100644 (file)
@@ -17,7 +17,8 @@ impl Perform for UserJoin {
     websocket_id: Option<ConnectionId>,
   ) -> Result<UserJoinResponse, LemmyError> {
     let data: &UserJoin = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     if let Some(ws_id) = websocket_id {
       context.chat_server().do_send(JoinUserRoom {
index 068bd253f5bc69b9de042f5a9e529017068c220f..c38d4e620d3141ded05f89243e61ed0c93970f31 100644 (file)
@@ -11,7 +11,6 @@ use lemmy_db_queries::{
   source::{
     community::{CommunityModerator_, Community_},
     person_block::PersonBlock_,
-    secret::SecretSingleton,
     site::Site_,
   },
   Crud,
@@ -42,7 +41,7 @@ use lemmy_db_views_actor::{
 use lemmy_utils::{
   claims::Claims,
   email::send_email,
-  settings::structs::Settings,
+  settings::structs::{FederationConfig, Settings},
   utils::MentionData,
   ApiError,
   LemmyError,
@@ -73,9 +72,19 @@ pub async fn send_local_notifs(
   post: Post,
   pool: &DbPool,
   do_send_email: bool,
+  settings: &Settings,
 ) -> Result<Vec<LocalUserId>, LemmyError> {
+  let settings = settings.to_owned();
   let ids = blocking(pool, move |conn| {
-    do_send_local_notifs(conn, &mentions, &comment, &person, &post, do_send_email)
+    do_send_local_notifs(
+      conn,
+      &mentions,
+      &comment,
+      &person,
+      &post,
+      do_send_email,
+      &settings,
+    )
   })
   .await?;
 
@@ -89,13 +98,14 @@ fn do_send_local_notifs(
   person: &Person,
   post: &Post,
   do_send_email: bool,
+  settings: &Settings,
 ) -> Vec<LocalUserId> {
   let mut recipient_ids = Vec::new();
 
   // Send the local mentions
   for mention in mentions
     .iter()
-    .filter(|m| m.is_local() && m.name.ne(&person.name))
+    .filter(|m| m.is_local(&settings.hostname) && m.name.ne(&person.name))
     .collect::<Vec<&MentionData>>()
   {
     if let Ok(mention_user_view) = LocalUserView::read_from_name(conn, &mention.name) {
@@ -121,6 +131,7 @@ fn do_send_local_notifs(
           "Mentioned by",
           "Person Mention",
           &comment.content,
+          settings,
         )
       }
     }
@@ -143,6 +154,7 @@ fn do_send_local_notifs(
                 "Reply from",
                 "Comment Reply",
                 &comment.content,
+                settings,
               )
             }
           }
@@ -161,6 +173,7 @@ fn do_send_local_notifs(
               "Reply from",
               "Post Reply",
               &comment.content,
+              settings,
             )
           }
         }
@@ -175,6 +188,7 @@ pub fn send_email_to_user(
   subject_text: &str,
   body_text: &str,
   comment_content: &str,
+  settings: &Settings,
 ) {
   if local_user_view.person.banned || !local_user_view.local_user.send_notifications_to_email {
     return;
@@ -183,18 +197,22 @@ pub fn send_email_to_user(
   if let Some(user_email) = &local_user_view.local_user.email {
     let subject = &format!(
       "{} - {} {}",
-      subject_text,
-      Settings::get().hostname,
-      local_user_view.person.name,
+      subject_text, settings.hostname, local_user_view.person.name,
     );
     let html = &format!(
       "<h1>{}</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
       body_text,
       local_user_view.person.name,
       comment_content,
-      Settings::get().get_protocol_and_hostname()
+      settings.get_protocol_and_hostname()
     );
-    match send_email(subject, user_email, &local_user_view.person.name, html) {
+    match send_email(
+      subject,
+      user_email,
+      &local_user_view.person.name,
+      html,
+      settings,
+    ) {
       Ok(_o) => _o,
       Err(e) => error!("{}", e),
     };
@@ -246,9 +264,9 @@ pub async fn mark_post_as_read(
 pub async fn get_local_user_view_from_jwt(
   jwt: &str,
   pool: &DbPool,
+  secret: &Secret,
 ) -> Result<LocalUserView, LemmyError> {
-  let jwt_secret = Secret::get().jwt_secret;
-  let claims = Claims::decode(jwt, &jwt_secret)
+  let claims = Claims::decode(jwt, &secret.jwt_secret)
     .map_err(|_| ApiError::err("not_logged_in"))?
     .claims;
   let local_user_id = LocalUserId(claims.sub);
@@ -285,9 +303,10 @@ pub fn check_validator_time(
 pub async fn get_local_user_view_from_jwt_opt(
   jwt: &Option<String>,
   pool: &DbPool,
+  secret: &Secret,
 ) -> Result<Option<LocalUserView>, LemmyError> {
   match jwt {
-    Some(jwt) => Ok(Some(get_local_user_view_from_jwt(jwt, pool).await?)),
+    Some(jwt) => Ok(Some(get_local_user_view_from_jwt(jwt, pool, secret).await?)),
     None => Ok(None),
   }
 }
@@ -295,9 +314,9 @@ pub async fn get_local_user_view_from_jwt_opt(
 pub async fn get_local_user_settings_view_from_jwt(
   jwt: &str,
   pool: &DbPool,
+  secret: &Secret,
 ) -> Result<LocalUserSettingsView, LemmyError> {
-  let jwt_secret = Secret::get().jwt_secret;
-  let claims = Claims::decode(jwt, &jwt_secret)
+  let claims = Claims::decode(jwt, &secret.jwt_secret)
     .map_err(|_| ApiError::err("not_logged_in"))?
     .claims;
   let local_user_id = LocalUserId(claims.sub);
@@ -318,10 +337,11 @@ pub async fn get_local_user_settings_view_from_jwt(
 pub async fn get_local_user_settings_view_from_jwt_opt(
   jwt: &Option<String>,
   pool: &DbPool,
+  secret: &Secret,
 ) -> Result<Option<LocalUserSettingsView>, LemmyError> {
   match jwt {
     Some(jwt) => Ok(Some(
-      get_local_user_settings_view_from_jwt(jwt, pool).await?,
+      get_local_user_settings_view_from_jwt(jwt, pool, secret).await?,
     )),
     None => Ok(None),
   }
@@ -391,15 +411,18 @@ pub async fn collect_moderated_communities(
 
 pub async fn build_federated_instances(
   pool: &DbPool,
+  federation_config: &FederationConfig,
+  hostname: &str,
 ) -> Result<Option<FederatedInstances>, LemmyError> {
-  if Settings::get().federation.enabled {
+  let federation = federation_config.to_owned();
+  if federation.enabled {
     let distinct_communities = blocking(pool, move |conn| {
       Community::distinct_federated_communities(conn)
     })
     .await??;
 
-    let allowed = Settings::get().federation.allowed_instances;
-    let blocked = Settings::get().federation.blocked_instances;
+    let allowed = federation.allowed_instances;
+    let blocked = federation.blocked_instances;
 
     let mut linked = distinct_communities
       .iter()
@@ -411,7 +434,7 @@ pub async fn build_federated_instances(
     }
 
     if let Some(blocked) = blocked.as_ref() {
-      linked.retain(|a| !blocked.contains(a) && !a.eq(&Settings::get().hostname));
+      linked.retain(|a| !blocked.contains(a) && !a.eq(hostname));
     }
 
     // Sort and remove dupes
index 7669870039affd31db74dec10d43b182a67e6da4..fb175179a6e0a2ca485b6918ad080bbcdbcab24d 100644 (file)
@@ -40,9 +40,11 @@ impl PerformCrud for CreateComment {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CommentResponse, LemmyError> {
     let data: &CreateComment = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
-    let content_slurs_removed = remove_slurs(&data.content.to_owned());
+    let content_slurs_removed =
+      remove_slurs(&data.content.to_owned(), &context.settings().slur_regex());
 
     // Check for a community ban
     let post_id = data.post_id;
@@ -91,10 +93,15 @@ impl PerformCrud for CreateComment {
 
     // Necessary to update the ap_id
     let inserted_comment_id = inserted_comment.id;
+    let protocol_and_hostname = context.settings().get_protocol_and_hostname();
+
     let updated_comment: Comment =
       blocking(context.pool(), move |conn| -> Result<Comment, LemmyError> {
-        let apub_id =
-          generate_apub_endpoint(EndpointType::Comment, &inserted_comment_id.to_string())?;
+        let apub_id = generate_apub_endpoint(
+          EndpointType::Comment,
+          &inserted_comment_id.to_string(),
+          &protocol_and_hostname,
+        )?;
         Ok(Comment::update_ap_id(conn, inserted_comment_id, apub_id)?)
       })
       .await?
@@ -118,6 +125,7 @@ impl PerformCrud for CreateComment {
       post,
       context.pool(),
       true,
+      &context.settings(),
     )
     .await?;
 
index 85917846e40f6c3192979c9e4eb6631135a6eb41..0b44f4ebbd5e268bb91b5802cfc1860c2a5629d9 100644 (file)
@@ -25,7 +25,8 @@ impl PerformCrud for DeleteComment {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CommentResponse, LemmyError> {
     let data: &DeleteComment = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let comment_id = data.comment_id;
     let orig_comment = blocking(context.pool(), move |conn| {
@@ -76,6 +77,7 @@ impl PerformCrud for DeleteComment {
       post,
       context.pool(),
       false,
+      &context.settings(),
     )
     .await?;
 
@@ -102,7 +104,8 @@ impl PerformCrud for RemoveComment {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CommentResponse, LemmyError> {
     let data: &RemoveComment = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let comment_id = data.comment_id;
     let orig_comment = blocking(context.pool(), move |conn| {
@@ -169,6 +172,7 @@ impl PerformCrud for RemoveComment {
       post,
       context.pool(),
       false,
+      &context.settings(),
     )
     .await?;
 
index fc4bd1e35119233c09362648d246a8713f787239..8ee9eb62860737f7ee622261f802be9927ff41eb 100644 (file)
@@ -17,7 +17,8 @@ impl PerformCrud for GetComments {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetCommentsResponse, LemmyError> {
     let data: &GetComments = self;
-    let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
 
     let show_bot_accounts = local_user_view
       .as_ref()
@@ -31,7 +32,7 @@ impl PerformCrud for GetComments {
     let community_actor_id = data
       .community_name
       .as_ref()
-      .map(|t| build_actor_id_from_shortname(EndpointType::Community, t).ok())
+      .map(|t| build_actor_id_from_shortname(EndpointType::Community, t, &context.settings()).ok())
       .unwrap_or(None);
     let saved_only = data.saved_only;
     let page = data.page;
index 8a5e8f0ed93d0cbb8758a6439c7f74e642024b79..24e2ddbdd2ae0ae3ba64232027044b6e0a13f240 100644 (file)
@@ -32,7 +32,8 @@ impl PerformCrud for EditComment {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CommentResponse, LemmyError> {
     let data: &EditComment = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let comment_id = data.comment_id;
     let orig_comment = blocking(context.pool(), move |conn| {
@@ -54,7 +55,8 @@ impl PerformCrud for EditComment {
     }
 
     // Do the update
-    let content_slurs_removed = remove_slurs(&data.content.to_owned());
+    let content_slurs_removed =
+      remove_slurs(&data.content.to_owned(), &context.settings().slur_regex());
     let comment_id = data.comment_id;
     let updated_comment = blocking(context.pool(), move |conn| {
       Comment::update_content(conn, comment_id, &content_slurs_removed)
@@ -81,6 +83,7 @@ impl PerformCrud for EditComment {
       orig_comment.post,
       context.pool(),
       false,
+      &context.settings(),
     )
     .await?;
 
index ecaa9058dd88964ad4b312401cbc611bf82cb1ab..1cc40d85f32ea0c5ecacfe1698341b6d56b0f19e 100644 (file)
@@ -45,23 +45,28 @@ impl PerformCrud for CreateCommunity {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<CommunityResponse, LemmyError> {
     let data: &CreateCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let site = blocking(context.pool(), move |conn| Site::read(conn, 0)).await??;
     if site.community_creation_admin_only && is_admin(&local_user_view).is_err() {
       return Err(ApiError::err("only_admins_can_create_communities").into());
     }
 
-    check_slurs(&data.name)?;
-    check_slurs(&data.title)?;
-    check_slurs_opt(&data.description)?;
+    check_slurs(&data.name, &context.settings().slur_regex())?;
+    check_slurs(&data.title, &context.settings().slur_regex())?;
+    check_slurs_opt(&data.description, &context.settings().slur_regex())?;
 
-    if !is_valid_actor_name(&data.name) {
+    if !is_valid_actor_name(&data.name, context.settings().actor_name_max_length) {
       return Err(ApiError::err("invalid_community_name").into());
     }
 
     // Double check for duplicate community actor_ids
-    let community_actor_id = generate_apub_endpoint(EndpointType::Community, &data.name)?;
+    let community_actor_id = generate_apub_endpoint(
+      EndpointType::Community,
+      &data.name,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let actor_id_cloned = community_actor_id.to_owned();
     let community_dupe = blocking(context.pool(), move |conn| {
       Community::read_from_apub_id(conn, &actor_id_cloned)
index b957b7d6edc741a6e352ede399358593a9d05672..2d54ff52c6bc89f6a0f7bc937839a7190a45c796 100644 (file)
@@ -21,7 +21,8 @@ impl PerformCrud for DeleteCommunity {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CommunityResponse, LemmyError> {
     let data: &DeleteCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Fetch the community mods
     let community_id = data.community_id;
@@ -75,7 +76,8 @@ impl PerformCrud for RemoveCommunity {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CommunityResponse, LemmyError> {
     let data: &RemoveCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Verify its an admin (only an admin can remove a community)
     is_admin(&local_user_view)?;
index 94e4ce7f4bc54ac97c1868f6344514741d02331d..b29f5f0a01c6ab104483731bda6ab38ffc2aef41 100644 (file)
@@ -27,14 +27,16 @@ impl PerformCrud for GetCommunity {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetCommunityResponse, LemmyError> {
     let data: &GetCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
     let person_id = local_user_view.map(|u| u.person.id);
 
     let community_id = match data.id {
       Some(id) => id,
       None => {
         let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
-        let community_actor_id = build_actor_id_from_shortname(EndpointType::Community, &name)?;
+        let community_actor_id =
+          build_actor_id_from_shortname(EndpointType::Community, &name, &context.settings())?;
 
         blocking(context.pool(), move |conn| {
           Community::read_from_apub_id(conn, &community_actor_id)
@@ -89,7 +91,8 @@ impl PerformCrud for ListCommunities {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<ListCommunitiesResponse, LemmyError> {
     let data: &ListCommunities = self;
-    let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
 
     let person_id = local_user_view.to_owned().map(|l| l.person.id);
 
index 2196c57b77e51bf316b31cb8a4897496a5b71898..ef94ad595e4f197c43ac079a9fbdb10707cafbd3 100644 (file)
@@ -26,10 +26,11 @@ impl PerformCrud for EditCommunity {
     websocket_id: Option<ConnectionId>,
   ) -> Result<CommunityResponse, LemmyError> {
     let data: &EditCommunity = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
-    check_slurs_opt(&data.title)?;
-    check_slurs_opt(&data.description)?;
+    check_slurs_opt(&data.title, &context.settings().slur_regex())?;
+    check_slurs_opt(&data.description, &context.settings().slur_regex())?;
 
     // Verify its a mod (only mods can edit it)
     let community_id = data.community_id;
index e21c6f33d005f9efe761db13841e56c078a5e06c..11896875cb53dce83896303c3da5a6e465aeb59f 100644 (file)
@@ -38,10 +38,12 @@ impl PerformCrud for CreatePost {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PostResponse, LemmyError> {
     let data: &CreatePost = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
-    check_slurs(&data.name)?;
-    check_slurs_opt(&data.body)?;
+    let slur_regex = &context.settings().slur_regex();
+    check_slurs(&data.name, slur_regex)?;
+    check_slurs_opt(&data.body, slur_regex)?;
 
     if !is_valid_post_title(&data.name) {
       return Err(ApiError::err("invalid_post_title").into());
@@ -51,7 +53,8 @@ impl PerformCrud for CreatePost {
 
     // Fetch post links and pictrs cached image
     let data_url = data.url.as_ref();
-    let (metadata_res, pictrs_thumbnail) = fetch_site_data(context.client(), data_url).await;
+    let (metadata_res, pictrs_thumbnail) =
+      fetch_site_data(context.client(), &context.settings(), data_url).await;
     let (embed_title, embed_description, embed_html) = metadata_res
       .map(|u| (u.title, u.description, u.html))
       .unwrap_or((None, None, None));
@@ -85,8 +88,13 @@ impl PerformCrud for CreatePost {
       };
 
     let inserted_post_id = inserted_post.id;
+    let protocol_and_hostname = context.settings().get_protocol_and_hostname();
     let updated_post = blocking(context.pool(), move |conn| -> Result<Post, LemmyError> {
-      let apub_id = generate_apub_endpoint(EndpointType::Post, &inserted_post_id.to_string())?;
+      let apub_id = generate_apub_endpoint(
+        EndpointType::Post,
+        &inserted_post_id.to_string(),
+        &protocol_and_hostname,
+      )?;
       Ok(Post::update_ap_id(conn, inserted_post_id, apub_id)?)
     })
     .await?
index c0ef351229c731bff1e93983afb98b7f0393c98f..18ede8a3743deab835154e7597d515775fa645a9 100644 (file)
@@ -23,7 +23,8 @@ impl PerformCrud for DeletePost {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PostResponse, LemmyError> {
     let data: &DeletePost = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let post_id = data.post_id;
     let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
@@ -83,7 +84,8 @@ impl PerformCrud for RemovePost {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PostResponse, LemmyError> {
     let data: &RemovePost = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     let post_id = data.post_id;
     let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
index d651a057708cd3e50b8bbc6e5e40c3d4b6a18e5f..1cfcbaf8c5f987300196530270da255274aae211 100644 (file)
@@ -24,7 +24,8 @@ impl PerformCrud for GetPost {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetPostResponse, LemmyError> {
     let data: &GetPost = self;
-    let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
 
     let show_bot_accounts = local_user_view
       .as_ref()
@@ -112,7 +113,8 @@ impl PerformCrud for GetPosts {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetPostsResponse, LemmyError> {
     let data: &GetPosts = self;
-    let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
 
     let person_id = local_user_view.to_owned().map(|l| l.person.id);
 
@@ -133,7 +135,7 @@ impl PerformCrud for GetPosts {
     let community_actor_id = data
       .community_name
       .as_ref()
-      .map(|t| build_actor_id_from_shortname(EndpointType::Community, t).ok())
+      .map(|t| build_actor_id_from_shortname(EndpointType::Community, t, &context.settings()).ok())
       .unwrap_or(None);
     let saved_only = data.saved_only;
 
index d52538e0684feef05d6c5b7743fcbffe6a5ba27d..b947868262fcd93403c8a5df496daf3fd916999c 100644 (file)
@@ -23,10 +23,12 @@ impl PerformCrud for EditPost {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PostResponse, LemmyError> {
     let data: &EditPost = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
-    check_slurs_opt(&data.name)?;
-    check_slurs_opt(&data.body)?;
+    let slur_regex = &context.settings().slur_regex();
+    check_slurs_opt(&data.name, slur_regex)?;
+    check_slurs_opt(&data.body, slur_regex)?;
 
     if let Some(name) = &data.name {
       if !is_valid_post_title(name) {
@@ -51,7 +53,8 @@ impl PerformCrud for EditPost {
 
     // Fetch post links and Pictrs cached image
     let data_url = data.url.as_ref();
-    let (metadata_res, pictrs_thumbnail) = fetch_site_data(context.client(), data_url).await;
+    let (metadata_res, pictrs_thumbnail) =
+      fetch_site_data(context.client(), &context.settings(), data_url).await;
     let (embed_title, embed_description, embed_html) = metadata_res
       .map(|u| (u.title, u.description, u.html))
       .unwrap_or((None, None, None));
index 18ef3835d35c868d96907cd64cb68f29a916579b..10d77da450c0015388b18689a815d2890ad7cb99 100644 (file)
@@ -31,9 +31,11 @@ impl PerformCrud for CreatePrivateMessage {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PrivateMessageResponse, LemmyError> {
     let data: &CreatePrivateMessage = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
-    let content_slurs_removed = remove_slurs(&data.content.to_owned());
+    let content_slurs_removed =
+      remove_slurs(&data.content.to_owned(), &context.settings().slur_regex());
 
     check_person_block(local_user_view.person.id, data.recipient_id, context.pool()).await?;
 
@@ -56,12 +58,14 @@ impl PerformCrud for CreatePrivateMessage {
     };
 
     let inserted_private_message_id = inserted_private_message.id;
+    let protocol_and_hostname = context.settings().get_protocol_and_hostname();
     let updated_private_message = blocking(
       context.pool(),
       move |conn| -> Result<PrivateMessage, LemmyError> {
         let apub_id = generate_apub_endpoint(
           EndpointType::PrivateMessage,
           &inserted_private_message_id.to_string(),
+          &protocol_and_hostname,
         )?;
         Ok(PrivateMessage::update_ap_id(
           conn,
@@ -101,6 +105,7 @@ impl PerformCrud for CreatePrivateMessage {
         "Private Message from",
         "Private Message",
         &content_slurs_removed,
+        &context.settings(),
       );
     }
 
index 6cd2b44f2085871d24d50872f18a79f6e75ee9b1..2171a143622d2cd2442a059445dd4ab5f5311774 100644 (file)
@@ -24,7 +24,8 @@ impl PerformCrud for DeletePrivateMessage {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PrivateMessageResponse, LemmyError> {
     let data: &DeletePrivateMessage = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Checking permissions
     let private_message_id = data.private_message_id;
index 3acbaa39200b8a0cfe6ae4c565ee5bbcd8c71c55..bf119d75c004a48c31550c92dafbf9075a171d09 100644 (file)
@@ -20,7 +20,8 @@ impl PerformCrud for GetPrivateMessages {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<PrivateMessagesResponse, LemmyError> {
     let data: &GetPrivateMessages = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
     let person_id = local_user_view.person.id;
 
     let page = data.page;
index 72ca4fbbf2d15e0c09bfe9281f6a0da739840dc0..1f7ec82baa82e4e759cfc01ed33767b772f69123 100644 (file)
@@ -24,7 +24,8 @@ impl PerformCrud for EditPrivateMessage {
     websocket_id: Option<ConnectionId>,
   ) -> Result<PrivateMessageResponse, LemmyError> {
     let data: &EditPrivateMessage = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Checking permissions
     let private_message_id = data.private_message_id;
@@ -37,7 +38,7 @@ impl PerformCrud for EditPrivateMessage {
     }
 
     // Doing the update
-    let content_slurs_removed = remove_slurs(&data.content);
+    let content_slurs_removed = remove_slurs(&data.content, &context.settings().slur_regex());
     let private_message_id = data.private_message_id;
     let updated_private_message = blocking(context.pool(), move |conn| {
       PrivateMessage::update_content(conn, private_message_id, &content_slurs_removed)
index b84adcdb4e88d3342bdd5b3a82cbfc55365d904c..8038f62cbd58cffe50a3ed41c6253a043874a182 100644 (file)
@@ -39,10 +39,11 @@ impl PerformCrud for CreateSite {
       return Err(ApiError::err("site_already_exists").into());
     };
 
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
-    check_slurs(&data.name)?;
-    check_slurs_opt(&data.description)?;
+    check_slurs(&data.name, &context.settings().slur_regex())?;
+    check_slurs_opt(&data.description, &context.settings().slur_regex())?;
 
     // Make sure user is an admin
     is_admin(&local_user_view)?;
index 0478109dc9fff3f466a9c577bc78162bb55a6c2d..1bed1e3bca5bdc9bad9a0530b7fbe573c6cac34c 100644 (file)
@@ -15,7 +15,7 @@ use lemmy_db_views_actor::{
   person_block_view::PersonBlockView,
   person_view::PersonViewSafe,
 };
-use lemmy_utils::{settings::structs::Settings, version, ApiError, ConnectionId, LemmyError};
+use lemmy_utils::{version, ApiError, ConnectionId, LemmyError};
 use lemmy_websocket::{messages::GetUsersOnline, LemmyContext};
 use log::info;
 
@@ -34,7 +34,7 @@ impl PerformCrud for GetSite {
       Ok(site_view) => Some(site_view),
       // If the site isn't created yet, check the setup
       Err(_) => {
-        if let Some(setup) = Settings::get().setup.as_ref() {
+        if let Some(setup) = context.settings().setup.as_ref() {
           let register = Register {
             username: setup.admin_username.to_owned(),
             email: setup.admin_email.to_owned(),
@@ -91,7 +91,8 @@ impl PerformCrud for GetSite {
 
     // Build the local user
     let my_user = if let Some(local_user_view) =
-      get_local_user_settings_view_from_jwt_opt(&data.auth, context.pool()).await?
+      get_local_user_settings_view_from_jwt_opt(&data.auth, context.pool(), context.secret())
+        .await?
     {
       let person_id = local_user_view.person.id;
       let follows = blocking(context.pool(), move |conn| {
@@ -131,7 +132,12 @@ impl PerformCrud for GetSite {
       None
     };
 
-    let federated_instances = build_federated_instances(context.pool()).await?;
+    let federated_instances = build_federated_instances(
+      context.pool(),
+      &context.settings().federation,
+      &context.settings().hostname,
+    )
+    .await?;
 
     Ok(GetSiteResponse {
       site_view,
index 781ea00812041bda6afc9f99c25e0c5e72683e55..b92cfd4a191b3118a9f2391a118867671444ba63 100644 (file)
@@ -30,10 +30,11 @@ impl PerformCrud for EditSite {
     websocket_id: Option<ConnectionId>,
   ) -> Result<SiteResponse, LemmyError> {
     let data: &EditSite = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
-    check_slurs_opt(&data.name)?;
-    check_slurs_opt(&data.description)?;
+    check_slurs_opt(&data.name, &context.settings().slur_regex())?;
+    check_slurs_opt(&data.description, &context.settings().slur_regex())?;
 
     // Make sure user is an admin
     is_admin(&local_user_view)?;
index 24b73462376d6f4069b7a68b92d9fcf2cdd99210..2b093e013f596bfb7b1d579abbb76d0d872b48d3 100644 (file)
@@ -9,7 +9,7 @@ use lemmy_apub::{
   EndpointType,
 };
 use lemmy_db_queries::{
-  source::{local_user::LocalUser_, secret::SecretSingleton, site::Site_},
+  source::{local_user::LocalUser_, site::Site_},
   Crud,
   Followable,
   Joinable,
@@ -21,7 +21,6 @@ use lemmy_db_schema::{
     community::*,
     local_user::{LocalUser, LocalUserForm},
     person::*,
-    secret::Secret,
     site::*,
   },
   CommunityId,
@@ -30,7 +29,6 @@ use lemmy_db_views_actor::person_view::PersonViewSafe;
 use lemmy_utils::{
   apub::generate_actor_keypair,
   claims::Claims,
-  settings::structs::Settings,
   utils::{check_slurs, is_valid_actor_name},
   ApiError,
   ConnectionId,
@@ -70,7 +68,7 @@ impl PerformCrud for Register {
     .await??;
 
     // If its not the admin, check the captcha
-    if !no_admins && Settings::get().captcha.enabled {
+    if !no_admins && context.settings().captcha.enabled {
       let check = context
         .chat_server()
         .send(CheckCaptcha {
@@ -89,13 +87,17 @@ impl PerformCrud for Register {
       }
     }
 
-    check_slurs(&data.username)?;
+    check_slurs(&data.username, &context.settings().slur_regex())?;
 
     let actor_keypair = generate_actor_keypair()?;
-    if !is_valid_actor_name(&data.username) {
+    if !is_valid_actor_name(&data.username, context.settings().actor_name_max_length) {
       return Err(ApiError::err("invalid_username").into());
     }
-    let actor_id = generate_apub_endpoint(EndpointType::Person, &data.username)?;
+    let actor_id = generate_apub_endpoint(
+      EndpointType::Person,
+      &data.username,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
 
     // We have to create both a person, and local_user
 
@@ -165,6 +167,7 @@ impl PerformCrud for Register {
     let main_community_keypair = generate_actor_keypair()?;
 
     // Create the main community if it doesn't exist
+    let protocol_and_hostname = context.settings().get_protocol_and_hostname();
     let main_community = match blocking(context.pool(), move |conn| {
       Community::read(conn, CommunityId(2))
     })
@@ -173,7 +176,11 @@ impl PerformCrud for Register {
       Ok(c) => c,
       Err(_e) => {
         let default_community_name = "main";
-        let actor_id = generate_apub_endpoint(EndpointType::Community, default_community_name)?;
+        let actor_id = generate_apub_endpoint(
+          EndpointType::Community,
+          default_community_name,
+          &protocol_and_hostname,
+        )?;
         let community_form = CommunityForm {
           name: default_community_name.to_string(),
           title: "The Default Community".to_string(),
@@ -219,9 +226,12 @@ impl PerformCrud for Register {
     }
 
     // Return the jwt
-    let jwt_secret = Secret::get().jwt_secret;
     Ok(LoginResponse {
-      jwt: Claims::jwt(inserted_local_user.id.0, &jwt_secret)?,
+      jwt: Claims::jwt(
+        inserted_local_user.id.0,
+        &context.secret().jwt_secret,
+        &context.settings().hostname,
+      )?,
     })
   }
 }
index fb9480dc7e74052871cf892b4f55c1b9998a4603..24f3c4003f07d6ad106f3e8cbf594010bf061c52 100644 (file)
@@ -17,7 +17,8 @@ impl PerformCrud for DeleteAccount {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<LoginResponse, LemmyError> {
     let data: &DeleteAccount = self;
-    let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
 
     // Verify the password
     let valid: bool = verify(
index 4cfd90ab5ae7d12ecdc9f3cfd0ea82260efd9941..b029f2998c6fa84fc5a6e16187bd25ebde9de6a1 100644 (file)
@@ -22,7 +22,8 @@ impl PerformCrud for GetPersonDetails {
     _websocket_id: Option<ConnectionId>,
   ) -> Result<GetPersonDetailsResponse, LemmyError> {
     let data: &GetPersonDetails = self;
-    let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
 
     let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw);
     let show_bot_accounts = local_user_view
@@ -41,7 +42,8 @@ impl PerformCrud for GetPersonDetails {
           .username
           .to_owned()
           .unwrap_or_else(|| "admin".to_string());
-        let actor_id = build_actor_id_from_shortname(EndpointType::Person, &name)?;
+        let actor_id =
+          build_actor_id_from_shortname(EndpointType::Person, &name, &context.settings())?;
 
         let person = blocking(context.pool(), move |conn| {
           Person::read_from_apub_id(conn, &actor_id)
index 9ce172004e90663db0d9b5000d10d9db430430f5..130623ff7b0f14d27c0d41d51aa426003de9e750 100644 (file)
@@ -57,7 +57,10 @@ impl CreateOrUpdateComment {
     })
     .await??;
 
-    let id = generate_activity_id(kind.clone())?;
+    let id = generate_activity_id(
+      kind.clone(),
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let maa = collect_non_local_mentions(comment, &community, context).await?;
 
     let create_or_update = CreateOrUpdateComment {
@@ -87,7 +90,7 @@ impl ActivityHandler for CreateOrUpdateComment {
     let community = extract_community(&self.cc, context, request_counter).await?;
     let community_id = ObjectId::new(community.actor_id());
 
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &community_id, context, request_counter).await?;
     verify_domains_match(self.actor.inner(), self.object.id_unchecked())?;
     // TODO: should add a check that the correct community is in cc (probably needs changes to
index 8f27e9bacffb997c7cb1698e255156db076a5e0f..9e91d2f1b01678e68614f5ac72809cd513939d21 100644 (file)
@@ -14,13 +14,11 @@ use lemmy_db_schema::{
 };
 use lemmy_utils::{
   request::{retry, RecvError},
-  settings::structs::Settings,
   utils::{scrape_text_for_mentions, MentionData},
   LemmyError,
 };
 use lemmy_websocket::LemmyContext;
 use log::debug;
-use reqwest::Client;
 use url::Url;
 
 pub mod create_or_update;
@@ -41,7 +39,16 @@ async fn get_notif_recipients(
   // anyway.
   // TODO: for compatibility with other projects, it would be much better to read this from cc or tags
   let mentions = scrape_text_for_mentions(&comment.content);
-  send_local_notifs(mentions, comment.clone(), actor, post, context.pool(), true).await
+  send_local_notifs(
+    mentions,
+    comment.clone(),
+    actor,
+    post,
+    context.pool(),
+    true,
+    &context.settings(),
+  )
+  .await
 }
 
 pub struct MentionsAndAddresses {
@@ -70,12 +77,12 @@ pub async fn collect_non_local_mentions(
   let mentions = scrape_text_for_mentions(&comment.content)
     .into_iter()
     // Filter only the non-local ones
-    .filter(|m| !m.is_local())
+    .filter(|m| !m.is_local(&context.settings().hostname))
     .collect::<Vec<MentionData>>();
 
   for mention in &mentions {
     // TODO should it be fetching it every time?
-    if let Ok(actor_id) = fetch_webfinger_url(mention, context.client()).await {
+    if let Ok(actor_id) = fetch_webfinger_url(mention, context).await {
       let actor_id: ObjectId<Person> = ObjectId::new(actor_id);
       debug!("mention actor_id: {}", actor_id);
       addressed_ccs.push(actor_id.to_owned().to_string().parse()?);
@@ -120,17 +127,20 @@ async fn get_comment_parent_creator(
 
 /// Turns a person id like `@name@example.com` into an apub ID, like `https://example.com/user/name`,
 /// using webfinger.
-async fn fetch_webfinger_url(mention: &MentionData, client: &Client) -> Result<Url, LemmyError> {
+async fn fetch_webfinger_url(
+  mention: &MentionData,
+  context: &LemmyContext,
+) -> Result<Url, LemmyError> {
   let fetch_url = format!(
     "{}://{}/.well-known/webfinger?resource=acct:{}@{}",
-    Settings::get().get_protocol_string(),
+    context.settings().get_protocol_string(),
     mention.domain,
     mention.name,
     mention.domain
   );
   debug!("Fetching webfinger url: {}", &fetch_url);
 
-  let response = retry(|| client.get(&fetch_url).send()).await?;
+  let response = retry(|| context.client().get(&fetch_url).send()).await?;
 
   let res: WebfingerResponse = response
     .json()
index a066211f3442e50097b888523a1deb1451b259d5..a71414dd226938eee20c8e8d27b94e5d8e619721 100644 (file)
@@ -55,7 +55,10 @@ impl AddMod {
     actor: &Person,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let id = generate_activity_id(AddType::Add)?;
+    let id = generate_activity_id(
+      AddType::Add,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let add = AddMod {
       actor: ObjectId::new(actor.actor_id()),
       to: [PublicUrl::Public],
@@ -81,7 +84,7 @@ impl ActivityHandler for AddMod {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, self.cc[0].clone(), context).await?;
     verify_add_remove_moderator_target(&self.target, &self.cc[0])?;
index 96797c8ffbbbee4439b6682ad9409b101c9cb5ff..dae37b60e0ef459e4bdaba6cd8a2bdb76ab3501c 100644 (file)
@@ -84,7 +84,10 @@ impl AnnounceActivity {
       object,
       cc: vec![community.followers_url()],
       kind: AnnounceType::Announce,
-      id: generate_activity_id(&AnnounceType::Announce)?,
+      id: generate_activity_id(
+        &AnnounceType::Announce,
+        &context.settings().get_protocol_and_hostname(),
+      )?,
       context: lemmy_context(),
       unparsed: Default::default(),
     };
@@ -100,7 +103,7 @@ impl ActivityHandler for AnnounceActivity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_community(&self.actor, context, request_counter).await?;
     self.object.verify(context, request_counter).await?;
     Ok(())
index f7e81f97c4a9c761a93b02b7d5ca02c92a7049bc..ad999988437c8dbdfbf5a28e112904d98d735b74 100644 (file)
@@ -56,6 +56,7 @@ impl BlockUserFromCommunity {
     community: &Community,
     target: &Person,
     actor: &Person,
+    context: &LemmyContext,
   ) -> Result<BlockUserFromCommunity, LemmyError> {
     Ok(BlockUserFromCommunity {
       actor: ObjectId::new(actor.actor_id()),
@@ -63,7 +64,10 @@ impl BlockUserFromCommunity {
       object: ObjectId::new(target.actor_id()),
       cc: [ObjectId::new(community.actor_id())],
       kind: BlockType::Block,
-      id: generate_activity_id(BlockType::Block)?,
+      id: generate_activity_id(
+        BlockType::Block,
+        &context.settings().get_protocol_and_hostname(),
+      )?,
       context: lemmy_context(),
       unparsed: Default::default(),
     })
@@ -75,7 +79,7 @@ impl BlockUserFromCommunity {
     actor: &Person,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let block = BlockUserFromCommunity::new(community, target, actor)?;
+    let block = BlockUserFromCommunity::new(community, target, actor, context)?;
     let block_id = block.id.clone();
 
     let activity = AnnouncableActivities::BlockUserFromCommunity(block);
@@ -91,7 +95,7 @@ impl ActivityHandler for BlockUserFromCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, self.cc[0].clone(), context).await?;
     Ok(())
index ba80ff4ad080f89cde0f7c597e753ddb8aa0face..642f83645c86e94fb3f869bc117edb88d5f4ba42 100644 (file)
@@ -1,7 +1,7 @@
 use crate::{check_is_apub_id_valid, CommunityType};
 use itertools::Itertools;
 use lemmy_db_schema::source::community::Community;
-use lemmy_utils::{settings::structs::Settings, LemmyError};
+use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
 use url::Url;
 
@@ -19,14 +19,16 @@ async fn list_community_follower_inboxes(
 ) -> Result<Vec<Url>, LemmyError> {
   Ok(
     vec![
-      community.get_follower_inboxes(context.pool()).await?,
+      community
+        .get_follower_inboxes(context.pool(), &context.settings())
+        .await?,
       additional_inboxes,
     ]
     .iter()
     .flatten()
     .unique()
-    .filter(|inbox| inbox.host_str() != Some(&Settings::get().hostname))
-    .filter(|inbox| check_is_apub_id_valid(inbox, false).is_ok())
+    .filter(|inbox| inbox.host_str() != Some(&context.settings().hostname))
+    .filter(|inbox| check_is_apub_id_valid(inbox, false, &context.settings()).is_ok())
     .map(|inbox| inbox.to_owned())
     .collect(),
   )
index 4960076c1a84a7dbd3bf1425d685ac496903974e..2da9bbdbb22eed59a32b62e5cb539a804ab3041a 100644 (file)
@@ -57,7 +57,10 @@ impl RemoveMod {
     actor: &Person,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let id = generate_activity_id(RemoveType::Remove)?;
+    let id = generate_activity_id(
+      RemoveType::Remove,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let remove = RemoveMod {
       actor: ObjectId::new(actor.actor_id()),
       to: [PublicUrl::Public],
@@ -83,7 +86,7 @@ impl ActivityHandler for RemoveMod {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     if let Some(target) = &self.target {
       verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
       verify_mod_action(&self.actor, self.cc[0].clone(), context).await?;
index eec90682103b8f9a24776e3ffb5f7a019c1dc9b2..29aa83f5b827f60e0309127caa5bb960f5d03a53 100644 (file)
@@ -52,9 +52,12 @@ impl UndoBlockUserFromCommunity {
     actor: &Person,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let block = BlockUserFromCommunity::new(community, target, actor)?;
+    let block = BlockUserFromCommunity::new(community, target, actor, context)?;
 
-    let id = generate_activity_id(UndoType::Undo)?;
+    let id = generate_activity_id(
+      UndoType::Undo,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let undo = UndoBlockUserFromCommunity {
       actor: ObjectId::new(actor.actor_id()),
       to: [PublicUrl::Public],
@@ -79,7 +82,7 @@ impl ActivityHandler for UndoBlockUserFromCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, self.cc[0].clone(), context).await?;
     self.object.verify(context, request_counter).await?;
index a6da1c9f31e4d911781c6ccd9a2da3dbaf605ad3..d217e2561f4c008f8d7d3d7cdeeae26bda6f6999 100644 (file)
@@ -55,7 +55,10 @@ impl UpdateCommunity {
     actor: &Person,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let id = generate_activity_id(UpdateType::Update)?;
+    let id = generate_activity_id(
+      UpdateType::Update,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let update = UpdateCommunity {
       actor: ObjectId::new(actor.actor_id()),
       to: [PublicUrl::Public],
@@ -79,7 +82,7 @@ impl ActivityHandler for UpdateCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, self.cc[0].clone(), context).await?;
     Ok(())
@@ -96,8 +99,12 @@ impl ActivityHandler for UpdateCommunity {
     })
     .await??;
 
-    let updated_community =
-      Group::from_apub_to_form(&self.object, &community.actor_id.clone().into()).await?;
+    let updated_community = Group::from_apub_to_form(
+      &self.object,
+      &community.actor_id.clone().into(),
+      &context.settings(),
+    )
+    .await?;
     let cf = CommunityForm {
       name: updated_community.name,
       title: updated_community.title,
index 8e8bd942f040681740f556628f7fc6c6237cced1..9e957a8ee0a01e50b6b2d0acaf8fd0e2adad9d2c 100644 (file)
@@ -87,7 +87,7 @@ impl ActivityHandler for Delete {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_delete_activity(
       &self.object,
       self,
@@ -138,6 +138,7 @@ impl Delete {
     community: &Community,
     object_id: Url,
     summary: Option<String>,
+    context: &LemmyContext,
   ) -> Result<Delete, LemmyError> {
     Ok(Delete {
       actor: ObjectId::new(actor.actor_id()),
@@ -146,7 +147,10 @@ impl Delete {
       cc: [ObjectId::new(community.actor_id())],
       kind: DeleteType::Delete,
       summary,
-      id: generate_activity_id(DeleteType::Delete)?,
+      id: generate_activity_id(
+        DeleteType::Delete,
+        &context.settings().get_protocol_and_hostname(),
+      )?,
       context: lemmy_context(),
       unparsed: Default::default(),
     })
@@ -158,7 +162,7 @@ impl Delete {
     summary: Option<String>,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let delete = Delete::new(actor, community, object_id, summary)?;
+    let delete = Delete::new(actor, community, object_id, summary, context)?;
     let delete_id = delete.id.clone();
 
     let activity = AnnouncableActivities::Delete(delete);
index 2dbbf9c46a7271b0dcca3ca3c35309f00b95c2e5..f74c34c90d30e820807f5760d16008c327a77808 100644 (file)
@@ -59,7 +59,7 @@ impl ActivityHandler for UndoDelete {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     self.object.verify(context, request_counter).await?;
     verify_delete_activity(
       &self.object.object,
@@ -106,9 +106,12 @@ impl UndoDelete {
     summary: Option<String>,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let object = Delete::new(actor, community, object_id, summary)?;
+    let object = Delete::new(actor, community, object_id, summary, context)?;
 
-    let id = generate_activity_id(UndoType::Undo)?;
+    let id = generate_activity_id(
+      UndoType::Undo,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let undo = UndoDelete {
       actor: ObjectId::new(actor.actor_id()),
       to: [PublicUrl::Public],
index a7472bc1cb0cb91cf856858c031102d4c8507342..86b0d2093c205719449ee91be55cf7aa5afcb584 100644 (file)
@@ -61,7 +61,10 @@ impl AcceptFollowCommunity {
       to: ObjectId::new(person.actor_id()),
       object: follow,
       kind: AcceptType::Accept,
-      id: generate_activity_id(AcceptType::Accept)?,
+      id: generate_activity_id(
+        AcceptType::Accept,
+        &context.settings().get_protocol_and_hostname(),
+      )?,
       context: lemmy_context(),
       unparsed: Default::default(),
     };
@@ -77,7 +80,7 @@ impl ActivityHandler for AcceptFollowCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_urls_match(self.to.inner(), self.object.actor())?;
     verify_urls_match(self.actor(), self.object.to.inner())?;
     verify_community(&self.actor, context, request_counter).await?;
index 8af3d3889821f294b85e1f775cef8396789b4e9a..21446eb1276e3c23342b680dea02e779fb036799 100644 (file)
@@ -48,13 +48,17 @@ impl FollowCommunity {
   pub(in crate::activities::following) fn new(
     actor: &Person,
     community: &Community,
+    context: &LemmyContext,
   ) -> Result<FollowCommunity, LemmyError> {
     Ok(FollowCommunity {
       actor: ObjectId::new(actor.actor_id()),
       to: ObjectId::new(community.actor_id()),
       object: ObjectId::new(community.actor_id()),
       kind: FollowType::Follow,
-      id: generate_activity_id(FollowType::Follow)?,
+      id: generate_activity_id(
+        FollowType::Follow,
+        &context.settings().get_protocol_and_hostname(),
+      )?,
       context: lemmy_context(),
       unparsed: Default::default(),
     })
@@ -74,7 +78,7 @@ impl FollowCommunity {
     })
     .await?;
 
-    let follow = FollowCommunity::new(actor, community)?;
+    let follow = FollowCommunity::new(actor, community, context)?;
     let inbox = vec![community.inbox_url.clone().into()];
     send_activity_new(context, &follow, &follow.id, actor, inbox, true).await
   }
@@ -87,7 +91,7 @@ impl ActivityHandler for FollowCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_urls_match(self.to.inner(), self.object.inner())?;
     verify_person(&self.actor, context, request_counter).await?;
     Ok(())
index f35b3095fc595cb2e2e7bf6995ed3d932bbf5364..cc103075dd8abf70c004e2d7fd0621b39c816ab1 100644 (file)
@@ -49,13 +49,16 @@ impl UndoFollowCommunity {
     community: &Community,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let object = FollowCommunity::new(actor, community)?;
+    let object = FollowCommunity::new(actor, community, context)?;
     let undo = UndoFollowCommunity {
       actor: ObjectId::new(actor.actor_id()),
       to: ObjectId::new(community.actor_id()),
       object,
       kind: UndoType::Undo,
-      id: generate_activity_id(UndoType::Undo)?,
+      id: generate_activity_id(
+        UndoType::Undo,
+        &context.settings().get_protocol_and_hostname(),
+      )?,
       context: lemmy_context(),
       unparsed: Default::default(),
     };
@@ -71,7 +74,7 @@ impl ActivityHandler for UndoFollowCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_urls_match(self.to.inner(), self.object.object.inner())?;
     verify_urls_match(self.actor(), self.object.actor())?;
     verify_person(&self.actor, context, request_counter).await?;
index 3cfaca859f92f6c373b1c2e9f662c781af96a299..e72f1e1dc205243183510b5f42ec9d43d10aba90 100644 (file)
@@ -91,8 +91,8 @@ async fn verify_community(
   Ok(())
 }
 
-fn verify_activity(activity: &dyn ActivityFields) -> Result<(), LemmyError> {
-  check_is_apub_id_valid(activity.actor(), false)?;
+fn verify_activity(activity: &dyn ActivityFields, settings: &Settings) -> Result<(), LemmyError> {
+  check_is_apub_id_valid(activity.actor(), false, settings)?;
   verify_domains_match(activity.id_unchecked(), activity.actor())?;
   Ok(())
 }
@@ -146,13 +146,13 @@ fn verify_add_remove_moderator_target(
 
 /// Generate a unique ID for an activity, in the format:
 /// `http(s)://example.com/receive/create/202daf0a-1489-45df-8d2e-c8a3173fed36`
-fn generate_activity_id<T>(kind: T) -> Result<Url, ParseError>
+fn generate_activity_id<T>(kind: T, protocol_and_hostname: &str) -> Result<Url, ParseError>
 where
   T: ToString,
 {
   let id = format!(
     "{}/activities/{}/{}",
-    Settings::get().get_protocol_and_hostname(),
+    protocol_and_hostname,
     kind.to_string().to_lowercase(),
     Uuid::new_v4()
   );
index 8a48da5f8a2c6e39206e84fa815a2fb68fb7450b..ae93f098884a46c6da58b7b796769760473bd721 100644 (file)
@@ -59,7 +59,10 @@ impl CreateOrUpdatePost {
     })
     .await??;
 
-    let id = generate_activity_id(kind.clone())?;
+    let id = generate_activity_id(
+      kind.clone(),
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let create_or_update = CreateOrUpdatePost {
       actor: ObjectId::new(actor.actor_id()),
       to: [PublicUrl::Public],
@@ -83,7 +86,7 @@ impl ActivityHandler for CreateOrUpdatePost {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     let community = self.cc[0].dereference(context, request_counter).await?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     match self.kind {
index 83f4824b144f7bc719f0a7e4885222770bf8c18b..f3b1c91fb549fabdb99c5621c385650a6cf2e640 100644 (file)
@@ -42,7 +42,10 @@ impl CreateOrUpdatePrivateMessage {
     let recipient =
       blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
 
-    let id = generate_activity_id(kind.clone())?;
+    let id = generate_activity_id(
+      kind.clone(),
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let create_or_update = CreateOrUpdatePrivateMessage {
       context: lemmy_context(),
       id: id.clone(),
@@ -63,7 +66,7 @@ impl ActivityHandler for CreateOrUpdatePrivateMessage {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person(&self.actor, context, request_counter).await?;
     verify_domains_match(self.actor.inner(), self.object.id_unchecked())?;
     self.object.verify(context, request_counter).await?;
index 82aad3177b241ab73a6178a8f504d67b5e5f1861..bf12f9d1ebc577695f39b31074b5d6bcdb444c5f 100644 (file)
@@ -39,13 +39,17 @@ impl DeletePrivateMessage {
   pub(in crate::activities::private_message) fn new(
     actor: &Person,
     pm: &PrivateMessage,
+    context: &LemmyContext,
   ) -> Result<DeletePrivateMessage, LemmyError> {
     Ok(DeletePrivateMessage {
       actor: ObjectId::new(actor.actor_id()),
       to: ObjectId::new(actor.actor_id()),
       object: pm.ap_id.clone().into(),
       kind: DeleteType::Delete,
-      id: generate_activity_id(DeleteType::Delete)?,
+      id: generate_activity_id(
+        DeleteType::Delete,
+        &context.settings().get_protocol_and_hostname(),
+      )?,
       context: lemmy_context(),
       unparsed: Default::default(),
     })
@@ -55,7 +59,7 @@ impl DeletePrivateMessage {
     pm: &PrivateMessage,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let delete = DeletePrivateMessage::new(actor, pm)?;
+    let delete = DeletePrivateMessage::new(actor, pm, context)?;
     let delete_id = delete.id.clone();
 
     let recipient_id = pm.recipient_id;
@@ -73,7 +77,7 @@ impl ActivityHandler for DeletePrivateMessage {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person(&self.actor, context, request_counter).await?;
     verify_domains_match(self.actor.inner(), &self.object)?;
     Ok(())
index 2dc9d7242428ca839275ea337e994a3146b9fa65..5aa6dbed4eaf54b70dd6dcd406c5109ca3784060 100644 (file)
@@ -50,8 +50,11 @@ impl UndoDeletePrivateMessage {
     let recipient =
       blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
 
-    let object = DeletePrivateMessage::new(actor, pm)?;
-    let id = generate_activity_id(UndoType::Undo)?;
+    let object = DeletePrivateMessage::new(actor, pm, context)?;
+    let id = generate_activity_id(
+      UndoType::Undo,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let undo = UndoDeletePrivateMessage {
       actor: ObjectId::new(actor.actor_id()),
       to: ObjectId::new(recipient.actor_id()),
@@ -73,7 +76,7 @@ impl ActivityHandler for UndoDeletePrivateMessage {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person(&self.actor, context, request_counter).await?;
     verify_urls_match(self.actor(), self.object.actor())?;
     verify_domains_match(self.actor(), &self.object.object)?;
index 29aa9dba8c62c43ae2c15115d20dfae85ddc4206..7f9c19e8cf1a58902245b0056f349260d793f139 100644 (file)
@@ -4,7 +4,7 @@ use lemmy_api_common::blocking;
 use lemmy_db_queries::DbPool;
 use lemmy_db_schema::source::community::Community;
 use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
-use lemmy_utils::LemmyError;
+use lemmy_utils::{settings::structs::Settings, LemmyError};
 use url::Url;
 
 impl ActorType for Community {
@@ -40,7 +40,11 @@ impl CommunityType for Community {
   }
 
   /// For a given community, returns the inboxes of all followers.
-  async fn get_follower_inboxes(&self, pool: &DbPool) -> Result<Vec<Url>, LemmyError> {
+  async fn get_follower_inboxes(
+    &self,
+    pool: &DbPool,
+    settings: &Settings,
+  ) -> Result<Vec<Url>, LemmyError> {
     let id = self.id;
 
     let follows = blocking(pool, move |conn| {
@@ -54,7 +58,7 @@ impl CommunityType for Community {
       .map(|i| i.into_inner())
       .unique()
       // Don't send to blocked instances
-      .filter(|inbox| check_is_apub_id_valid(inbox, false).is_ok())
+      .filter(|inbox| check_is_apub_id_valid(inbox, false, settings).is_ok())
       .collect();
 
     Ok(inboxes)
index eaf3684de28d36e82ac6a9f599c72d3b697fef71..422d0deeada2831ce3e0922cd10b7bcf8a7fcaa4 100644 (file)
@@ -43,7 +43,7 @@ impl ActivityHandler for UndoRemovePostCommentOrCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     self.object.verify(context, request_counter).await?;
 
     verify_delete_activity(
index e11d29602c41452d1d3bf3ee0bfcded368a985bb..963292fa576b369ee293acffa768676700f1e8ef 100644 (file)
@@ -64,8 +64,11 @@ impl UndoVote {
     })
     .await??;
 
-    let object = Vote::new(object, actor, &community, kind.clone())?;
-    let id = generate_activity_id(UndoType::Undo)?;
+    let object = Vote::new(object, actor, &community, kind.clone(), context)?;
+    let id = generate_activity_id(
+      UndoType::Undo,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
     let undo_vote = UndoVote {
       actor: ObjectId::new(actor.actor_id()),
       to: [PublicUrl::Public],
@@ -88,7 +91,7 @@ impl ActivityHandler for UndoVote {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_urls_match(self.actor(), self.object.actor())?;
     self.object.verify(context, request_counter).await?;
index 69a9c3ba91567da7bddd87993ff9ee8c34b43090..e74dea108508aecad23d92bd319633f6edba999c 100644 (file)
@@ -77,6 +77,7 @@ impl Vote {
     actor: &Person,
     community: &Community,
     kind: VoteType,
+    context: &LemmyContext,
   ) -> Result<Vote, LemmyError> {
     Ok(Vote {
       actor: ObjectId::new(actor.actor_id()),
@@ -84,7 +85,7 @@ impl Vote {
       object: ObjectId::new(object.ap_id()),
       cc: [ObjectId::new(community.actor_id())],
       kind: kind.clone(),
-      id: generate_activity_id(kind)?,
+      id: generate_activity_id(kind, &context.settings().get_protocol_and_hostname())?,
       context: lemmy_context(),
       unparsed: Default::default(),
     })
@@ -101,7 +102,7 @@ impl Vote {
       Community::read(conn, community_id)
     })
     .await??;
-    let vote = Vote::new(object, actor, &community, kind)?;
+    let vote = Vote::new(object, actor, &community, kind, context)?;
     let vote_id = vote.id.clone();
 
     let activity = AnnouncableActivities::Vote(vote);
@@ -116,7 +117,7 @@ impl ActivityHandler for Vote {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_activity(self)?;
+    verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     Ok(())
   }
index 01959c7d72ba50f2faf4bf68efe54ebcf8de1427..f05c4fce434c0078e16f124c6dea162ae55ba780 100644 (file)
@@ -16,7 +16,7 @@ use background_jobs::{
   WorkerConfig,
 };
 use lemmy_db_schema::source::community::Community;
-use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
+use lemmy_utils::{location_info, LemmyError};
 use lemmy_websocket::LemmyContext;
 use log::{info, warn};
 use reqwest::Client;
@@ -56,7 +56,7 @@ pub(crate) async fn send_activity_new<T>(
 where
   T: Serialize,
 {
-  if !Settings::get().federation.enabled || inboxes.is_empty() {
+  if !context.settings().federation.enabled || inboxes.is_empty() {
     return Ok(());
   }
 
@@ -64,7 +64,7 @@ where
 
   // Don't send anything to ourselves
   // TODO: this should be a debug assert
-  let hostname = Settings::get().get_hostname_without_port()?;
+  let hostname = context.settings().get_hostname_without_port()?;
   let inboxes: Vec<&Url> = inboxes
     .iter()
     .filter(|i| i.domain().expect("valid inbox url") != hostname)
index 99dd3f85e87074cead5988d6231ff1907248ab11..174741128d4fc046b3fa14bb8997053a99e5ed0d 100644 (file)
@@ -73,8 +73,13 @@ pub(crate) async fn fetch_community_outbox(
   outbox: &Url,
   recursion_counter: &mut i32,
 ) -> Result<(), LemmyError> {
-  let outbox =
-    fetch_remote_object::<OrderedCollection>(context.client(), outbox, recursion_counter).await?;
+  let outbox = fetch_remote_object::<OrderedCollection>(
+    context.client(),
+    &context.settings(),
+    outbox,
+    recursion_counter,
+  )
+  .await?;
   let outbox_activities = outbox.items().context(location_info!())?.clone();
   let mut outbox_activities = outbox_activities.many().context(location_info!())?;
   if outbox_activities.len() > 20 {
@@ -98,9 +103,13 @@ async fn fetch_community_mods(
   recursion_counter: &mut i32,
 ) -> Result<Vec<Url>, LemmyError> {
   if let Some(mods_url) = &group.moderators {
-    let mods =
-      fetch_remote_object::<OrderedCollection>(context.client(), mods_url, recursion_counter)
-        .await?;
+    let mods = fetch_remote_object::<OrderedCollection>(
+      context.client(),
+      &context.settings(),
+      mods_url,
+      recursion_counter,
+    )
+    .await?;
     let mods = mods
       .items()
       .map(|i| i.as_many())
index 1e6f8de89b6ea73f6cc66a4fec3898075b6f0f7b..29c7f9df6531e71f5b89e9db3bbc241c4652aa79 100644 (file)
@@ -1,6 +1,6 @@
 use crate::{check_is_apub_id_valid, APUB_JSON_CONTENT_TYPE};
 use anyhow::anyhow;
-use lemmy_utils::{request::retry, LemmyError};
+use lemmy_utils::{request::retry, settings::structs::Settings, LemmyError};
 use log::info;
 use reqwest::Client;
 use serde::Deserialize;
@@ -18,6 +18,7 @@ static MAX_REQUEST_NUMBER: i32 = 25;
 /// timeouts etc.
 pub(in crate::fetcher) async fn fetch_remote_object<Response>(
   client: &Client,
+  settings: &Settings,
   url: &Url,
   recursion_counter: &mut i32,
 ) -> Result<Response, LemmyError>
@@ -28,7 +29,7 @@ where
   if *recursion_counter > MAX_REQUEST_NUMBER {
     return Err(anyhow!("Maximum recursion depth reached").into());
   }
-  check_is_apub_id_valid(url, false)?;
+  check_is_apub_id_valid(url, false, settings)?;
 
   let timeout = Duration::from_secs(60);
 
diff --git a/crates/apub/src/fetcher/objects.rs b/crates/apub/src/fetcher/objects.rs
new file mode 100644 (file)
index 0000000..c222776
--- /dev/null
@@ -0,0 +1,107 @@
+use crate::{
+  fetcher::fetch::fetch_remote_object,
+  objects::{comment::Note, post::Page, FromApub},
+  PostOrComment,
+};
+use anyhow::anyhow;
+use diesel::result::Error::NotFound;
+use lemmy_api_common::blocking;
+use lemmy_db_queries::{ApubObject, Crud};
+use lemmy_db_schema::source::{comment::Comment, post::Post};
+use lemmy_utils::LemmyError;
+use lemmy_websocket::LemmyContext;
+use log::debug;
+use url::Url;
+
+/// Gets a post by its apub ID. If it exists locally, it is returned directly. Otherwise it is
+/// pulled from its apub ID, inserted and returned.
+///
+/// The parent community is also pulled if necessary. Comments are not pulled.
+pub(crate) async fn get_or_fetch_and_insert_post(
+  post_ap_id: &Url,
+  context: &LemmyContext,
+  recursion_counter: &mut i32,
+) -> Result<Post, LemmyError> {
+  let post_ap_id_owned = post_ap_id.to_owned();
+  let post = blocking(context.pool(), move |conn| {
+    Post::read_from_apub_id(conn, &post_ap_id_owned.into())
+  })
+  .await?;
+
+  match post {
+    Ok(p) => Ok(p),
+    Err(NotFound {}) => {
+      debug!("Fetching and creating remote post: {}", post_ap_id);
+      let page = fetch_remote_object::<Page>(
+        context.client(),
+        &context.settings(),
+        post_ap_id,
+        recursion_counter,
+      )
+      .await?;
+      let post = Post::from_apub(&page, context, post_ap_id, recursion_counter).await?;
+
+      Ok(post)
+    }
+    Err(e) => Err(e.into()),
+  }
+}
+
+/// Gets a comment by its apub ID. If it exists locally, it is returned directly. Otherwise it is
+/// pulled from its apub ID, inserted and returned.
+///
+/// The parent community, post and comment are also pulled if necessary.
+pub(crate) async fn get_or_fetch_and_insert_comment(
+  comment_ap_id: &Url,
+  context: &LemmyContext,
+  recursion_counter: &mut i32,
+) -> Result<Comment, LemmyError> {
+  let comment_ap_id_owned = comment_ap_id.to_owned();
+  let comment = blocking(context.pool(), move |conn| {
+    Comment::read_from_apub_id(conn, &comment_ap_id_owned.into())
+  })
+  .await?;
+
+  match comment {
+    Ok(p) => Ok(p),
+    Err(NotFound {}) => {
+      debug!(
+        "Fetching and creating remote comment and its parents: {}",
+        comment_ap_id
+      );
+      let comment = fetch_remote_object::<Note>(
+        context.client(),
+        &context.settings(),
+        comment_ap_id,
+        recursion_counter,
+      )
+      .await?;
+      let comment = Comment::from_apub(&comment, context, comment_ap_id, recursion_counter).await?;
+
+      let post_id = comment.post_id;
+      let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
+      if post.locked {
+        return Err(anyhow!("Post is locked").into());
+      }
+
+      Ok(comment)
+    }
+    Err(e) => Err(e.into()),
+  }
+}
+
+pub(crate) async fn get_or_fetch_and_insert_post_or_comment(
+  ap_id: &Url,
+  context: &LemmyContext,
+  recursion_counter: &mut i32,
+) -> Result<PostOrComment, LemmyError> {
+  Ok(
+    match get_or_fetch_and_insert_post(ap_id, context, recursion_counter).await {
+      Ok(p) => PostOrComment::Post(Box::new(p)),
+      Err(_) => {
+        let c = get_or_fetch_and_insert_comment(ap_id, context, recursion_counter).await?;
+        PostOrComment::Comment(Box::new(c))
+      }
+    },
+  )
+}
diff --git a/crates/apub/src/fetcher/person.rs b/crates/apub/src/fetcher/person.rs
new file mode 100644 (file)
index 0000000..54c3163
--- /dev/null
@@ -0,0 +1,80 @@
+use crate::{
+  fetcher::{fetch::fetch_remote_object, is_deleted, should_refetch_actor},
+  objects::{person::Person as ApubPerson, FromApub},
+};
+use anyhow::anyhow;
+use diesel::result::Error::NotFound;
+use lemmy_api_common::blocking;
+use lemmy_db_queries::{source::person::Person_, ApubObject};
+use lemmy_db_schema::source::person::Person;
+use lemmy_utils::LemmyError;
+use lemmy_websocket::LemmyContext;
+use log::debug;
+use url::Url;
+
+/// Get a person from its apub ID.
+///
+/// If it exists locally and `!should_refetch_actor()`, it is returned directly from the database.
+/// Otherwise it is fetched from the remote instance, stored and returned.
+pub(crate) async fn get_or_fetch_and_upsert_person(
+  apub_id: &Url,
+  context: &LemmyContext,
+  recursion_counter: &mut i32,
+) -> Result<Person, LemmyError> {
+  let apub_id_owned = apub_id.to_owned();
+  let person = blocking(context.pool(), move |conn| {
+    Person::read_from_apub_id(conn, &apub_id_owned.into())
+  })
+  .await?;
+
+  match person {
+    // If its older than a day, re-fetch it
+    Ok(u) if !u.local && should_refetch_actor(u.last_refreshed_at) => {
+      debug!("Fetching and updating from remote person: {}", apub_id);
+      let person = fetch_remote_object::<ApubPerson>(
+        context.client(),
+        &context.settings(),
+        apub_id,
+        recursion_counter,
+      )
+      .await;
+
+      if is_deleted(&person) {
+        // TODO: use Person::update_deleted() once implemented
+        blocking(context.pool(), move |conn| {
+          Person::delete_account(conn, u.id)
+        })
+        .await??;
+        return Err(anyhow!("Person was deleted by remote instance").into());
+      } else if person.is_err() {
+        return Ok(u);
+      }
+
+      let person = Person::from_apub(&person?, context, apub_id, recursion_counter).await?;
+
+      let person_id = person.id;
+      blocking(context.pool(), move |conn| {
+        Person::mark_as_updated(conn, person_id)
+      })
+      .await??;
+
+      Ok(person)
+    }
+    Ok(u) => Ok(u),
+    Err(NotFound {}) => {
+      debug!("Fetching and creating remote person: {}", apub_id);
+      let person = fetch_remote_object::<ApubPerson>(
+        context.client(),
+        &context.settings(),
+        apub_id,
+        recursion_counter,
+      )
+      .await?;
+
+      let person = Person::from_apub(&person, context, apub_id, recursion_counter).await?;
+
+      Ok(person)
+    }
+    Err(e) => Err(e.into()),
+  }
+}
index 6a3cc14f08e7fec21db1fa263e355199b2ccde8f..da152f2f935173ba1f2f2a4ead7d191ba30fa1a3 100644 (file)
@@ -45,7 +45,14 @@ pub async fn search_by_apub_id(
       // remote actor, use webfinger to resolve url
       if name.contains('@') {
         let (name, domain) = name.splitn(2, '@').collect_tuple().expect("invalid query");
-        webfinger_resolve_actor(name, domain, kind, context.client()).await?
+        webfinger_resolve_actor(
+          name,
+          domain,
+          kind,
+          context.client(),
+          context.settings().get_protocol_string(),
+        )
+        .await?
       }
       // local actor, read from database and return
       else {
index 47182259f30aa779333c88c1b061ab4363c85296..a70ed6f00a1c1d395f52038d70c8efb1840f590c 100644 (file)
@@ -23,7 +23,7 @@ use lemmy_api_common::blocking;
 use lemmy_apub_lib::{ActivityFields, ActivityHandler};
 use lemmy_db_queries::{source::activity::Activity_, DbPool};
 use lemmy_db_schema::source::activity::Activity;
-use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
+use lemmy_utils::{location_info, LemmyError};
 use lemmy_websocket::LemmyContext;
 use log::{info, trace};
 use serde::{Deserialize, Serialize};
@@ -98,10 +98,10 @@ where
   if is_activity_already_known(context.pool(), activity.id_unchecked()).await? {
     return Ok(HttpResponse::Ok().finish());
   }
-  check_is_apub_id_valid(activity.actor(), false)?;
+  check_is_apub_id_valid(activity.actor(), false, &context.settings())?;
   info!("Verifying activity {}", activity.id_unchecked().to_string());
   activity.verify(context, request_counter).await?;
-  assert_activity_not_local(&activity)?;
+  assert_activity_not_local(&activity, &context.settings().hostname)?;
 
   // Log the activity, so we avoid receiving and parsing it twice. Note that this could still happen
   // if we receive the same activity twice in very quick succession.
@@ -151,7 +151,7 @@ pub(crate) async fn get_activity(
   info: web::Path<ActivityQuery>,
   context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse<Body>, LemmyError> {
-  let settings = Settings::get();
+  let settings = context.settings();
   let activity_id = Url::parse(&format!(
     "{}/activities/{}/{}",
     settings.get_protocol_and_hostname(),
@@ -187,10 +187,13 @@ pub(crate) async fn is_activity_already_known(
   }
 }
 
-fn assert_activity_not_local<T: Debug + ActivityFields>(activity: &T) -> Result<(), LemmyError> {
+fn assert_activity_not_local<T: Debug + ActivityFields>(
+  activity: &T,
+  hostname: &str,
+) -> Result<(), LemmyError> {
   let activity_domain = activity.id_unchecked().domain().context(location_info!())?;
 
-  if activity_domain == Settings::get().hostname {
+  if activity_domain == hostname {
     return Err(
       anyhow!(
         "Error: received activity which was sent by local instance: {:?}",
index cd6b11486ee5afa08a9864a0fdb2425f95b9d819..612cc45864207759d0a27e183529e89b685b1e4a 100644 (file)
@@ -24,9 +24,9 @@ use sha2::{Digest, Sha256};
 static APUB_JSON_CONTENT_TYPE_LONG: &str =
   "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
 
-pub fn config(cfg: &mut web::ServiceConfig) {
-  if Settings::get().federation.enabled {
-    println!("federation enabled, host is {}", Settings::get().hostname);
+pub fn config(cfg: &mut web::ServiceConfig, settings: &Settings) {
+  if settings.federation.enabled {
+    println!("federation enabled, host is {}", settings.hostname);
     let digest_verifier = VerifyDigest::new(Sha256::new());
 
     let header_guard_accept = guard::Any(guard::Header("Accept", APUB_JSON_CONTENT_TYPE))
index e7065752a03149548e0c08b362682367ed5c5bc9..027da7f7aa935601c14da90b6258f14a6f715db9 100644 (file)
@@ -37,8 +37,8 @@ static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json";
 pub(crate) fn check_is_apub_id_valid(
   apub_id: &Url,
   use_strict_allowlist: bool,
+  settings: &Settings,
 ) -> Result<(), LemmyError> {
-  let settings = Settings::get();
   let domain = apub_id.domain().context(location_info!())?.to_string();
   let local_instance = settings.get_hostname_without_port()?;
 
@@ -62,22 +62,22 @@ pub(crate) fn check_is_apub_id_valid(
     return Err(anyhow!("invalid hostname {}: {}", host, apub_id).into());
   }
 
-  if apub_id.scheme() != Settings::get().get_protocol_string() {
+  if apub_id.scheme() != settings.get_protocol_string() {
     return Err(anyhow!("invalid apub id scheme {}: {}", apub_id.scheme(), apub_id).into());
   }
 
   // TODO: might be good to put the part above in one method, and below in another
   //       (which only gets called in apub::objects)
   //        -> no that doesnt make sense, we still need the code below for blocklist and strict allowlist
-  if let Some(blocked) = Settings::get().federation.blocked_instances {
+  if let Some(blocked) = settings.to_owned().federation.blocked_instances {
     if blocked.contains(&domain) {
       return Err(anyhow!("{} is in federation blocklist", domain).into());
     }
   }
 
-  if let Some(mut allowed) = Settings::get().federation.allowed_instances {
+  if let Some(mut allowed) = settings.to_owned().federation.allowed_instances {
     // Only check allowlist if this is a community, or strict allowlist is enabled.
-    let strict_allowlist = Settings::get().federation.strict_allowlist;
+    let strict_allowlist = settings.to_owned().federation.strict_allowlist;
     if use_strict_allowlist || strict_allowlist {
       // need to allow this explicitly because apub receive might contain objects from our local
       // instance.
@@ -128,7 +128,11 @@ trait ActorType {
 #[async_trait::async_trait(?Send)]
 pub trait CommunityType {
   fn followers_url(&self) -> Url;
-  async fn get_follower_inboxes(&self, pool: &DbPool) -> Result<Vec<Url>, LemmyError>;
+  async fn get_follower_inboxes(
+    &self,
+    pool: &DbPool,
+    settings: &Settings,
+  ) -> Result<Vec<Url>, LemmyError>;
 }
 
 pub enum EndpointType {
@@ -160,12 +164,9 @@ fn generate_apub_endpoint_for_domain(
 pub fn generate_apub_endpoint(
   endpoint_type: EndpointType,
   name: &str,
+  protocol_and_hostname: &str,
 ) -> Result<DbUrl, ParseError> {
-  generate_apub_endpoint_for_domain(
-    endpoint_type,
-    name,
-    &Settings::get().get_protocol_and_hostname(),
-  )
+  generate_apub_endpoint_for_domain(endpoint_type, name, protocol_and_hostname)
 }
 
 pub fn generate_followers_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
@@ -200,6 +201,7 @@ fn generate_moderators_url(community_id: &DbUrl) -> Result<DbUrl, LemmyError> {
 pub fn build_actor_id_from_shortname(
   endpoint_type: EndpointType,
   short_name: &str,
+  settings: &Settings,
 ) -> Result<DbUrl, ParseError> {
   let split = short_name.split('@').collect::<Vec<&str>>();
 
@@ -207,9 +209,9 @@ pub fn build_actor_id_from_shortname(
 
   // If there's no @, its local
   let domain = if split.len() == 1 {
-    Settings::get().get_protocol_and_hostname()
+    settings.get_protocol_and_hostname()
   } else {
-    format!("{}://{}", Settings::get().get_protocol_string(), split[1])
+    format!("{}://{}", settings.get_protocol_string(), split[1])
   };
 
   generate_apub_endpoint_for_domain(endpoint_type, name, &domain)
index f334487101fa108268f19362319993b226062aa1..e27817d6fd418dbf1e6ce32230e47747d631efc1 100644 (file)
@@ -222,7 +222,7 @@ impl FromApub for Comment {
     }
 
     let content = &note.source.content;
-    let content_slurs_removed = remove_slurs(content);
+    let content_slurs_removed = remove_slurs(content, &context.settings().slur_regex());
 
     let form = CommentForm {
       creator_id: creator.id,
index dcd00e6d54ac29a1ac818022f21be87eff9e2142..c8ddd29724dcca733c0b46602547104bb94be978 100644 (file)
@@ -24,6 +24,7 @@ use lemmy_db_schema::{
   source::community::{Community, CommunityForm},
 };
 use lemmy_utils::{
+  settings::structs::Settings,
   utils::{check_slurs, check_slurs_opt, convert_datetime, markdown_to_html},
   LemmyError,
 };
@@ -74,6 +75,7 @@ impl Group {
   pub(crate) async fn from_apub_to_form(
     group: &Group,
     expected_domain: &Url,
+    settings: &Settings,
   ) -> Result<CommunityForm, LemmyError> {
     let actor_id = Some(group.id(expected_domain)?.clone().into());
     let name = group.preferred_username.clone();
@@ -81,9 +83,10 @@ impl Group {
     let description = group.source.clone().map(|s| s.content);
     let shared_inbox = group.endpoints.shared_inbox.clone().map(|s| s.into());
 
-    check_slurs(&name)?;
-    check_slurs(&title)?;
-    check_slurs_opt(&description)?;
+    let slur_regex = &settings.slur_regex();
+    check_slurs(&name, slur_regex)?;
+    check_slurs(&title, slur_regex)?;
+    check_slurs_opt(&description, slur_regex)?;
 
     Ok(CommunityForm {
       name,
@@ -175,7 +178,7 @@ impl FromApub for Community {
     expected_domain: &Url,
     request_counter: &mut i32,
   ) -> Result<Community, LemmyError> {
-    let form = Group::from_apub_to_form(group, expected_domain).await?;
+    let form = Group::from_apub_to_form(group, expected_domain, &context.settings()).await?;
 
     let community = blocking(context.pool(), move |conn| Community::upsert(conn, &form)).await??;
     update_community_mods(group, &community, context, request_counter).await?;
index 04af848ffd5c4f5779e6f0b26eb0dbcb951b4609..5bf7a589744ca525e1068fb6861238c8f2913b6e 100644 (file)
@@ -150,10 +150,12 @@ impl FromApub for DbPerson {
       UserTypes::Service => true,
     };
 
-    check_slurs(&name)?;
-    check_slurs_opt(&display_name)?;
-    check_slurs_opt(&bio)?;
-    check_is_apub_id_valid(&person.id, false)?;
+    let slur_regex = &context.settings().slur_regex();
+    check_slurs(&name, slur_regex)?;
+    check_slurs_opt(&display_name, slur_regex)?;
+    check_slurs_opt(&bio, slur_regex)?;
+
+    check_is_apub_id_valid(&person.id, false, &context.settings())?;
 
     let person_form = PersonForm {
       name,
index 341b428b6def03e257da0d34e880a6917d912896..451ce0554ea1826bf8e91c136eb3c717dd1c188f 100644 (file)
@@ -100,7 +100,7 @@ impl Page {
   ) -> Result<(), LemmyError> {
     let community = extract_community(&self.to, context, request_counter).await?;
 
-    check_slurs(&self.name)?;
+    check_slurs(&self.name, &context.settings().slur_regex())?;
     verify_domains_match(self.attributed_to.inner(), &self.id)?;
     verify_person_in_community(
       &self.attributed_to,
@@ -191,7 +191,7 @@ impl FromApub for Post {
 
     let thumbnail_url: Option<Url> = page.image.clone().map(|i| i.url);
     let (metadata_res, pictrs_thumbnail) = if let Some(url) = &page.url {
-      fetch_site_data(context.client(), Some(url)).await
+      fetch_site_data(context.client(), &context.settings(), Some(url)).await
     } else {
       (None, thumbnail_url)
     };
@@ -199,7 +199,10 @@ impl FromApub for Post {
       .map(|u| (u.title, u.description, u.html))
       .unwrap_or((None, None, None));
 
-    let body_slurs_removed = page.source.as_ref().map(|s| remove_slurs(&s.content));
+    let body_slurs_removed = page
+      .source
+      .as_ref()
+      .map(|s| remove_slurs(&s.content, &context.settings().slur_regex()));
     let form = PostForm {
       name: page.name.clone(),
       url: page.url.clone().map(|u| u.into()),
index ebd49ea67b161d71b64177b7d50ef8d5758d9440..a5395d099d5f657e3016f9107407784e015b56c2 100644 (file)
@@ -1,7 +1,6 @@
 use anyhow::anyhow;
 use lemmy_utils::{
   request::{retry, RecvError},
-  settings::structs::Settings,
   LemmyError,
 };
 use log::debug;
@@ -38,6 +37,7 @@ pub async fn webfinger_resolve_actor(
   domain: &str,
   webfinger_type: WebfingerType,
   client: &Client,
+  protocol_string: &str,
 ) -> Result<Url, LemmyError> {
   let webfinger_type = match webfinger_type {
     WebfingerType::Person => "acct",
@@ -45,11 +45,7 @@ pub async fn webfinger_resolve_actor(
   };
   let fetch_url = format!(
     "{}://{}/.well-known/webfinger?resource={}:{}@{}",
-    Settings::get().get_protocol_string(),
-    domain,
-    webfinger_type,
-    name,
-    domain
+    protocol_string, domain, webfinger_type, name, domain
   );
   debug!("Fetching webfinger url: {}", &fetch_url);
 
index eac0d7eb4905b39e5897d042ddcc78b9fdad9b2a..6181549fea88c7f2a89e4dddb297344fd23da23a 100644 (file)
@@ -1,36 +1,18 @@
 use diesel::{result::Error, *};
 use lemmy_db_schema::source::secret::Secret;
-use lemmy_utils::settings::structs::Settings;
-use std::sync::RwLock;
 
-use crate::get_database_url_from_env;
-
-lazy_static! {
-  static ref SECRET: RwLock<Secret> = RwLock::new(init().expect("Failed to load secrets from DB."));
-}
-
-pub trait SecretSingleton {
-  fn get() -> Secret;
+pub trait Secret_ {
+  fn init(conn: &PgConnection) -> Result<Secret, Error>;
 }
 
-impl SecretSingleton for Secret {
-  /// Returns the Secret as a struct
-  fn get() -> Self {
-    SECRET.read().expect("read secrets").to_owned()
+impl Secret_ for Secret {
+  /// Initialize the Secrets from the DB.
+  /// Warning: You should only call this once.
+  fn init(conn: &PgConnection) -> Result<Secret, Error> {
+    read_secrets(conn)
   }
 }
 
-/// Reads the secrets from the DB
-fn init() -> Result<Secret, Error> {
-  let db_url = match get_database_url_from_env() {
-    Ok(url) => url,
-    Err(_) => Settings::get().get_database_url(),
-  };
-
-  let conn = PgConnection::establish(&db_url).expect("Couldn't get DB connection for Secrets.");
-  read_secrets(&conn)
-}
-
 fn read_secrets(conn: &PgConnection) -> Result<Secret, Error> {
   use lemmy_db_schema::schema::secret::dsl::*;
   secret.first::<Secret>(conn)
index 5cf2f1759d609c3f881dd6254f1a12491de2a1fd..66e23ee3e94b891be97fd07120a50e58cfcaf668 100644 (file)
@@ -4,13 +4,13 @@ use chrono::{DateTime, NaiveDateTime, Utc};
 use diesel::PgConnection;
 use lemmy_api_common::blocking;
 use lemmy_db_queries::{
-  source::{community::Community_, person::Person_, secret::SecretSingleton},
+  source::{community::Community_, person::Person_},
   Crud,
   ListingType,
   SortType,
 };
 use lemmy_db_schema::{
-  source::{community::Community, local_user::LocalUser, person::Person, secret::Secret},
+  source::{community::Community, local_user::LocalUser, person::Person},
   LocalUserId,
 };
 use lemmy_db_views::{
@@ -19,12 +19,7 @@ use lemmy_db_views::{
   site_view::SiteView,
 };
 use lemmy_db_views_actor::person_mention_view::{PersonMentionQueryBuilder, PersonMentionView};
-use lemmy_utils::{
-  claims::Claims,
-  settings::structs::Settings,
-  utils::markdown_to_html,
-  LemmyError,
-};
+use lemmy_utils::{claims::Claims, utils::markdown_to_html, LemmyError};
 use lemmy_websocket::LemmyContext;
 use rss::{
   extension::dublincore::DublinCoreExtensionBuilder,
@@ -98,7 +93,7 @@ async fn get_feed_data(
   })
   .await??;
 
-  let items = create_post_items(posts)?;
+  let items = create_post_items(posts, &context.settings().get_protocol_and_hostname())?;
 
   let mut channel_builder = ChannelBuilder::default();
   channel_builder
@@ -108,7 +103,7 @@ async fn get_feed_data(
       site_view.site.name,
       listing_type.to_string()
     ))
-    .link(Settings::get().get_protocol_and_hostname())
+    .link(context.settings().get_protocol_and_hostname())
     .items(items);
 
   if let Some(site_desc) = site_view.site.description {
@@ -141,11 +136,20 @@ async fn get_feed(
     _ => return Err(ErrorBadRequest(LemmyError::from(anyhow!("wrong_type")))),
   };
 
+  let jwt_secret = context.secret().jwt_secret.to_owned();
+  let protocol_and_hostname = context.settings().get_protocol_and_hostname();
+
   let builder = blocking(context.pool(), move |conn| match request_type {
-    RequestType::User => get_feed_user(conn, &sort_type, param),
-    RequestType::Community => get_feed_community(conn, &sort_type, param),
-    RequestType::Front => get_feed_front(conn, &sort_type, param),
-    RequestType::Inbox => get_feed_inbox(conn, param),
+    RequestType::User => get_feed_user(conn, &sort_type, &param, &protocol_and_hostname),
+    RequestType::Community => get_feed_community(conn, &sort_type, &param, &protocol_and_hostname),
+    RequestType::Front => get_feed_front(
+      conn,
+      &jwt_secret,
+      &sort_type,
+      &param,
+      &protocol_and_hostname,
+    ),
+    RequestType::Inbox => get_feed_inbox(conn, &jwt_secret, &param, &protocol_and_hostname),
   })
   .await?
   .map_err(ErrorBadRequest)?;
@@ -170,10 +174,11 @@ fn get_sort_type(info: web::Query<Params>) -> Result<SortType, ParseError> {
 fn get_feed_user(
   conn: &PgConnection,
   sort_type: &SortType,
-  user_name: String,
+  user_name: &str,
+  protocol_and_hostname: &str,
 ) -> Result<ChannelBuilder, LemmyError> {
   let site_view = SiteView::read(conn)?;
-  let person = Person::find_by_name(conn, &user_name)?;
+  let person = Person::find_by_name(conn, user_name)?;
 
   let posts = PostQueryBuilder::create(conn)
     .listing_type(ListingType::All)
@@ -181,7 +186,7 @@ fn get_feed_user(
     .creator_id(person.id)
     .list()?;
 
-  let items = create_post_items(posts)?;
+  let items = create_post_items(posts, protocol_and_hostname)?;
 
   let mut channel_builder = ChannelBuilder::default();
   channel_builder
@@ -196,10 +201,11 @@ fn get_feed_user(
 fn get_feed_community(
   conn: &PgConnection,
   sort_type: &SortType,
-  community_name: String,
+  community_name: &str,
+  protocol_and_hostname: &str,
 ) -> Result<ChannelBuilder, LemmyError> {
   let site_view = SiteView::read(conn)?;
-  let community = Community::read_from_name(conn, &community_name)?;
+  let community = Community::read_from_name(conn, community_name)?;
 
   let posts = PostQueryBuilder::create(conn)
     .listing_type(ListingType::All)
@@ -207,7 +213,7 @@ fn get_feed_community(
     .community_id(community.id)
     .list()?;
 
-  let items = create_post_items(posts)?;
+  let items = create_post_items(posts, protocol_and_hostname)?;
 
   let mut channel_builder = ChannelBuilder::default();
   channel_builder
@@ -225,12 +231,13 @@ fn get_feed_community(
 
 fn get_feed_front(
   conn: &PgConnection,
+  jwt_secret: &str,
   sort_type: &SortType,
-  jwt: String,
+  jwt: &str,
+  protocol_and_hostname: &str,
 ) -> Result<ChannelBuilder, LemmyError> {
   let site_view = SiteView::read(conn)?;
-  let jwt_secret = Secret::get().jwt_secret;
-  let local_user_id = LocalUserId(Claims::decode(&jwt, &jwt_secret)?.claims.sub);
+  let local_user_id = LocalUserId(Claims::decode(jwt, jwt_secret)?.claims.sub);
   let local_user = LocalUser::read(conn, local_user_id)?;
 
   let posts = PostQueryBuilder::create(conn)
@@ -241,13 +248,13 @@ fn get_feed_front(
     .sort(*sort_type)
     .list()?;
 
-  let items = create_post_items(posts)?;
+  let items = create_post_items(posts, protocol_and_hostname)?;
 
   let mut channel_builder = ChannelBuilder::default();
   channel_builder
     .namespaces(RSS_NAMESPACE.to_owned())
     .title(&format!("{} - Subscribed", site_view.site.name))
-    .link(Settings::get().get_protocol_and_hostname())
+    .link(protocol_and_hostname)
     .items(items);
 
   if let Some(site_desc) = site_view.site.description {
@@ -257,10 +264,14 @@ fn get_feed_front(
   Ok(channel_builder)
 }
 
-fn get_feed_inbox(conn: &PgConnection, jwt: String) -> Result<ChannelBuilder, LemmyError> {
+fn get_feed_inbox(
+  conn: &PgConnection,
+  jwt_secret: &str,
+  jwt: &str,
+  protocol_and_hostname: &str,
+) -> Result<ChannelBuilder, LemmyError> {
   let site_view = SiteView::read(conn)?;
-  let jwt_secret = Secret::get().jwt_secret;
-  let local_user_id = LocalUserId(Claims::decode(&jwt, &jwt_secret)?.claims.sub);
+  let local_user_id = LocalUserId(Claims::decode(jwt, jwt_secret)?.claims.sub);
   let local_user = LocalUser::read(conn, local_user_id)?;
   let person_id = local_user.person_id;
   let show_bot_accounts = local_user.show_bot_accounts;
@@ -280,16 +291,13 @@ fn get_feed_inbox(conn: &PgConnection, jwt: String) -> Result<ChannelBuilder, Le
     .sort(sort)
     .list()?;
 
-  let items = create_reply_and_mention_items(replies, mentions)?;
+  let items = create_reply_and_mention_items(replies, mentions, protocol_and_hostname)?;
 
   let mut channel_builder = ChannelBuilder::default();
   channel_builder
     .namespaces(RSS_NAMESPACE.to_owned())
     .title(&format!("{} - Inbox", site_view.site.name))
-    .link(format!(
-      "{}/inbox",
-      Settings::get().get_protocol_and_hostname()
-    ))
+    .link(format!("{}/inbox", protocol_and_hostname,))
     .items(items);
 
   if let Some(site_desc) = site_view.site.description {
@@ -302,21 +310,21 @@ fn get_feed_inbox(conn: &PgConnection, jwt: String) -> Result<ChannelBuilder, Le
 fn create_reply_and_mention_items(
   replies: Vec<CommentView>,
   mentions: Vec<PersonMentionView>,
+  protocol_and_hostname: &str,
 ) -> Result<Vec<Item>, LemmyError> {
   let mut reply_items: Vec<Item> = replies
     .iter()
     .map(|r| {
       let reply_url = format!(
         "{}/post/{}/comment/{}",
-        Settings::get().get_protocol_and_hostname(),
-        r.post.id,
-        r.comment.id
+        protocol_and_hostname, r.post.id, r.comment.id
       );
       build_item(
         &r.creator.name,
         &r.comment.published,
         &reply_url,
         &r.comment.content,
+        protocol_and_hostname,
       )
     })
     .collect::<Result<Vec<Item>, LemmyError>>()?;
@@ -326,15 +334,14 @@ fn create_reply_and_mention_items(
     .map(|m| {
       let mention_url = format!(
         "{}/post/{}/comment/{}",
-        Settings::get().get_protocol_and_hostname(),
-        m.post.id,
-        m.comment.id
+        protocol_and_hostname, m.post.id, m.comment.id
       );
       build_item(
         &m.creator.name,
         &m.comment.published,
         &mention_url,
         &m.comment.content,
+        protocol_and_hostname,
       )
     })
     .collect::<Result<Vec<Item>, LemmyError>>()?;
@@ -348,14 +355,11 @@ fn build_item(
   published: &NaiveDateTime,
   url: &str,
   content: &str,
+  protocol_and_hostname: &str,
 ) -> Result<Item, LemmyError> {
   let mut i = ItemBuilder::default();
   i.title(format!("Reply from {}", creator_name));
-  let author_url = format!(
-    "{}/u/{}",
-    Settings::get().get_protocol_and_hostname(),
-    creator_name
-  );
+  let author_url = format!("{}/u/{}", protocol_and_hostname, creator_name);
   i.author(format!(
     "/u/{} <a href=\"{}\">(link)</a>",
     creator_name, author_url
@@ -376,7 +380,10 @@ fn build_item(
   Ok(i.build().map_err(|e| anyhow!(e))?)
 }
 
-fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
+fn create_post_items(
+  posts: Vec<PostView>,
+  protocol_and_hostname: &str,
+) -> Result<Vec<Item>, LemmyError> {
   let mut items: Vec<Item> = Vec::new();
 
   for p in posts {
@@ -390,11 +397,7 @@ fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
     let dt = DateTime::<Utc>::from_utc(p.post.published, Utc);
     i.pub_date(dt.to_rfc2822());
 
-    let post_url = format!(
-      "{}/post/{}",
-      Settings::get().get_protocol_and_hostname(),
-      p.post.id
-    );
+    let post_url = format!("{}/post/{}", protocol_and_hostname, p.post.id);
     i.link(post_url.to_owned());
     i.comments(post_url.to_owned());
     let guid = GuidBuilder::default()
@@ -404,11 +407,7 @@ fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
       .map_err(|e| anyhow!(e))?;
     i.guid(guid);
 
-    let community_url = format!(
-      "{}/c/{}",
-      Settings::get().get_protocol_and_hostname(),
-      p.community.name
-    );
+    let community_url = format!("{}/c/{}", protocol_and_hostname, p.community.name);
 
     // TODO add images
     let mut description = format!("submitted by <a href=\"{}\">{}</a> to <a href=\"{}\">{}</a><br>{} points | <a href=\"{}\">{} comments</a>",
index 230841d440bdee44e41e51ec4cde168972c6fe4f..e5e33489d40e413728b94fd65da1cae0103755cf 100644 (file)
@@ -2,9 +2,8 @@ use actix_http::http::header::ACCEPT_ENCODING;
 use actix_web::{body::BodyStream, http::StatusCode, web::Data, *};
 use anyhow::anyhow;
 use awc::Client;
-use lemmy_db_queries::source::secret::SecretSingleton;
-use lemmy_db_schema::source::secret::Secret;
-use lemmy_utils::{claims::Claims, rate_limit::RateLimit, settings::structs::Settings, LemmyError};
+use lemmy_utils::{claims::Claims, rate_limit::RateLimit, LemmyError};
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use std::time::Duration;
 
@@ -48,18 +47,21 @@ async fn upload(
   req: HttpRequest,
   body: web::Payload,
   client: web::Data<Client>,
+  context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse, Error> {
   // TODO: check rate limit here
   let jwt = req
     .cookie("jwt")
     .expect("No auth header for picture upload");
 
-  let jwt_secret = Secret::get().jwt_secret;
-  if Claims::decode(jwt.value(), &jwt_secret).is_err() {
+  if Claims::decode(jwt.value(), &context.secret().jwt_secret).is_err() {
     return Ok(HttpResponse::Unauthorized().finish());
   };
 
-  let mut client_req = client.request_from(format!("{}/image", pictrs_url()?), req.head());
+  let mut client_req = client.request_from(
+    format!("{}/image", pictrs_url(context.settings().pictrs_url)?),
+    req.head(),
+  );
   // remove content-encoding header so that pictrs doesnt send gzipped response
   client_req.headers_mut().remove(ACCEPT_ENCODING);
 
@@ -82,17 +84,28 @@ async fn full_res(
   web::Query(params): web::Query<PictrsParams>,
   req: HttpRequest,
   client: web::Data<Client>,
+  context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse, Error> {
   let name = &filename.into_inner();
 
   // If there are no query params, the URL is original
+  let pictrs_url_settings = context.settings().pictrs_url;
   let url = if params.format.is_none() && params.thumbnail.is_none() {
-    format!("{}/image/original/{}", pictrs_url()?, name,)
+    format!(
+      "{}/image/original/{}",
+      pictrs_url(pictrs_url_settings)?,
+      name,
+    )
   } else {
     // Use jpg as a default when none is given
     let format = params.format.unwrap_or_else(|| "jpg".to_string());
 
-    let mut url = format!("{}/image/process.{}?src={}", pictrs_url()?, format, name,);
+    let mut url = format!(
+      "{}/image/process.{}?src={}",
+      pictrs_url(pictrs_url_settings)?,
+      format,
+      name,
+    );
 
     if let Some(size) = params.thumbnail {
       url = format!("{}&thumbnail={}", url, size,);
@@ -138,10 +151,16 @@ async fn delete(
   components: web::Path<(String, String)>,
   req: HttpRequest,
   client: web::Data<Client>,
+  context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse, Error> {
   let (token, file) = components.into_inner();
 
-  let url = format!("{}/image/delete/{}/{}", pictrs_url()?, &token, &file);
+  let url = format!(
+    "{}/image/delete/{}/{}",
+    pictrs_url(context.settings().pictrs_url)?,
+    &token,
+    &file
+  );
 
   let mut client_req = client.request_from(url, req.head());
   client_req.headers_mut().remove(ACCEPT_ENCODING);
@@ -159,8 +178,6 @@ async fn delete(
   Ok(HttpResponse::build(res.status()).body(BodyStream::new(res)))
 }
 
-fn pictrs_url() -> Result<String, LemmyError> {
-  Settings::get()
-    .pictrs_url
-    .ok_or_else(|| anyhow!("images_disabled").into())
+fn pictrs_url(pictrs_url: Option<String>) -> Result<String, LemmyError> {
+  pictrs_url.ok_or_else(|| anyhow!("images_disabled").into())
 }
index 86d625900db52599da54e6533af0b3370046794f..9e327efaef56536cb0cbb4f185f40e835246dffe 100644 (file)
@@ -2,7 +2,7 @@ use actix_web::{body::Body, error::ErrorBadRequest, *};
 use anyhow::anyhow;
 use lemmy_api_common::blocking;
 use lemmy_db_views::site_view::SiteView;
-use lemmy_utils::{settings::structs::Settings, version, LemmyError};
+use lemmy_utils::{version, LemmyError};
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use url::Url;
@@ -13,13 +13,15 @@ pub fn config(cfg: &mut web::ServiceConfig) {
     .route("/.well-known/nodeinfo", web::get().to(node_info_well_known));
 }
 
-async fn node_info_well_known() -> Result<HttpResponse<Body>, LemmyError> {
+async fn node_info_well_known(
+  context: web::Data<LemmyContext>,
+) -> Result<HttpResponse<Body>, LemmyError> {
   let node_info = NodeInfoWellKnown {
     links: NodeInfoWellKnownLinks {
       rel: Url::parse("http://nodeinfo.diaspora.software/ns/schema/2.0")?,
       href: Url::parse(&format!(
         "{}/nodeinfo/2.0.json",
-        Settings::get().get_protocol_and_hostname()
+        &context.settings().get_protocol_and_hostname(),
       ))?,
     },
   };
@@ -31,7 +33,7 @@ async fn node_info(context: web::Data<LemmyContext>) -> Result<HttpResponse, Err
     .await?
     .map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?;
 
-  let protocols = if Settings::get().federation.enabled {
+  let protocols = if context.settings().federation.enabled {
     vec!["activitypub".to_string()]
   } else {
     vec![]
index 6773218877a22f7c12230a6cc26498bf12a1e31c..798636da5bcb30e812e721064f800eb4451c27c6 100644 (file)
@@ -4,12 +4,7 @@ use lemmy_api_common::blocking;
 use lemmy_apub_lib::webfinger::{WebfingerLink, WebfingerResponse};
 use lemmy_db_queries::source::{community::Community_, person::Person_};
 use lemmy_db_schema::source::{community::Community, person::Person};
-use lemmy_utils::{
-  settings::structs::Settings,
-  LemmyError,
-  WEBFINGER_COMMUNITY_REGEX,
-  WEBFINGER_USERNAME_REGEX,
-};
+use lemmy_utils::{settings::structs::Settings, LemmyError};
 use lemmy_websocket::LemmyContext;
 use serde::Deserialize;
 
@@ -18,8 +13,8 @@ struct Params {
   resource: String,
 }
 
-pub fn config(cfg: &mut web::ServiceConfig) {
-  if Settings::get().federation.enabled {
+pub fn config(cfg: &mut web::ServiceConfig, settings: &Settings) {
+  if settings.federation.enabled {
     cfg.route(
       ".well-known/webfinger",
       web::get().to(get_webfinger_response),
@@ -37,12 +32,16 @@ async fn get_webfinger_response(
   info: Query<Params>,
   context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse, Error> {
-  let community_regex_parsed = WEBFINGER_COMMUNITY_REGEX
+  let community_regex_parsed = context
+    .settings()
+    .webfinger_community_regex()
     .captures(&info.resource)
     .map(|c| c.get(1))
     .flatten();
 
-  let username_regex_parsed = WEBFINGER_USERNAME_REGEX
+  let username_regex_parsed = context
+    .settings()
+    .webfinger_username_regex()
     .captures(&info.resource)
     .map(|c| c.get(1))
     .flatten();
index 2b6ce9854d65fa5ced7ee49c89008e2f2200db00..d68b4119d3f7ab2cc794b7f238004c40c7960ca3 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{settings::structs::Settings, LemmyError};
+use crate::LemmyError;
 use chrono::Utc;
 use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation};
 use serde::{Deserialize, Serialize};
@@ -24,10 +24,10 @@ impl Claims {
     Ok(decode::<Claims>(jwt, &key, &v)?)
   }
 
-  pub fn jwt(local_user_id: i32, jwt_secret: &str) -> Result<Jwt, LemmyError> {
+  pub fn jwt(local_user_id: i32, jwt_secret: &str, hostname: &str) -> Result<Jwt, LemmyError> {
     let my_claims = Claims {
       sub: local_user_id,
-      iss: Settings::get().hostname,
+      iss: hostname.to_string(),
       iat: Utc::now().timestamp(),
     };
 
index 3e5307421b40b54f3a8cf93796963b2eb737423e..77f83d020bcec4ae788c377664a1dc2a604f6b1b 100644 (file)
@@ -18,9 +18,10 @@ pub fn send_email(
   to_email: &str,
   to_username: &str,
   html: &str,
+  settings: &Settings,
 ) -> Result<(), String> {
-  let email_config = Settings::get().email.ok_or("no_email_setup")?;
-  let domain = Settings::get().hostname;
+  let email_config = settings.email.to_owned().ok_or("no_email_setup")?;
+  let domain = settings.hostname.to_owned();
 
   let (smtp_server, smtp_port) = {
     let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>();
index f1093fd585f2f032607ee74d01e44c600f105a14..ad539f8b006c32d78d9955270a8c8ed5ee369c03 100644 (file)
@@ -17,9 +17,8 @@ mod test;
 pub mod utils;
 pub mod version;
 
-use crate::settings::structs::Settings;
 use http::StatusCode;
-use regex::Regex;
+
 use std::fmt;
 use thiserror::Error;
 
@@ -88,16 +87,3 @@ impl actix_web::error::ResponseError for LemmyError {
     }
   }
 }
-
-lazy_static! {
-  pub static ref WEBFINGER_COMMUNITY_REGEX: Regex = Regex::new(&format!(
-    "^group:([a-z0-9_]{{3,}})@{}$",
-    Settings::get().hostname
-  ))
-  .expect("compile webfinger regex");
-  pub static ref WEBFINGER_USERNAME_REGEX: Regex = Regex::new(&format!(
-    "^acct:([a-z0-9_]{{3,}})@{}$",
-    Settings::get().hostname
-  ))
-  .expect("compile webfinger regex");
-}
index ca7f124cd0ab11880efe33f786a9032559e911be..c1a4627c1d9f8ca50913d00ce67f08b90e7b55ec 100644 (file)
@@ -1,9 +1,4 @@
-use crate::{
-  settings::structs::{RateLimitConfig, Settings},
-  utils::get_ip,
-  IpAddr,
-  LemmyError,
-};
+use crate::{settings::structs::RateLimitConfig, utils::get_ip, IpAddr, LemmyError};
 use actix_web::dev::{Service, ServiceRequest, ServiceResponse, Transform};
 use futures::future::{ok, Ready};
 use rate_limiter::{RateLimitType, RateLimiter};
@@ -22,11 +17,13 @@ pub struct RateLimit {
   // it might be reasonable to use a std::sync::Mutex here, since we don't need to lock this
   // across await points
   pub rate_limiter: Arc<Mutex<RateLimiter>>,
+  pub rate_limit_config: RateLimitConfig,
 }
 
 #[derive(Debug, Clone)]
 pub struct RateLimited {
   rate_limiter: Arc<Mutex<RateLimiter>>,
+  rate_limit_config: RateLimitConfig,
   type_: RateLimitType,
 }
 
@@ -55,6 +52,7 @@ impl RateLimit {
   fn kind(&self, type_: RateLimitType) -> RateLimited {
     RateLimited {
       rate_limiter: self.rate_limiter.clone(),
+      rate_limit_config: self.rate_limit_config.clone(),
       type_,
     }
   }
@@ -71,7 +69,7 @@ impl RateLimited {
   {
     // Does not need to be blocking because the RwLock in settings never held across await points,
     // and the operation here locks only long enough to clone
-    let rate_limit: RateLimitConfig = Settings::get().rate_limit.unwrap_or_default();
+    let rate_limit = self.rate_limit_config;
 
     // before
     {
index f1655710e202533245382a37c45cb35a6c5d5bdc..f143b1781e9510021478f05e3f085be101068a15 100644 (file)
@@ -120,9 +120,10 @@ pub(crate) struct PictrsFile {
 
 pub(crate) async fn fetch_pictrs(
   client: &Client,
+  settings: &Settings,
   image_url: &Url,
 ) -> Result<PictrsResponse, LemmyError> {
-  if let Some(pictrs_url) = Settings::get().pictrs_url {
+  if let Some(pictrs_url) = settings.pictrs_url.to_owned() {
     is_image_content_type(client, image_url).await?;
 
     let fetch_url = format!(
@@ -152,6 +153,7 @@ pub(crate) async fn fetch_pictrs(
 /// Returns the SiteMetadata, and a Pictrs URL, if there is a picture associated
 pub async fn fetch_site_data(
   client: &Client,
+  settings: &Settings,
   url: Option<&Url>,
 ) -> (Option<SiteMetadata>, Option<Url>) {
   match &url {
@@ -166,16 +168,16 @@ pub async fn fetch_site_data(
         Some(metadata_res) => match &metadata_res.image {
           // Metadata, with image
           // Try to generate a small thumbnail if there's a full sized one from post-links
-          Some(metadata_image) => fetch_pictrs(client, metadata_image)
+          Some(metadata_image) => fetch_pictrs(client, settings, metadata_image)
             .await
             .map(|r| r.files[0].file.to_owned()),
           // Metadata, but no image
-          None => fetch_pictrs(client, url)
+          None => fetch_pictrs(client, settings, url)
             .await
             .map(|r| r.files[0].file.to_owned()),
         },
         // No metadata, try to fetch the URL as an image
-        None => fetch_pictrs(client, url)
+        None => fetch_pictrs(client, settings, url)
           .await
           .map(|r| r.files[0].file.to_owned()),
       };
@@ -185,7 +187,7 @@ pub async fn fetch_site_data(
         .map(|p| {
           Url::parse(&format!(
             "{}/pictrs/image/{}",
-            Settings::get().get_protocol_and_hostname(),
+            settings.get_protocol_and_hostname(),
             p
           ))
           .ok()
index d4776326f698d50cce04c4378cb14122519b2dca..d47cc5b4b1b07ed1a9272d8856da2f2b52832433 100644 (file)
@@ -1,6 +1,7 @@
 use crate::{location_info, settings::structs::Settings, LemmyError};
 use anyhow::{anyhow, Context};
 use deser_hjson::from_str;
+use regex::{Regex, RegexBuilder};
 use std::{env, fs, io::Error, sync::RwLock};
 
 pub mod structs;
@@ -17,14 +18,25 @@ impl Settings {
   ///
   /// Note: The env var `LEMMY_DATABASE_URL` is parsed in
   /// `lemmy_db_queries/src/lib.rs::get_database_url_from_env()`
-  fn init() -> Result<Self, LemmyError> {
+  /// Warning: Only call this once.
+  pub fn init() -> Result<Self, LemmyError> {
     // Read the config file
-    let config = from_str::<Settings>(&Self::read_config_file()?)?;
+    let mut config = from_str::<Settings>(&Self::read_config_file()?)?;
 
     if config.hostname == "unset" {
       return Err(anyhow!("Hostname variable is not set!").into());
     }
 
+    // Initialize the regexes
+    config.webfinger_community_regex = Some(
+      Regex::new(&format!("^group:([a-z0-9_]{{3,}})@{}$", config.hostname))
+        .expect("compile webfinger regex"),
+    );
+    config.webfinger_username_regex = Some(
+      Regex::new(&format!("^acct:([a-z0-9_]{{3,}})@{}$", config.hostname))
+        .expect("compile webfinger regex"),
+    );
+
     Ok(config)
   }
 
@@ -92,4 +104,30 @@ impl Settings {
 
     Ok(Self::read_config_file()?)
   }
+
+  pub fn webfinger_community_regex(&self) -> Regex {
+    self
+      .webfinger_community_regex
+      .to_owned()
+      .expect("compile webfinger regex")
+  }
+
+  pub fn webfinger_username_regex(&self) -> Regex {
+    self
+      .webfinger_username_regex
+      .to_owned()
+      .expect("compile webfinger regex")
+  }
+
+  pub fn slur_regex(&self) -> Regex {
+    let mut slurs = r"(fag(g|got|tard)?\b|cock\s?sucker(s|ing)?|ni((g{2,}|q)+|[gq]{2,})[e3r]+(s|z)?|mudslime?s?|kikes?|\bspi(c|k)s?\b|\bchinks?|gooks?|bitch(es|ing|y)?|whor(es?|ing)|\btr(a|@)nn?(y|ies?)|\b(b|re|r)tard(ed)?s?)".to_string();
+    if let Some(additional_slurs) = &self.additional_slurs {
+      slurs.push('|');
+      slurs.push_str(additional_slurs);
+    };
+    RegexBuilder::new(&slurs)
+      .case_insensitive(true)
+      .build()
+      .expect("compile regex")
+  }
 }
index 9ba8a5f9491b0741a219d44138a6d942fff6548b..29334934863d085d2df5c076b2db4e94510a4918 100644 (file)
@@ -1,3 +1,4 @@
+use regex::Regex;
 use serde::Deserialize;
 use std::net::{IpAddr, Ipv4Addr};
 
@@ -30,6 +31,12 @@ pub struct Settings {
   pub additional_slurs: Option<String>,
   #[default(20)]
   pub actor_name_max_length: usize,
+  #[default(None)]
+  #[serde(skip)]
+  pub webfinger_community_regex: Option<Regex>,
+  #[default(None)]
+  #[serde(skip)]
+  pub webfinger_username_regex: Option<Regex>,
 }
 
 #[derive(Debug, Deserialize, Clone, SmartDefault)]
index 33bf38700ca9904a0598a96c25895e4c09af415f..a59d04129fbea89ca2e590123b9060069ee08300 100644 (file)
@@ -1,12 +1,15 @@
-use crate::utils::{
-  is_valid_actor_name,
-  is_valid_display_name,
-  is_valid_matrix_id,
-  is_valid_post_title,
-  remove_slurs,
-  scrape_text_for_mentions,
-  slur_check,
-  slurs_vec_to_str,
+use crate::{
+  settings::structs::Settings,
+  utils::{
+    is_valid_actor_name,
+    is_valid_display_name,
+    is_valid_matrix_id,
+    is_valid_post_title,
+    remove_slurs,
+    scrape_text_for_mentions,
+    slur_check,
+    slurs_vec_to_str,
+  },
 };
 
 #[test]
@@ -21,23 +24,28 @@ fn test_mentions_regex() {
 
 #[test]
 fn test_valid_actor_name() {
-  assert!(is_valid_actor_name("Hello_98"));
-  assert!(is_valid_actor_name("ten"));
-  assert!(!is_valid_actor_name("Hello-98"));
-  assert!(!is_valid_actor_name("a"));
-  assert!(!is_valid_actor_name(""));
+  let actor_name_max_length = Settings::init().unwrap().actor_name_max_length;
+  assert!(is_valid_actor_name("Hello_98", actor_name_max_length));
+  assert!(is_valid_actor_name("ten", actor_name_max_length));
+  assert!(!is_valid_actor_name("Hello-98", actor_name_max_length));
+  assert!(!is_valid_actor_name("a", actor_name_max_length));
+  assert!(!is_valid_actor_name("", actor_name_max_length));
 }
 
 #[test]
 fn test_valid_display_name() {
-  assert!(is_valid_display_name("hello @there"));
-  assert!(!is_valid_display_name("@hello there"));
+  let actor_name_max_length = Settings::init().unwrap().actor_name_max_length;
+  assert!(is_valid_display_name("hello @there", actor_name_max_length));
+  assert!(!is_valid_display_name(
+    "@hello there",
+    actor_name_max_length
+  ));
 
   // Make sure zero-space with an @ doesn't work
-  assert!(!is_valid_display_name(&format!(
-    "{}@my name is",
-    '\u{200b}'
-  )));
+  assert!(!is_valid_display_name(
+    &format!("{}@my name is", '\u{200b}'),
+    actor_name_max_length
+  ));
 }
 
 #[test]
@@ -57,11 +65,12 @@ fn test_valid_matrix_id() {
 
 #[test]
 fn test_slur_filter() {
+  let slur_regex = Settings::init().unwrap().slur_regex();
   let test =
       "faggot test kike tranny cocksucker retardeds. Capitalized Niggerz. This is a bunch of other safe text.";
   let slur_free = "No slurs here";
   assert_eq!(
-      remove_slurs(test),
+      remove_slurs(test, &slur_regex),
       "*removed* test *removed* *removed* *removed* *removed*. Capitalized *removed*. This is a bunch of other safe text."
         .to_string()
     );
@@ -76,9 +85,9 @@ fn test_slur_filter() {
   ];
   let has_slurs_err_str = "No slurs - Niggerz, cocksucker, faggot, kike, retardeds, tranny";
 
-  assert_eq!(slur_check(test), Err(has_slurs_vec));
-  assert_eq!(slur_check(slur_free), Ok(()));
-  if let Err(slur_vec) = slur_check(test) {
+  assert_eq!(slur_check(test, &slur_regex), Err(has_slurs_vec));
+  assert_eq!(slur_check(slur_free, &slur_regex), Ok(()));
+  if let Err(slur_vec) = slur_check(test, &slur_regex) {
     assert_eq!(&slurs_vec_to_str(slur_vec), has_slurs_err_str);
   }
 }
index 0fb1f788882727a45f4ddd4fb4d2544b63b1a573..97384fc2f19d0076706209bf4ce3e5b40b213901 100644 (file)
@@ -1,22 +1,13 @@
-use crate::{settings::structs::Settings, ApiError, IpAddr};
+use crate::{ApiError, IpAddr};
 use actix_web::dev::ConnectionInfo;
 use chrono::{DateTime, FixedOffset, NaiveDateTime};
 use itertools::Itertools;
 use rand::{distributions::Alphanumeric, thread_rng, Rng};
-use regex::{Regex, RegexBuilder};
+use regex::Regex;
 use url::Url;
 
 lazy_static! {
   static ref EMAIL_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").expect("compile regex");
-  static ref SLUR_REGEX: Regex = {
-    let mut slurs = r"(fag(g|got|tard)?\b|cock\s?sucker(s|ing)?|ni((g{2,}|q)+|[gq]{2,})[e3r]+(s|z)?|mudslime?s?|kikes?|\bspi(c|k)s?\b|\bchinks?|gooks?|bitch(es|ing|y)?|whor(es?|ing)|\btr(a|@)nn?(y|ies?)|\b(b|re|r)tard(ed)?s?)".to_string();
-    if let Some(additional_slurs) = Settings::get().additional_slurs {
-        slurs.push('|');
-        slurs.push_str(&additional_slurs);
-    };
-    RegexBuilder::new(&slurs).case_insensitive(true).build().expect("compile regex")
-  };
-
 
   static ref USERNAME_MATCHES_REGEX: Regex = Regex::new(r"/u/[a-zA-Z][0-9a-zA-Z_]*").expect("compile regex");
   // TODO keep this old one, it didn't work with port well tho
@@ -37,12 +28,12 @@ pub fn convert_datetime(datetime: NaiveDateTime) -> DateTime<FixedOffset> {
   DateTime::<FixedOffset>::from_utc(datetime, FixedOffset::east(0))
 }
 
-pub fn remove_slurs(test: &str) -> String {
-  SLUR_REGEX.replace_all(test, "*removed*").to_string()
+pub fn remove_slurs(test: &str, slur_regex: &Regex) -> String {
+  slur_regex.replace_all(test, "*removed*").to_string()
 }
 
-pub(crate) fn slur_check(test: &str) -> Result<(), Vec<&str>> {
-  let mut matches: Vec<&str> = SLUR_REGEX.find_iter(test).map(|mat| mat.as_str()).collect();
+pub(crate) fn slur_check<'a>(test: &'a str, slur_regex: &'a Regex) -> Result<(), Vec<&'a str>> {
+  let mut matches: Vec<&str> = slur_regex.find_iter(test).map(|mat| mat.as_str()).collect();
 
   // Unique
   matches.sort_unstable();
@@ -55,17 +46,17 @@ pub(crate) fn slur_check(test: &str) -> Result<(), Vec<&str>> {
   }
 }
 
-pub fn check_slurs(text: &str) -> Result<(), ApiError> {
-  if let Err(slurs) = slur_check(text) {
+pub fn check_slurs(text: &str, slur_regex: &Regex) -> Result<(), ApiError> {
+  if let Err(slurs) = slur_check(text, slur_regex) {
     Err(ApiError::err(&slurs_vec_to_str(slurs)))
   } else {
     Ok(())
   }
 }
 
-pub fn check_slurs_opt(text: &Option<String>) -> Result<(), ApiError> {
+pub fn check_slurs_opt(text: &Option<String>, slur_regex: &Regex) -> Result<(), ApiError> {
   match text {
-    Some(t) => check_slurs(t),
+    Some(t) => check_slurs(t, slur_regex),
     None => Ok(()),
   }
 }
@@ -96,8 +87,8 @@ pub struct MentionData {
 }
 
 impl MentionData {
-  pub fn is_local(&self) -> bool {
-    Settings::get().hostname.eq(&self.domain)
+  pub fn is_local(&self, hostname: &str) -> bool {
+    hostname.eq(&self.domain)
   }
   pub fn full_name(&self) -> String {
     format!("@{}@{}", &self.name, &self.domain)
@@ -115,17 +106,16 @@ pub fn scrape_text_for_mentions(text: &str) -> Vec<MentionData> {
   out.into_iter().unique().collect()
 }
 
-pub fn is_valid_actor_name(name: &str) -> bool {
-  name.chars().count() <= Settings::get().actor_name_max_length
-    && VALID_ACTOR_NAME_REGEX.is_match(name)
+pub fn is_valid_actor_name(name: &str, actor_name_max_length: usize) -> bool {
+  name.chars().count() <= actor_name_max_length && VALID_ACTOR_NAME_REGEX.is_match(name)
 }
 
 // Can't do a regex here, reverse lookarounds not supported
-pub fn is_valid_display_name(name: &str) -> bool {
+pub fn is_valid_display_name(name: &str, actor_name_max_length: usize) -> bool {
   !name.starts_with('@')
     && !name.starts_with('\u{200b}')
     && name.chars().count() >= 3
-    && name.chars().count() <= Settings::get().actor_name_max_length
+    && name.chars().count() <= actor_name_max_length
 }
 
 pub fn is_valid_matrix_id(matrix_id: &str) -> bool {
index 2e4fda2e4c0c3f949a2d49852e1d5f52a5f429b5..7ab65aad23e20b4444040a7ca4e9148ea473ee3c 100644 (file)
@@ -14,10 +14,11 @@ use diesel::{
   PgConnection,
 };
 use lemmy_api_common::{comment::*, post::*};
-use lemmy_db_schema::{CommunityId, LocalUserId, PostId};
+use lemmy_db_schema::{source::secret::Secret, CommunityId, LocalUserId, PostId};
 use lemmy_utils::{
   location_info,
   rate_limit::RateLimit,
+  settings::structs::Settings,
   ApiError,
   ConnectionId,
   IpAddr,
@@ -71,6 +72,12 @@ pub struct ChatServer {
   /// The DB Pool
   pub(super) pool: Pool<ConnectionManager<PgConnection>>,
 
+  /// The Settings
+  pub(super) settings: Settings,
+
+  /// The Secrets
+  pub(super) secret: Secret,
+
   /// Rate limiting based on rate type and IP addr
   pub(super) rate_limiter: RateLimit,
 
@@ -95,6 +102,7 @@ pub struct SessionInfo {
 /// And manages available rooms. Peers send messages to other peers in same
 /// room through `ChatServer`.
 impl ChatServer {
+  #![allow(clippy::too_many_arguments)]
   pub fn startup(
     pool: Pool<ConnectionManager<PgConnection>>,
     rate_limiter: RateLimit,
@@ -102,6 +110,8 @@ impl ChatServer {
     message_handler_crud: MessageHandlerCrudType,
     client: Client,
     activity_queue: QueueHandle,
+    settings: Settings,
+    secret: Secret,
   ) -> ChatServer {
     ChatServer {
       sessions: HashMap::new(),
@@ -117,6 +127,8 @@ impl ChatServer {
       message_handler_crud,
       client,
       activity_queue,
+      settings,
+      secret,
     }
   }
 
@@ -452,6 +464,8 @@ impl ChatServer {
       chat_server: ctx.address(),
       client: self.client.to_owned(),
       activity_queue: self.activity_queue.to_owned(),
+      settings: self.settings.to_owned(),
+      secret: self.secret.to_owned(),
     };
     let message_handler_crud = self.message_handler_crud;
     let message_handler = self.message_handler;
index d501e9611d7ae2f5871abd004860ff87db5d1fb2..366512eb904ceff6caa5c0c36e3f932bc6079250 100644 (file)
@@ -5,7 +5,8 @@ use crate::chat_server::ChatServer;
 use actix::Addr;
 use background_jobs::QueueHandle;
 use lemmy_db_queries::DbPool;
-use lemmy_utils::LemmyError;
+use lemmy_db_schema::source::secret::Secret;
+use lemmy_utils::{settings::structs::Settings, LemmyError};
 use reqwest::Client;
 use serde::Serialize;
 
@@ -20,6 +21,8 @@ pub struct LemmyContext {
   pub chat_server: Addr<ChatServer>,
   pub client: Client,
   pub activity_queue: QueueHandle,
+  pub settings: Settings,
+  pub secret: Secret,
 }
 
 impl LemmyContext {
@@ -28,12 +31,16 @@ impl LemmyContext {
     chat_server: Addr<ChatServer>,
     client: Client,
     activity_queue: QueueHandle,
+    settings: Settings,
+    secret: Secret,
   ) -> LemmyContext {
     LemmyContext {
       pool,
       chat_server,
       client,
       activity_queue,
+      settings,
+      secret,
     }
   }
   pub fn pool(&self) -> &DbPool {
@@ -48,6 +55,13 @@ impl LemmyContext {
   pub fn activity_queue(&self) -> &QueueHandle {
     &self.activity_queue
   }
+  pub fn settings(&self) -> Settings {
+    // TODO hacky solution to be able to hotload the settings.
+    Settings::get()
+  }
+  pub fn secret(&self) -> &Secret {
+    &self.secret
+  }
 }
 
 impl Clone for LemmyContext {
@@ -57,6 +71,8 @@ impl Clone for LemmyContext {
       chat_server: self.chat_server.clone(),
       client: self.client.clone(),
       activity_queue: self.activity_queue.clone(),
+      settings: self.settings.clone(),
+      secret: self.secret.clone(),
     }
   }
 }
index cebf12936efe9c061e5369ad12926aa6eaede0fd..1f9381986e954fd6486665d3dd8ea7ff663c5236 100644 (file)
@@ -24,22 +24,28 @@ use lemmy_db_schema::{
     private_message::PrivateMessage,
   },
 };
-use lemmy_utils::{apub::generate_actor_keypair, settings::structs::Settings, LemmyError};
+use lemmy_utils::{apub::generate_actor_keypair, LemmyError};
 use log::info;
 
-pub fn run_advanced_migrations(conn: &PgConnection) -> Result<(), LemmyError> {
-  user_updates_2020_04_02(conn)?;
-  community_updates_2020_04_02(conn)?;
-  post_updates_2020_04_03(conn)?;
-  comment_updates_2020_04_03(conn)?;
-  private_message_updates_2020_05_05(conn)?;
-  post_thumbnail_url_updates_2020_07_27(conn)?;
+pub fn run_advanced_migrations(
+  conn: &PgConnection,
+  protocol_and_hostname: &str,
+) -> Result<(), LemmyError> {
+  user_updates_2020_04_02(conn, protocol_and_hostname)?;
+  community_updates_2020_04_02(conn, protocol_and_hostname)?;
+  post_updates_2020_04_03(conn, protocol_and_hostname)?;
+  comment_updates_2020_04_03(conn, protocol_and_hostname)?;
+  private_message_updates_2020_05_05(conn, protocol_and_hostname)?;
+  post_thumbnail_url_updates_2020_07_27(conn, protocol_and_hostname)?;
   apub_columns_2021_02_02(conn)?;
 
   Ok(())
 }
 
-fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
+fn user_updates_2020_04_02(
+  conn: &PgConnection,
+  protocol_and_hostname: &str,
+) -> Result<(), LemmyError> {
   use lemmy_db_schema::schema::person::dsl::*;
 
   info!("Running user_updates_2020_04_02");
@@ -55,7 +61,11 @@ fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
 
     let form = PersonForm {
       name: cperson.name.to_owned(),
-      actor_id: Some(generate_apub_endpoint(EndpointType::Person, &cperson.name)?),
+      actor_id: Some(generate_apub_endpoint(
+        EndpointType::Person,
+        &cperson.name,
+        protocol_and_hostname,
+      )?),
       private_key: Some(Some(keypair.private_key)),
       public_key: Some(Some(keypair.public_key)),
       last_refreshed_at: Some(naive_now()),
@@ -70,7 +80,10 @@ fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
   Ok(())
 }
 
-fn community_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
+fn community_updates_2020_04_02(
+  conn: &PgConnection,
+  protocol_and_hostname: &str,
+) -> Result<(), LemmyError> {
   use lemmy_db_schema::schema::community::dsl::*;
 
   info!("Running community_updates_2020_04_02");
@@ -83,7 +96,11 @@ fn community_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
 
   for ccommunity in &incorrect_communities {
     let keypair = generate_actor_keypair()?;
-    let community_actor_id = generate_apub_endpoint(EndpointType::Community, &ccommunity.name)?;
+    let community_actor_id = generate_apub_endpoint(
+      EndpointType::Community,
+      &ccommunity.name,
+      protocol_and_hostname,
+    )?;
 
     let form = CommunityForm {
       name: ccommunity.name.to_owned(),
@@ -114,7 +131,10 @@ fn community_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
   Ok(())
 }
 
-fn post_updates_2020_04_03(conn: &PgConnection) -> Result<(), LemmyError> {
+fn post_updates_2020_04_03(
+  conn: &PgConnection,
+  protocol_and_hostname: &str,
+) -> Result<(), LemmyError> {
   use lemmy_db_schema::schema::post::dsl::*;
 
   info!("Running post_updates_2020_04_03");
@@ -126,7 +146,11 @@ fn post_updates_2020_04_03(conn: &PgConnection) -> Result<(), LemmyError> {
     .load::<Post>(conn)?;
 
   for cpost in &incorrect_posts {
-    let apub_id = generate_apub_endpoint(EndpointType::Post, &cpost.id.to_string())?;
+    let apub_id = generate_apub_endpoint(
+      EndpointType::Post,
+      &cpost.id.to_string(),
+      protocol_and_hostname,
+    )?;
     Post::update_ap_id(conn, cpost.id, apub_id)?;
   }
 
@@ -135,7 +159,10 @@ fn post_updates_2020_04_03(conn: &PgConnection) -> Result<(), LemmyError> {
   Ok(())
 }
 
-fn comment_updates_2020_04_03(conn: &PgConnection) -> Result<(), LemmyError> {
+fn comment_updates_2020_04_03(
+  conn: &PgConnection,
+  protocol_and_hostname: &str,
+) -> Result<(), LemmyError> {
   use lemmy_db_schema::schema::comment::dsl::*;
 
   info!("Running comment_updates_2020_04_03");
@@ -147,7 +174,11 @@ fn comment_updates_2020_04_03(conn: &PgConnection) -> Result<(), LemmyError> {
     .load::<Comment>(conn)?;
 
   for ccomment in &incorrect_comments {
-    let apub_id = generate_apub_endpoint(EndpointType::Comment, &ccomment.id.to_string())?;
+    let apub_id = generate_apub_endpoint(
+      EndpointType::Comment,
+      &ccomment.id.to_string(),
+      protocol_and_hostname,
+    )?;
     Comment::update_ap_id(conn, ccomment.id, apub_id)?;
   }
 
@@ -156,7 +187,10 @@ fn comment_updates_2020_04_03(conn: &PgConnection) -> Result<(), LemmyError> {
   Ok(())
 }
 
-fn private_message_updates_2020_05_05(conn: &PgConnection) -> Result<(), LemmyError> {
+fn private_message_updates_2020_05_05(
+  conn: &PgConnection,
+  protocol_and_hostname: &str,
+) -> Result<(), LemmyError> {
   use lemmy_db_schema::schema::private_message::dsl::*;
 
   info!("Running private_message_updates_2020_05_05");
@@ -168,7 +202,11 @@ fn private_message_updates_2020_05_05(conn: &PgConnection) -> Result<(), LemmyEr
     .load::<PrivateMessage>(conn)?;
 
   for cpm in &incorrect_pms {
-    let apub_id = generate_apub_endpoint(EndpointType::PrivateMessage, &cpm.id.to_string())?;
+    let apub_id = generate_apub_endpoint(
+      EndpointType::PrivateMessage,
+      &cpm.id.to_string(),
+      protocol_and_hostname,
+    )?;
     PrivateMessage::update_ap_id(conn, cpm.id, apub_id)?;
   }
 
@@ -177,15 +215,15 @@ fn private_message_updates_2020_05_05(conn: &PgConnection) -> Result<(), LemmyEr
   Ok(())
 }
 
-fn post_thumbnail_url_updates_2020_07_27(conn: &PgConnection) -> Result<(), LemmyError> {
+fn post_thumbnail_url_updates_2020_07_27(
+  conn: &PgConnection,
+  protocol_and_hostname: &str,
+) -> Result<(), LemmyError> {
   use lemmy_db_schema::schema::post::dsl::*;
 
   info!("Running post_thumbnail_url_updates_2020_07_27");
 
-  let domain_prefix = format!(
-    "{}/pictrs/image/",
-    Settings::get().get_protocol_and_hostname(),
-  );
+  let domain_prefix = format!("{}/pictrs/image/", protocol_and_hostname,);
 
   let incorrect_thumbnails = post.filter(thumbnail_url.not_like("http%"));
 
index 504ccc80eab12cc568687363ddd88cee0c490c52..4e827d72a0842065b1b2be27aab54b1ee07ec2d8 100644 (file)
@@ -11,7 +11,8 @@ use lemmy_api::match_websocket_operation;
 use lemmy_api_common::blocking;
 use lemmy_api_crud::match_websocket_operation_crud;
 use lemmy_apub::activity_queue::create_activity_queue;
-use lemmy_db_queries::get_database_url_from_env;
+use lemmy_db_queries::{get_database_url_from_env, source::secret::Secret_};
+use lemmy_db_schema::source::secret::Secret;
 use lemmy_routes::{feeds, images, nodeinfo, webfinger};
 use lemmy_server::{api_routes, code_migrations::run_advanced_migrations, scheduled_tasks};
 use lemmy_utils::{
@@ -29,7 +30,7 @@ embed_migrations!();
 #[actix_web::main]
 async fn main() -> Result<(), LemmyError> {
   env_logger::init();
-  let settings = Settings::get();
+  let settings = Settings::init().expect("Couldn't initialize settings.");
 
   // Set up the r2d2 connection pool
   let db_url = match get_database_url_from_env() {
@@ -43,9 +44,10 @@ async fn main() -> Result<(), LemmyError> {
     .unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
 
   // Run the migrations from code
+  let protocol_and_hostname = settings.get_protocol_and_hostname();
   blocking(&pool, move |conn| {
     embedded_migrations::run(conn)?;
-    run_advanced_migrations(conn)?;
+    run_advanced_migrations(conn, &protocol_and_hostname)?;
     Ok(()) as Result<(), LemmyError>
   })
   .await??;
@@ -58,8 +60,13 @@ async fn main() -> Result<(), LemmyError> {
   // Set up the rate limiter
   let rate_limiter = RateLimit {
     rate_limiter: Arc::new(Mutex::new(RateLimiter::default())),
+    rate_limit_config: settings.rate_limit.to_owned().unwrap_or_default(),
   };
 
+  // Initialize the secrets
+  let conn = pool.get()?;
+  let secret = Secret::init(&conn).expect("Couldn't initialize secrets.");
+
   println!(
     "Starting http server at {}:{}",
     settings.bind, settings.port
@@ -74,16 +81,21 @@ async fn main() -> Result<(), LemmyError> {
     |c, i, o, d| Box::pin(match_websocket_operation_crud(c, i, o, d)),
     Client::default(),
     activity_queue.clone(),
+    settings.clone(),
+    secret.clone(),
   )
   .start();
 
   // Create Http server with websocket support
+  let settings_bind = settings.clone();
   HttpServer::new(move || {
     let context = LemmyContext::create(
       pool.clone(),
       chat_server.to_owned(),
       Client::default(),
       activity_queue.to_owned(),
+      settings.to_owned(),
+      secret.to_owned(),
     );
     let rate_limiter = rate_limiter.clone();
     App::new()
@@ -91,13 +103,13 @@ async fn main() -> Result<(), LemmyError> {
       .app_data(Data::new(context))
       // The routes
       .configure(|cfg| api_routes::config(cfg, &rate_limiter))
-      .configure(lemmy_apub::http::routes::config)
+      .configure(|cfg| lemmy_apub::http::routes::config(cfg, &settings))
       .configure(feeds::config)
       .configure(|cfg| images::config(cfg, &rate_limiter))
       .configure(nodeinfo::config)
-      .configure(webfinger::config)
+      .configure(|cfg| webfinger::config(cfg, &settings))
   })
-  .bind((settings.bind, settings.port))?
+  .bind((settings_bind.bind, settings_bind.port))?
   .run()
   .await?;