Remove update and read site config. Fixes #2306 (#2329)

* Remove update and read site config. Fixes #2306

* Removing lazy_static, removing Settings::get()
handle-better-deleted-actors
Dessalines 2022-06-22 16:24:54 -04:00 committed by GitHub
parent 8af913f583
commit a745fa6f43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 84 additions and 200 deletions

View File

@ -98,12 +98,6 @@ pub async fn match_websocket_operation(
// Site ops
UserOperation::GetModlog => do_websocket_operation::<GetModlog>(context, id, op, data).await,
UserOperation::GetSiteConfig => {
do_websocket_operation::<GetSiteConfig>(context, id, op, data).await
}
UserOperation::SaveSiteConfig => {
do_websocket_operation::<SaveSiteConfig>(context, id, op, data).await
}
UserOperation::PurgePerson => {
do_websocket_operation::<PurgePerson>(context, id, op, data).await
}
@ -226,13 +220,13 @@ mod tests {
traits::Crud,
utils::establish_unpooled_connection,
};
use lemmy_utils::{claims::Claims, settings::structs::Settings};
use lemmy_utils::{claims::Claims, settings::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 settings = &SETTINGS.to_owned();
let new_person = PersonForm {
name: "Gerry9812".into(),

View File

@ -52,7 +52,7 @@ impl Perform for BanPerson {
remove_user_data(
person.id,
context.pool(),
&context.settings(),
context.settings(),
context.client(),
)
.await?;

View File

@ -17,7 +17,7 @@ impl Perform for GetCaptcha {
context: &Data<LemmyContext>,
_websocket_id: Option<ConnectionId>,
) -> Result<Self::Response, LemmyError> {
let captcha_settings = context.settings().captcha;
let captcha_settings = &context.settings().captcha;
if !captcha_settings.enabled {
return Ok(GetCaptchaResponse { ok: None });

View File

@ -29,7 +29,7 @@ impl Perform for PasswordReset {
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_that_username_or_email"))?;
// Email the pure token to the user.
send_password_reset_email(&local_user_view, context.pool(), &context.settings()).await?;
send_password_reset_email(&local_user_view, context.pool(), context.settings()).await?;
Ok(PasswordResetResponse {})
}
}

View File

@ -48,7 +48,7 @@ impl Perform for SaveUserSettings {
let previous_email = local_user_view.local_user.email.clone().unwrap_or_default();
// Only send the verification email if there was an email change
if previous_email.ne(email) {
send_verification_email(&local_user_view, email, context.pool(), &context.settings())
send_verification_email(&local_user_view, email, context.pool(), context.settings())
.await?;
}
}

View File

@ -49,7 +49,7 @@ impl Perform for VerifyEmail {
})
.await??;
send_email_verification_success(&local_user_view, &context.settings())?;
send_email_verification_success(&local_user_view, context.settings())?;
blocking(context.pool(), move |conn| {
EmailVerification::delete_old_tokens_for_local_user(conn, local_user_id)

View File

@ -1,2 +0,0 @@
mod read;
mod update;

View File

@ -1,31 +0,0 @@
use crate::Perform;
use actix_web::web::Data;
use lemmy_api_common::{
site::{GetSiteConfig, GetSiteConfigResponse},
utils::{get_local_user_view_from_jwt, is_admin},
};
use lemmy_utils::{error::LemmyError, settings::structs::Settings, ConnectionId};
use lemmy_websocket::LemmyContext;
#[async_trait::async_trait(?Send)]
impl Perform for GetSiteConfig {
type Response = GetSiteConfigResponse;
#[tracing::instrument(skip(context, _websocket_id))]
async fn perform(
&self,
context: &Data<LemmyContext>,
_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(), context.secret()).await?;
// Only let admins read this
is_admin(&local_user_view)?;
let config_hjson = Settings::read_config_file()?;
Ok(GetSiteConfigResponse { config_hjson })
}
}

View File

@ -1,33 +0,0 @@
use crate::Perform;
use actix_web::web::Data;
use lemmy_api_common::{
site::{GetSiteConfigResponse, SaveSiteConfig},
utils::{get_local_user_view_from_jwt, is_admin},
};
use lemmy_utils::{error::LemmyError, settings::structs::Settings, ConnectionId};
use lemmy_websocket::LemmyContext;
#[async_trait::async_trait(?Send)]
impl Perform for SaveSiteConfig {
type Response = GetSiteConfigResponse;
#[tracing::instrument(skip(context, _websocket_id))]
async fn perform(
&self,
context: &Data<LemmyContext>,
_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(), context.secret()).await?;
// Only let admins read this
is_admin(&local_user_view)?;
// Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem
let config_hjson = Settings::save_config_file(&data.config_hjson)
.map_err(|e| e.with_message("couldnt_update_site"))?;
Ok(GetSiteConfigResponse { config_hjson })
}
}

View File

@ -57,8 +57,7 @@ impl Perform for LeaveAdmin {
let site_view = blocking(context.pool(), SiteView::read_local).await??;
let admins = blocking(context.pool(), PersonViewSafe::admins).await??;
let federated_instances =
build_federated_instances(context.pool(), &context.settings()).await?;
let federated_instances = build_federated_instances(context.pool(), context.settings()).await?;
Ok(GetSiteResponse {
site_view: Some(site_view),

View File

@ -1,4 +1,3 @@
mod config;
mod leave_admin;
mod mod_log;
mod purge;

View File

@ -41,13 +41,13 @@ impl Perform for PurgeCommunity {
.await??;
if let Some(banner) = community.banner {
purge_image_from_pictrs(context.client(), &context.settings(), &banner)
purge_image_from_pictrs(context.client(), context.settings(), &banner)
.await
.ok();
}
if let Some(icon) = community.icon {
purge_image_from_pictrs(context.client(), &context.settings(), &icon)
purge_image_from_pictrs(context.client(), context.settings(), &icon)
.await
.ok();
}
@ -55,7 +55,7 @@ impl Perform for PurgeCommunity {
purge_image_posts_for_community(
community_id,
context.pool(),
&context.settings(),
context.settings(),
context.client(),
)
.await?;

View File

@ -37,13 +37,13 @@ impl Perform for PurgePerson {
let person = blocking(context.pool(), move |conn| Person::read(conn, person_id)).await??;
if let Some(banner) = person.banner {
purge_image_from_pictrs(context.client(), &context.settings(), &banner)
purge_image_from_pictrs(context.client(), context.settings(), &banner)
.await
.ok();
}
if let Some(avatar) = person.avatar {
purge_image_from_pictrs(context.client(), &context.settings(), &avatar)
purge_image_from_pictrs(context.client(), context.settings(), &avatar)
.await
.ok();
}
@ -51,7 +51,7 @@ impl Perform for PurgePerson {
purge_image_posts_for_person(
person_id,
context.pool(),
&context.settings(),
context.settings(),
context.client(),
)
.await?;

View File

@ -39,13 +39,13 @@ impl Perform for PurgePost {
// Purge image
if let Some(url) = post.url {
purge_image_from_pictrs(context.client(), &context.settings(), &url)
purge_image_from_pictrs(context.client(), context.settings(), &url)
.await
.ok();
}
// Purge thumbnail
if let Some(thumbnail_url) = post.thumbnail_url {
purge_image_from_pictrs(context.client(), &context.settings(), &thumbnail_url)
purge_image_from_pictrs(context.client(), context.settings(), &thumbnail_url)
.await
.ok();
}

View File

@ -66,7 +66,7 @@ impl Perform for ApproveRegistrationApplication {
.await??;
if approved_local_user_view.local_user.email.is_some() {
send_application_approved_email(&approved_local_user_view, &context.settings())?;
send_application_approved_email(&approved_local_user_view, context.settings())?;
}
}

View File

@ -262,15 +262,15 @@ pub fn build_user_agent(settings: &Settings) -> String {
#[cfg(test)]
mod tests {
use crate::request::{build_user_agent, fetch_site_metadata, SiteMetadata};
use lemmy_utils::settings::structs::Settings;
use lemmy_utils::settings::SETTINGS;
use url::Url;
// These helped with testing
#[actix_rt::test]
async fn test_site_metadata() {
let settings = Settings::init().unwrap();
let settings = &SETTINGS.to_owned();
let client = reqwest::Client::builder()
.user_agent(build_user_agent(&settings))
.user_agent(build_user_agent(settings))
.build()
.unwrap()
.into();

View File

@ -179,22 +179,6 @@ pub struct LeaveAdmin {
pub auth: Sensitive<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GetSiteConfig {
pub auth: Sensitive<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GetSiteConfigResponse {
pub config_hjson: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SaveSiteConfig {
pub config_hjson: String,
pub auth: Sensitive<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct FederatedInstances {
pub linked: Vec<String>,

View File

@ -87,7 +87,7 @@ impl PerformCrud for CreatePost {
// Fetch post links and pictrs cached image
let data_url = data.url.as_ref();
let (metadata_res, thumbnail_url) =
fetch_site_data(context.client(), &context.settings(), data_url).await;
fetch_site_data(context.client(), context.settings(), data_url).await;
let (embed_title, embed_description, embed_video_url) = metadata_res
.map(|u| (u.title, u.description, u.embed_video_url))
.unwrap_or_default();

View File

@ -70,7 +70,7 @@ impl PerformCrud for EditPost {
// Fetch post links and Pictrs cached image
let data_url = data.url.as_ref();
let (metadata_res, thumbnail_url) =
fetch_site_data(context.client(), &context.settings(), data_url).await;
fetch_site_data(context.client(), context.settings(), data_url).await;
let (embed_title, embed_description, embed_video_url) = metadata_res
.map(|u| (u.title, u.description, u.embed_video_url))
.unwrap_or_default();

View File

@ -119,7 +119,7 @@ impl PerformCrud for CreatePrivateMessage {
&content_slurs_removed,
&local_recipient.person.name,
),
&context.settings(),
context.settings(),
);
}

View File

@ -15,7 +15,6 @@ use lemmy_db_schema::{
use lemmy_db_views::structs::SiteView;
use lemmy_utils::{
error::LemmyError,
settings::structs::Settings,
utils::{check_slurs, check_slurs_opt},
ConnectionId,
};
@ -57,7 +56,7 @@ impl PerformCrud for CreateSite {
site_description_length_check(desc)?;
}
let actor_id: DbUrl = Url::parse(&Settings::get().get_protocol_and_hostname())?.into();
let actor_id: DbUrl = Url::parse(&context.settings().get_protocol_and_hostname())?.into();
let inbox_url = Some(generate_site_inbox_url(&actor_id)?);
let keypair = generate_actor_keypair()?;
let site_form = SiteForm {

View File

@ -120,8 +120,7 @@ impl PerformCrud for GetSite {
None
};
let federated_instances =
build_federated_instances(context.pool(), &context.settings()).await?;
let federated_instances = build_federated_instances(context.pool(), context.settings()).await?;
Ok(GetSiteResponse {
site_view,

View File

@ -211,13 +211,8 @@ impl PerformCrud for Register {
.email
.clone()
.expect("email was provided");
send_verification_email(
&local_user_view,
&email,
context.pool(),
&context.settings(),
)
.await?;
send_verification_email(&local_user_view, &email, context.pool(), context.settings())
.await?;
login_response.verify_email_sent = true;
}

View File

@ -36,7 +36,7 @@ impl PerformCrud for DeleteAccount {
delete_user_account(
local_user_view.person.id,
context.pool(),
&context.settings(),
context.settings(),
context.client(),
)
.await?;

View File

@ -37,7 +37,7 @@ use lemmy_db_schema::{
},
traits::{Bannable, Crud, Followable},
};
use lemmy_utils::{error::LemmyError, settings::structs::Settings, utils::convert_datetime};
use lemmy_utils::{error::LemmyError, utils::convert_datetime};
use lemmy_websocket::LemmyContext;
use url::Url;
@ -131,7 +131,7 @@ impl ActivityHandler for BlockUser {
{
SiteOrCommunity::Site(site) => {
let domain = self.object.inner().domain().expect("url needs domain");
if Settings::get().hostname == domain {
if context.settings().hostname == domain {
return Err(
anyhow!("Site bans from remote instance can't affect user's home instance").into(),
);
@ -184,7 +184,7 @@ impl ActivityHandler for BlockUser {
remove_user_data(
blocked_person.id,
context.pool(),
&context.settings(),
context.settings(),
context.client(),
)
.await?;

View File

@ -54,7 +54,7 @@ impl ActivityHandler for DeleteUser {
delete_user_account(
actor.id,
context.pool(),
&context.settings(),
context.settings(),
context.client(),
)
.await?;

View File

@ -3,7 +3,7 @@ use activitypub_federation::traits::ApubObject;
use itertools::Itertools;
use lemmy_api_common::utils::blocking;
use lemmy_db_schema::traits::ApubActor;
use lemmy_utils::{error::LemmyError, settings::structs::Settings};
use lemmy_utils::error::LemmyError;
use lemmy_websocket::LemmyContext;
pub mod post_or_comment;
@ -35,7 +35,7 @@ where
.collect_tuple()
.expect("invalid query");
let name = name.to_string();
let domain = format!("{}://{}", Settings::get().get_protocol_string(), domain);
let domain = format!("{}://{}", context.settings().get_protocol_string(), domain);
let actor = blocking(context.pool(), move |conn| {
DbActor::read_from_name_and_domain(conn, &name, &domain)
})

View File

@ -8,7 +8,7 @@ use activitypub_federation::{deser::context::WithContext, traits::ApubObject};
use actix_web::{web, HttpRequest, HttpResponse};
use lemmy_api_common::utils::blocking;
use lemmy_db_schema::source::site::Site;
use lemmy_utils::{error::LemmyError, settings::structs::Settings};
use lemmy_utils::error::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -24,10 +24,12 @@ pub(crate) async fn get_apub_site_http(
}
#[tracing::instrument(skip_all)]
pub(crate) async fn get_apub_site_outbox() -> Result<HttpResponse, LemmyError> {
pub(crate) async fn get_apub_site_outbox(
context: web::Data<LemmyContext>,
) -> Result<HttpResponse, LemmyError> {
let outbox_id = format!(
"{}/site_outbox",
Settings::get().get_protocol_and_hostname()
context.settings().get_protocol_and_hostname()
);
let outbox = EmptyOutbox::new(Url::parse(&outbox_id)?).await?;
Ok(create_apub_response(&outbox))

View File

@ -8,7 +8,11 @@ use activitypub_federation::{
use anyhow::Context;
use lemmy_api_common::utils::blocking;
use lemmy_db_schema::{newtypes::DbUrl, source::activity::Activity, utils::DbPool};
use lemmy_utils::{error::LemmyError, location_info, settings::structs::Settings};
use lemmy_utils::{
error::LemmyError,
location_info,
settings::{structs::Settings, SETTINGS},
};
use lemmy_websocket::LemmyContext;
use once_cell::sync::{Lazy, OnceCell};
use url::{ParseError, Url};
@ -34,11 +38,13 @@ fn local_instance(context: &LemmyContext) -> &'static LocalInstance {
.http_fetch_retry_limit(context.settings().federation.http_fetch_retry_limit)
.worker_count(context.settings().federation.worker_count)
.debug(context.settings().federation.debug)
.verify_url_function(|url| check_apub_id_valid(url, &Settings::get()))
// TODO No idea why, but you can't pass context.settings() to the verify_url_function closure
// without the value getting captured.
.verify_url_function(|url| check_apub_id_valid(url, &SETTINGS.to_owned()))
.build()
.expect("configure federation");
LocalInstance::new(
context.settings().hostname,
context.settings().hostname.to_owned(),
context.client().clone(),
settings,
)

View File

@ -142,8 +142,8 @@ impl ApubObject for ApubComment {
Community::read(conn, community_id)
})
.await??;
check_apub_id_valid_with_strictness(note.id.inner(), community.local, &context.settings())?;
verify_is_remote_object(note.id.inner())?;
check_apub_id_valid_with_strictness(note.id.inner(), community.local, context.settings())?;
verify_is_remote_object(note.id.inner(), context.settings())?;
verify_person_in_community(
&note.attributed_to,
&community.into(),

View File

@ -206,9 +206,7 @@ impl ApubCommunity {
.unique()
.filter(|inbox: &Url| inbox.host_str() != Some(&context.settings().hostname))
// Don't send to blocked instances
.filter(|inbox| {
check_apub_id_valid_with_strictness(inbox, false, &context.settings()).is_ok()
})
.filter(|inbox| check_apub_id_valid_with_strictness(inbox, false, context.settings()).is_ok())
.collect();
Ok(inboxes)

View File

@ -103,7 +103,7 @@ impl ApubObject for ApubSite {
data: &Self::DataType,
_request_counter: &mut i32,
) -> Result<(), LemmyError> {
check_apub_id_valid_with_strictness(apub.id.inner(), true, &data.settings())?;
check_apub_id_valid_with_strictness(apub.id.inner(), true, data.settings())?;
verify_domains_match(expected_domain, apub.id.inner())?;
let slur_regex = &data.settings().slur_regex();

View File

@ -43,8 +43,8 @@ pub(crate) fn read_from_string_or_source_opt(
/// wrapped in Announce. If we simply receive this like any other federated object, overwrite the
/// existing, local Post. In particular, it will set the field local = false, so that the object
/// can't be fetched from the Activitypub HTTP endpoint anymore (which only serves local objects).
pub(crate) fn verify_is_remote_object(id: &Url) -> Result<(), LemmyError> {
let local_domain = Settings::get().get_hostname_without_port()?;
pub(crate) fn verify_is_remote_object(id: &Url, settings: &Settings) -> Result<(), LemmyError> {
let local_domain = settings.get_hostname_without_port()?;
if id.domain() == Some(&local_domain) {
Err(anyhow!("cant accept local object from remote instance").into())
} else {
@ -68,7 +68,7 @@ pub(crate) mod tests {
use lemmy_utils::{
error::LemmyError,
rate_limit::{rate_limiter::RateLimiter, RateLimit},
settings::structs::Settings,
settings::SETTINGS,
};
use lemmy_websocket::{chat_server::ChatServer, LemmyContext};
use parking_lot::Mutex;
@ -96,7 +96,7 @@ pub(crate) mod tests {
pub(crate) fn init_context() -> LemmyContext {
// call this to run migrations
establish_unpooled_connection();
let settings = Settings::init().unwrap();
let settings = SETTINGS.to_owned();
let rate_limiter = RateLimit {
rate_limiter: Arc::new(Mutex::new(RateLimiter::default())),
rate_limit_config: settings.rate_limit.to_owned().unwrap_or_default(),

View File

@ -120,7 +120,7 @@ impl ApubObject for ApubPerson {
_request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(person.id.inner(), expected_domain)?;
check_apub_id_valid_with_strictness(person.id.inner(), false, &context.settings())?;
check_apub_id_valid_with_strictness(person.id.inner(), false, context.settings())?;
let slur_regex = &context.settings().slur_regex();
check_slurs(&person.preferred_username, slur_regex)?;

View File

@ -19,6 +19,7 @@ use activitystreams_kinds::public;
use chrono::NaiveDateTime;
use lemmy_api_common::{request::fetch_site_data, utils::blocking};
use lemmy_db_schema::{
self,
source::{
community::Community,
moderator::{ModLockPost, ModLockPostForm, ModStickyPost, ModStickyPostForm},
@ -26,7 +27,6 @@ use lemmy_db_schema::{
post::{Post, PostForm},
},
traits::Crud,
{self},
};
use lemmy_utils::{
error::LemmyError,
@ -132,11 +132,11 @@ impl ApubObject for ApubPost {
// instance from the post author.
if !page.is_mod_action(context).await? {
verify_domains_match(page.id.inner(), expected_domain)?;
verify_is_remote_object(page.id.inner())?;
verify_is_remote_object(page.id.inner(), context.settings())?;
};
let community = page.extract_community(context, request_counter).await?;
check_apub_id_valid_with_strictness(page.id.inner(), community.local, &context.settings())?;
check_apub_id_valid_with_strictness(page.id.inner(), community.local, context.settings())?;
verify_person_in_community(&page.creator()?, &community, context, request_counter).await?;
check_slurs(&page.name, &context.settings().slur_regex())?;
verify_domains_match(page.creator()?.inner(), page.id.inner())?;
@ -168,7 +168,7 @@ impl ApubObject for ApubPost {
page.url
};
let (metadata_res, thumbnail_url) = if let Some(url) = &url {
fetch_site_data(context.client(), &context.settings(), Some(url)).await
fetch_site_data(context.client(), context.settings(), Some(url)).await
} else {
(None, page.image.map(|i| i.url.into()))
};

View File

@ -24,7 +24,6 @@ use lemmy_db_schema::{
};
use lemmy_utils::{
error::LemmyError,
settings::structs::Settings,
utils::{convert_datetime, markdown_to_html},
};
use lemmy_websocket::LemmyContext;
@ -109,7 +108,7 @@ impl ApubObject for ApubPrivateMessage {
) -> Result<(), LemmyError> {
verify_domains_match(note.id.inner(), expected_domain)?;
verify_domains_match(note.attributed_to.inner(), note.id.inner())?;
check_apub_id_valid_with_strictness(note.id.inner(), false, &Settings::get())?;
check_apub_id_valid_with_strictness(note.id.inner(), false, context.settings())?;
let person = note
.attributed_to
.dereference(context, local_instance(context), request_counter)

View File

@ -63,7 +63,7 @@ impl Group {
expected_domain: &Url,
context: &LemmyContext,
) -> Result<(), LemmyError> {
check_apub_id_valid_with_strictness(self.id.inner(), true, &context.settings())?;
check_apub_id_valid_with_strictness(self.id.inner(), true, context.settings())?;
verify_domains_match(expected_domain, self.id.inner())?;
let slur_regex = &context.settings().slur_regex();

View File

@ -7,18 +7,18 @@ use anyhow::{anyhow, Context};
use deser_hjson::from_str;
use once_cell::sync::Lazy;
use regex::{Regex, RegexBuilder};
use std::{env, fs, io::Error, sync::RwLock};
use std::{env, fs, io::Error};
pub mod structs;
static DEFAULT_CONFIG_FILE: &str = "config/config.hjson";
static SETTINGS: Lazy<RwLock<Settings>> =
Lazy::new(|| RwLock::new(Settings::init().expect("Failed to load settings file")));
pub static SETTINGS: Lazy<Settings> =
Lazy::new(|| Settings::init().expect("Failed to load settings file"));
static WEBFINGER_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new(&format!(
"^acct:([a-zA-Z0-9_]{{3,}})@{}$",
Settings::get().hostname
SETTINGS.hostname
))
.expect("compile webfinger regex")
});
@ -29,7 +29,7 @@ impl Settings {
/// Note: The env var `LEMMY_DATABASE_URL` is parsed in
/// `lemmy_db_schema/src/lib.rs::get_database_url_from_env()`
/// Warning: Only call this once.
pub fn init() -> Result<Self, LemmyError> {
pub(crate) fn init() -> Result<Self, LemmyError> {
// Read the config file
let config = from_str::<Settings>(&Self::read_config_file()?)?;
@ -40,11 +40,6 @@ impl Settings {
Ok(config)
}
/// Returns the config as a struct.
pub fn get() -> Self {
SETTINGS.read().expect("read config").to_owned()
}
pub fn get_database_url(&self) -> String {
let conf = &self.database;
format!(
@ -91,23 +86,6 @@ impl Settings {
)
}
pub fn save_config_file(data: &str) -> Result<String, LemmyError> {
// check that the config is valid
from_str::<Settings>(data)?;
fs::write(Settings::get_config_location(), data)?;
// Reload the new settings
// From https://stackoverflow.com/questions/29654927/how-do-i-assign-a-string-to-a-mutable-static-variable/47181804#47181804
let mut new_settings = SETTINGS.write().expect("write config");
*new_settings = match Settings::init() {
Ok(c) => c,
Err(e) => panic!("{}", e),
};
Ok(Self::read_config_file()?)
}
pub fn webfinger_regex(&self) -> Regex {
WEBFINGER_REGEX.to_owned()
}

View File

@ -1,5 +1,5 @@
use crate::{
settings::structs::Settings,
settings::SETTINGS,
utils::{
is_valid_actor_name,
is_valid_display_name,
@ -24,7 +24,7 @@ fn test_mentions_regex() {
#[test]
fn test_valid_actor_name() {
let actor_name_max_length = Settings::init().unwrap().actor_name_max_length;
let actor_name_max_length = SETTINGS.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));
@ -34,7 +34,7 @@ fn test_valid_actor_name() {
#[test]
fn test_valid_display_name() {
let actor_name_max_length = Settings::init().unwrap().actor_name_max_length;
let actor_name_max_length = SETTINGS.actor_name_max_length;
assert!(is_valid_display_name("hello @there", actor_name_max_length));
assert!(!is_valid_display_name(
"@hello there",
@ -65,7 +65,7 @@ fn test_valid_matrix_id() {
#[test]
fn test_slur_filter() {
let slur_regex = Settings::init().unwrap().slur_regex();
let slur_regex = SETTINGS.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";

View File

@ -4,7 +4,10 @@ extern crate strum_macros;
use crate::chat_server::ChatServer;
use actix::Addr;
use lemmy_db_schema::{source::secret::Secret, utils::DbPool};
use lemmy_utils::{error::LemmyError, settings::structs::Settings};
use lemmy_utils::{
error::LemmyError,
settings::{structs::Settings, SETTINGS},
};
use reqwest_middleware::ClientWithMiddleware;
use serde::Serialize;
@ -47,9 +50,8 @@ impl LemmyContext {
pub fn client(&self) -> &ClientWithMiddleware {
&self.client
}
pub fn settings(&self) -> Settings {
// TODO hacky solution to be able to hotload the settings.
Settings::get()
pub fn settings(&self) -> &'static Settings {
&SETTINGS
}
pub fn secret(&self) -> &Secret {
&self.secret
@ -133,8 +135,6 @@ pub enum UserOperation {
PasswordChange,
MarkPrivateMessageAsRead,
UserJoin,
GetSiteConfig,
SaveSiteConfig,
PostJoin,
CommunityJoin,
ModJoin,

View File

@ -217,7 +217,7 @@ pub async fn send_local_notifs(
&mention_user_view,
&lang.notification_mentioned_by_subject(&person.name),
&lang.notification_mentioned_by_body(&comment.content, &inbox_link, &person.name),
&context.settings(),
context.settings(),
)
}
}
@ -252,7 +252,7 @@ pub async fn send_local_notifs(
&parent_user_view,
&lang.notification_comment_reply_subject(&person.name),
&lang.notification_comment_reply_body(&comment.content, &inbox_link, &person.name),
&context.settings(),
context.settings(),
)
}
}
@ -282,7 +282,7 @@ pub async fn send_local_notifs(
&parent_user_view,
&lang.notification_post_reply_subject(&person.name),
&lang.notification_post_reply_body(&comment.content, &inbox_link, &person.name),
&context.settings(),
context.settings(),
)
}
}

View File

@ -18,9 +18,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
.route("", web::get().to(route_get_crud::<GetSite>))
// Admin Actions
.route("", web::post().to(route_post_crud::<CreateSite>))
.route("", web::put().to(route_post_crud::<EditSite>))
.route("/config", web::get().to(route_get::<GetSiteConfig>))
.route("/config", web::put().to(route_post::<SaveSiteConfig>)),
.route("", web::put().to(route_post_crud::<EditSite>)),
)
.service(
web::resource("/modlog")

View File

@ -26,7 +26,7 @@ use lemmy_server::{
use lemmy_utils::{
error::LemmyError,
rate_limit::{rate_limiter::RateLimiter, RateLimit},
settings::structs::Settings,
settings::{structs::Settings, SETTINGS},
};
use lemmy_websocket::{chat_server::ChatServer, LemmyContext};
use parking_lot::Mutex;
@ -54,7 +54,7 @@ async fn main() -> Result<(), LemmyError> {
return Ok(());
}
let settings = Settings::init().expect("Couldn't initialize settings.");
let settings = SETTINGS.to_owned();
init_logging(settings.opentelemetry_url.as_deref())?;