diff --git a/.rustfmt.toml b/.rustfmt.toml index f3efdc30..59528c80 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,5 +1,5 @@ tab_spaces = 2 edition="2018" imports_layout="HorizontalVertical" -merge_imports=true +imports_granularity="Crate" reorder_imports=true diff --git a/Cargo.lock b/Cargo.lock index 2edcca8d..47ee01e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "activitystreams" version = "0.7.0-alpha.10" @@ -8,7 +10,7 @@ checksum = "fe7ceed015dfca322d3bcec3653909c77557e7e57df72e98cb8806e2c93cc919" dependencies = [ "chrono", "mime", - "serde 1.0.123", + "serde", "serde_json", "thiserror", "url", @@ -21,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb8e19a0810cc25df3535061a08b7d8f8a734d309ea4411c57a9767e4a2ffa0e" dependencies = [ "activitystreams", - "serde 1.0.123", + "serde", "serde_json", ] @@ -128,7 +130,7 @@ dependencies = [ "pin-project 1.0.4", "rand 0.7.3", "regex", - "serde 1.0.123", + "serde", "serde_json", "serde_urlencoded", "sha-1 0.9.3", @@ -156,7 +158,7 @@ dependencies = [ "http", "log", "regex", - "serde 1.0.123", + "serde", ] [[package]] @@ -300,7 +302,7 @@ dependencies = [ "pin-project 1.0.4", "regex", "rustls", - "serde 1.0.123", + "serde", "serde_json", "serde_urlencoded", "socket2", @@ -389,12 +391,6 @@ version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "async-mutex" version = "1.4.0" @@ -464,7 +460,7 @@ dependencies = [ "percent-encoding", "rand 0.7.3", "rustls", - "serde 1.0.123", + "serde", "serde_json", "serde_urlencoded", ] @@ -494,7 +490,7 @@ dependencies = [ "log", "num_cpus", "rand 0.7.3", - "serde 1.0.123", + "serde", "serde_json", "thiserror", "tokio 0.2.25", @@ -513,7 +509,7 @@ dependencies = [ "async-trait", "chrono", "log", - "serde 1.0.123", + "serde", "serde_json", "thiserror", "tokio 0.2.25", @@ -733,8 +729,8 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ "libc", "num-integer", - "num-traits 0.2.14", - "serde 1.0.123", + "num-traits", + "serde", "time 0.1.44", "winapi 0.3.9", ] @@ -781,18 +777,6 @@ dependencies = [ "xdg", ] -[[package]] -name = "config" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" -dependencies = [ - "lazy_static", - "nom 5.1.2", - "serde 1.0.123", - "serde-hjson", -] - [[package]] name = "const_fn" version = "0.4.5" @@ -995,6 +979,15 @@ dependencies = [ "syn", ] +[[package]] +name = "deser-hjson" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d995b60ff81bc6af01a98f0bf5db70a7418a1ac8bd74ada633968f388139da5e" +dependencies = [ + "serde", +] + [[package]] name = "diesel" version = "1.4.5" @@ -1590,7 +1583,7 @@ dependencies = [ "jpeg-decoder", "num-iter", "num-rational", - "num-traits 0.2.14", + "num-traits", "png", "scoped_threadpool", "tiff", @@ -1684,7 +1677,7 @@ dependencies = [ "base64 0.12.3", "pem", "ring", - "serde 1.0.123", + "serde", "serde_json", "simple_asn1", ] @@ -1745,7 +1738,7 @@ dependencies = [ "openssl", "rand 0.8.3", "reqwest", - "serde 1.0.123", + "serde", "serde_json", "sha2", "strum", @@ -1792,7 +1785,7 @@ dependencies = [ "percent-encoding", "rand 0.8.3", "reqwest", - "serde 1.0.123", + "serde", "serde_json", "sha2", "strum", @@ -1816,7 +1809,7 @@ dependencies = [ "lemmy_utils", "log", "regex", - "serde 1.0.123", + "serde", "serde_json", "sha2", "strum", @@ -1831,7 +1824,7 @@ dependencies = [ "chrono", "diesel", "log", - "serde 1.0.123", + "serde", "serde_json", "url", ] @@ -1844,7 +1837,7 @@ dependencies = [ "lemmy_db_queries", "lemmy_db_schema", "log", - "serde 1.0.123", + "serde", "url", ] @@ -1855,7 +1848,7 @@ dependencies = [ "diesel", "lemmy_db_queries", "lemmy_db_schema", - "serde 1.0.123", + "serde", ] [[package]] @@ -1865,7 +1858,7 @@ dependencies = [ "diesel", "lemmy_db_queries", "lemmy_db_schema", - "serde 1.0.123", + "serde", ] [[package]] @@ -1889,7 +1882,7 @@ dependencies = [ "lemmy_websocket", "log", "rss", - "serde 1.0.123", + "serde", "sha2", "strum", "url", @@ -1925,7 +1918,7 @@ dependencies = [ "log", "openssl", "reqwest", - "serde 1.0.123", + "serde", "serde_json", "strum", "tokio 0.3.7", @@ -1946,7 +1939,7 @@ dependencies = [ "lemmy_db_views_moderator", "lemmy_utils", "log", - "serde 1.0.123", + "serde", "serde_json", "url", ] @@ -1960,7 +1953,7 @@ dependencies = [ "anyhow", "chrono", "comrak", - "config", + "deser-hjson", "diesel", "futures", "http", @@ -1974,7 +1967,7 @@ dependencies = [ "rand 0.8.3", "regex", "reqwest", - "serde 1.0.123", + "serde", "serde_json", "strum", "strum_macros", @@ -2001,7 +1994,7 @@ dependencies = [ "log", "rand 0.8.3", "reqwest", - "serde 1.0.123", + "serde", "serde_json", "strum", "strum_macros", @@ -2020,46 +2013,23 @@ dependencies = [ "idna", "mime", "native-tls", - "nom 6.1.0", + "nom", "once_cell", "quoted_printable", "r2d2", "rand 0.8.3", "regex", - "serde 1.0.123", + "serde", "serde_json", "uuid", ] -[[package]] -name = "lexical-core" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616" -dependencies = [ - "arrayvec", - "bitflags", - "cfg-if 0.1.10", - "ryu", - "static_assertions", -] - [[package]] name = "libc" version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff" -[[package]] -name = "linked-hash-map" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" -dependencies = [ - "serde 0.8.23", - "serde_test", -] - [[package]] name = "linked-hash-map" version = "0.5.4" @@ -2102,7 +2072,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" dependencies = [ - "linked-hash-map 0.5.4", + "linked-hash-map", ] [[package]] @@ -2271,17 +2241,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "nom" -version = "5.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" -dependencies = [ - "lexical-core", - "memchr", - "version_check", -] - [[package]] name = "nom" version = "6.1.0" @@ -2301,7 +2260,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ "autocfg", "num-integer", - "num-traits 0.2.14", + "num-traits", ] [[package]] @@ -2311,7 +2270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ "autocfg", - "num-traits 0.2.14", + "num-traits", ] [[package]] @@ -2322,7 +2281,7 @@ checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" dependencies = [ "autocfg", "num-integer", - "num-traits 0.2.14", + "num-traits", ] [[package]] @@ -2333,16 +2292,7 @@ checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" dependencies = [ "autocfg", "num-integer", - "num-traits 0.2.14", -] - -[[package]] -name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -dependencies = [ - "num-traits 0.2.14", + "num-traits", ] [[package]] @@ -2838,7 +2788,7 @@ dependencies = [ "native-tls", "percent-encoding", "pin-project-lite 0.2.4", - "serde 1.0.123", + "serde", "serde_json", "serde_urlencoded", "tokio 0.2.25", @@ -3008,12 +2958,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -[[package]] -name = "serde" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" - [[package]] name = "serde" version = "1.0.123" @@ -3023,19 +2967,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-hjson" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" -dependencies = [ - "lazy_static", - "linked-hash-map 0.3.0", - "num-traits 0.1.43", - "regex", - "serde 0.8.23", -] - [[package]] name = "serde_derive" version = "1.0.123" @@ -3056,16 +2987,7 @@ dependencies = [ "indexmap", "itoa", "ryu", - "serde 1.0.123", -] - -[[package]] -name = "serde_test" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" -dependencies = [ - "serde 0.8.23", + "serde", ] [[package]] @@ -3077,7 +2999,7 @@ dependencies = [ "form_urlencoded", "itoa", "ryu", - "serde 1.0.123", + "serde", ] [[package]] @@ -3147,7 +3069,7 @@ checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" dependencies = [ "chrono", "num-bigint", - "num-traits 0.2.14", + "num-traits", ] [[package]] @@ -3188,12 +3110,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stdweb" version = "0.4.20" @@ -3216,7 +3132,7 @@ checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ "proc-macro2", "quote", - "serde 1.0.123", + "serde", "serde_derive", "syn", ] @@ -3230,7 +3146,7 @@ dependencies = [ "base-x", "proc-macro2", "quote", - "serde 1.0.123", + "serde", "serde_derive", "serde_json", "sha1", @@ -3666,7 +3582,7 @@ dependencies = [ "idna", "matches", "percent-encoding", - "serde 1.0.123", + "serde", ] [[package]] @@ -3676,7 +3592,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ "getrandom 0.2.2", - "serde 1.0.123", + "serde", ] [[package]] @@ -3720,7 +3636,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be" dependencies = [ "cfg-if 1.0.0", - "serde 1.0.123", + "serde", "serde_json", "wasm-bindgen-macro", ] diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 5e9e1c16..7caaba3b 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -19,7 +19,13 @@ use lemmy_db_views_actor::{ community_view::CommunityView, }; use lemmy_structs::{blocking, comment::*, community::*, post::*, site::*, user::*, websocket::*}; -use lemmy_utils::{claims::Claims, settings::Settings, APIError, ConnectionId, LemmyError}; +use lemmy_utils::{ + claims::Claims, + settings::structs::Settings, + APIError, + ConnectionId, + LemmyError, +}; use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation}; use serde::Deserialize; use std::process::Command; diff --git a/crates/api/src/site.rs b/crates/api/src/site.rs index 1bdce91a..83037d65 100644 --- a/crates/api/src/site.rs +++ b/crates/api/src/site.rs @@ -48,7 +48,7 @@ use lemmy_db_views_moderator::{ use lemmy_structs::{blocking, site::*, user::Register}; use lemmy_utils::{ location_info, - settings::Settings, + settings::structs::Settings, utils::{check_slurs, check_slurs_opt}, version, APIError, @@ -583,7 +583,9 @@ impl Perform for GetSiteConfig { // Only let admins read this is_admin(context.pool(), user.id).await?; - let config_hjson = Settings::read_config_file()?; + // TODO: should make the response field optional? + // or include env vars, but then we cant really save it + let config_hjson = Settings::read_config_file().unwrap_or("".to_string()); Ok(GetSiteConfigResponse { config_hjson }) } diff --git a/crates/api/src/user.rs b/crates/api/src/user.rs index 93d40bda..df8d1263 100644 --- a/crates/api/src/user.rs +++ b/crates/api/src/user.rs @@ -71,7 +71,7 @@ use lemmy_utils::{ claims::Claims, email::send_email, location_info, - settings::Settings, + settings::structs::Settings, utils::{ check_slurs, generate_random_string, diff --git a/crates/apub/src/activities/send/comment.rs b/crates/apub/src/activities/send/comment.rs index f007cda4..be96b6c2 100644 --- a/crates/apub/src/activities/send/comment.rs +++ b/crates/apub/src/activities/send/comment.rs @@ -31,7 +31,7 @@ use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post use lemmy_structs::{blocking, WebFingerResponse}; use lemmy_utils::{ request::{retry, RecvError}, - settings::Settings, + settings::structs::Settings, utils::{scrape_text_for_mentions, MentionData}, LemmyError, }; diff --git a/crates/apub/src/activities/send/mod.rs b/crates/apub/src/activities/send/mod.rs index 166855e2..2da0b48c 100644 --- a/crates/apub/src/activities/send/mod.rs +++ b/crates/apub/src/activities/send/mod.rs @@ -1,4 +1,4 @@ -use lemmy_utils::settings::Settings; +use lemmy_utils::settings::structs::Settings; use url::{ParseError, Url}; use uuid::Uuid; diff --git a/crates/apub/src/activity_queue.rs b/crates/apub/src/activity_queue.rs index c0c4ac46..285c8c47 100644 --- a/crates/apub/src/activity_queue.rs +++ b/crates/apub/src/activity_queue.rs @@ -22,7 +22,7 @@ use background_jobs::{ use itertools::Itertools; use lemmy_db_queries::DbPool; use lemmy_db_schema::source::{community::Community, user::User_}; -use lemmy_utils::{location_info, settings::Settings, LemmyError}; +use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use log::{debug, warn}; use reqwest::Client; diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs index 9f465f76..b7eb70cd 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -35,14 +35,14 @@ use lemmy_db_schema::source::{ use lemmy_db_views::{comment_view::CommentView, post_view::PostView}; use lemmy_db_views_actor::{community_view::CommunityView, user_view::UserViewSafe}; use lemmy_structs::{blocking, site::SearchResponse}; -use lemmy_utils::{settings::Settings, LemmyError}; +use lemmy_utils::{settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use log::debug; use url::Url; /// The types of ActivityPub objects that can be fetched directly by searching for their ID. -#[serde(untagged)] #[derive(serde::Deserialize, Debug)] +#[serde(untagged)] enum SearchAcceptedObjects { Person(Box), Group(Box), diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index f0ffbcb1..f2c8a208 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -4,7 +4,7 @@ use http::StatusCode; use lemmy_db_queries::source::activity::Activity_; use lemmy_db_schema::source::activity::Activity; use lemmy_structs::blocking; -use lemmy_utils::{settings::Settings, LemmyError}; +use lemmy_utils::{settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; diff --git a/crates/apub/src/inbox/mod.rs b/crates/apub/src/inbox/mod.rs index 765d5dff..6e90a2bc 100644 --- a/crates/apub/src/inbox/mod.rs +++ b/crates/apub/src/inbox/mod.rs @@ -19,7 +19,7 @@ use lemmy_db_queries::{ }; use lemmy_db_schema::source::{activity::Activity, community::Community, user::User_}; use lemmy_structs::blocking; -use lemmy_utils::{location_info, settings::Settings, LemmyError}; +use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use serde::Serialize; use std::fmt::Debug; diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 388d57e6..159e20cf 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -34,7 +34,7 @@ use lemmy_db_schema::source::{ user::User_, }; use lemmy_structs::blocking; -use lemmy_utils::{location_info, settings::Settings, LemmyError}; +use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use serde::Serialize; use std::net::IpAddr; diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs index bf0ac24c..014144de 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -15,7 +15,12 @@ use diesel::result::Error::NotFound; use lemmy_db_queries::{ApubObject, Crud, DbPool}; use lemmy_db_schema::source::community::Community; use lemmy_structs::blocking; -use lemmy_utils::{location_info, settings::Settings, utils::convert_datetime, LemmyError}; +use lemmy_utils::{ + location_info, + settings::structs::Settings, + utils::convert_datetime, + LemmyError, +}; use lemmy_websocket::LemmyContext; use url::Url; diff --git a/crates/apub/src/objects/user.rs b/crates/apub/src/objects/user.rs index 8a911de2..de05398f 100644 --- a/crates/apub/src/objects/user.rs +++ b/crates/apub/src/objects/user.rs @@ -26,7 +26,7 @@ use lemmy_db_schema::{ use lemmy_structs::blocking; use lemmy_utils::{ location_info, - settings::Settings, + settings::structs::Settings, utils::{check_slurs, check_slurs_opt, convert_datetime}, LemmyError, }; diff --git a/crates/apub/src/routes.rs b/crates/apub/src/routes.rs index 3717a894..68700b9c 100644 --- a/crates/apub/src/routes.rs +++ b/crates/apub/src/routes.rs @@ -16,7 +16,7 @@ use crate::{ }; use actix_web::*; use http_signature_normalization_actix::digest::middleware::VerifyDigest; -use lemmy_utils::settings::Settings; +use lemmy_utils::settings::structs::Settings; use sha2::{Digest, Sha256}; static APUB_JSON_CONTENT_TYPE_LONG: &str = diff --git a/crates/db_queries/src/source/user.rs b/crates/db_queries/src/source/user.rs index 5f3fa6cb..5f175e1d 100644 --- a/crates/db_queries/src/source/user.rs +++ b/crates/db_queries/src/source/user.rs @@ -7,7 +7,7 @@ use lemmy_db_schema::{ source::user::{UserForm, UserSafeSettings, User_}, Url, }; -use lemmy_utils::settings::Settings; +use lemmy_utils::settings::structs::Settings; mod safe_type { use crate::ToSafe; diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 837e1489..0f723fde 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -15,7 +15,12 @@ use lemmy_db_views::{ }; use lemmy_db_views_actor::user_mention_view::{UserMentionQueryBuilder, UserMentionView}; use lemmy_structs::blocking; -use lemmy_utils::{claims::Claims, settings::Settings, utils::markdown_to_html, LemmyError}; +use lemmy_utils::{ + claims::Claims, + settings::structs::Settings, + utils::markdown_to_html, + LemmyError, +}; use lemmy_websocket::LemmyContext; use rss::{ extension::dublincore::DublinCoreExtensionBuilder, diff --git a/crates/routes/src/images.rs b/crates/routes/src/images.rs index 4d7656e1..0177c7e9 100644 --- a/crates/routes/src/images.rs +++ b/crates/routes/src/images.rs @@ -1,7 +1,7 @@ use actix::clock::Duration; use actix_web::{body::BodyStream, http::StatusCode, *}; use awc::Client; -use lemmy_utils::{claims::Claims, rate_limit::RateLimit, settings::Settings}; +use lemmy_utils::{claims::Claims, rate_limit::RateLimit, settings::structs::Settings}; use serde::{Deserialize, Serialize}; pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { diff --git a/crates/routes/src/nodeinfo.rs b/crates/routes/src/nodeinfo.rs index 46ef7ce4..a3c2af5a 100644 --- a/crates/routes/src/nodeinfo.rs +++ b/crates/routes/src/nodeinfo.rs @@ -2,7 +2,7 @@ use actix_web::{body::Body, error::ErrorBadRequest, *}; use anyhow::anyhow; use lemmy_db_views::site_view::SiteView; use lemmy_structs::blocking; -use lemmy_utils::{settings::Settings, version, LemmyError}; +use lemmy_utils::{settings::structs::Settings, version, LemmyError}; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/routes/src/webfinger.rs b/crates/routes/src/webfinger.rs index 4059e0f8..bd0d8d47 100644 --- a/crates/routes/src/webfinger.rs +++ b/crates/routes/src/webfinger.rs @@ -4,7 +4,7 @@ use lemmy_db_queries::source::{community::Community_, user::User}; use lemmy_db_schema::source::{community::Community, user::User_}; use lemmy_structs::{blocking, WebFingerLink, WebFingerResponse}; use lemmy_utils::{ - settings::Settings, + settings::structs::Settings, LemmyError, WEBFINGER_COMMUNITY_REGEX, WEBFINGER_USER_REGEX, diff --git a/crates/structs/src/lib.rs b/crates/structs/src/lib.rs index 8b56fab6..cf69a3c2 100644 --- a/crates/structs/src/lib.rs +++ b/crates/structs/src/lib.rs @@ -13,7 +13,7 @@ use lemmy_db_schema::source::{ user::User_, user_mention::{UserMention, UserMentionForm}, }; -use lemmy_utils::{email::send_email, settings::Settings, utils::MentionData, LemmyError}; +use lemmy_utils::{email::send_email, settings::structs::Settings, utils::MentionData, LemmyError}; use log::error; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index c10b7c2c..50a41fb7 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -9,7 +9,6 @@ path = "src/lib.rs" [dependencies] regex = "1.4.3" -config = { version = "0.10.1", default-features = false, features = ["hjson"] } chrono = { version = "0.4.19", features = ["serde"] } lettre = "0.10.0-alpha.5" log = "0.4.14" @@ -34,3 +33,4 @@ futures = "0.3.12" diesel = "1.4.5" http = "0.2.3" jsonwebtoken = "7.2.0" +deser-hjson = "0.1.12" diff --git a/crates/utils/src/claims.rs b/crates/utils/src/claims.rs index dff79d85..2fb0d734 100644 --- a/crates/utils/src/claims.rs +++ b/crates/utils/src/claims.rs @@ -1,4 +1,4 @@ -use crate::settings::Settings; +use crate::settings::structs::Settings; use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; diff --git a/crates/utils/src/email.rs b/crates/utils/src/email.rs index 8e61500c..280ec41c 100644 --- a/crates/utils/src/email.rs +++ b/crates/utils/src/email.rs @@ -1,4 +1,4 @@ -use crate::settings::Settings; +use crate::settings::structs::Settings; use lettre::{ message::{header, Mailbox, MultiPart, SinglePart}, transport::smtp::{ diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index 6d8265aa..051c776d 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -14,7 +14,7 @@ mod test; pub mod utils; pub mod version; -use crate::settings::Settings; +use crate::settings::structs::Settings; use http::StatusCode; use regex::Regex; use thiserror::Error; diff --git a/crates/utils/src/rate_limit/mod.rs b/crates/utils/src/rate_limit/mod.rs index 5a18ffd5..3c095be1 100644 --- a/crates/utils/src/rate_limit/mod.rs +++ b/crates/utils/src/rate_limit/mod.rs @@ -1,5 +1,5 @@ use crate::{ - settings::{RateLimitConfig, Settings}, + settings::structs::{RateLimitConfig, Settings}, utils::get_ip, LemmyError, }; diff --git a/crates/utils/src/request.rs b/crates/utils/src/request.rs index 411d4342..7899dad7 100644 --- a/crates/utils/src/request.rs +++ b/crates/utils/src/request.rs @@ -1,4 +1,4 @@ -use crate::{settings::Settings, LemmyError}; +use crate::{settings::structs::Settings, LemmyError}; use anyhow::anyhow; use log::error; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; diff --git a/crates/utils/src/settings.rs b/crates/utils/src/settings.rs deleted file mode 100644 index 8301dcee..00000000 --- a/crates/utils/src/settings.rs +++ /dev/null @@ -1,210 +0,0 @@ -use crate::location_info; -use anyhow::Context; -use config::{Config, ConfigError, Environment, File}; -use serde::Deserialize; -use std::{env, fs, io::Error, net::IpAddr, sync::RwLock}; - -static CONFIG_FILE_DEFAULTS: &str = "config/defaults.hjson"; -static CONFIG_FILE: &str = "config/config.hjson"; - -#[derive(Debug, Deserialize, Clone)] -pub struct Settings { - pub setup: Option, - pub database: DatabaseConfig, - pub hostname: String, - pub bind: IpAddr, - pub port: u16, - pub tls_enabled: bool, - pub jwt_secret: String, - pub pictrs_url: String, - pub iframely_url: String, - pub rate_limit: RateLimitConfig, - pub email: Option, - pub federation: FederationConfig, - pub captcha: CaptchaConfig, -} - -#[derive(Debug, Deserialize, Clone)] -pub struct Setup { - pub admin_username: String, - pub admin_password: String, - pub admin_email: Option, - pub site_name: String, -} - -#[derive(Debug, Deserialize, Clone)] -pub struct RateLimitConfig { - pub message: i32, - pub message_per_second: i32, - pub post: i32, - pub post_per_second: i32, - pub register: i32, - pub register_per_second: i32, - pub image: i32, - pub image_per_second: i32, -} - -#[derive(Debug, Deserialize, Clone)] -pub struct EmailConfig { - pub smtp_server: String, - pub smtp_login: Option, - pub smtp_password: Option, - pub smtp_from_address: String, - pub use_tls: bool, -} - -#[derive(Debug, Deserialize, Clone)] -pub struct CaptchaConfig { - pub enabled: bool, - pub difficulty: String, // easy, medium, or hard -} - -#[derive(Debug, Deserialize, Clone)] -pub struct DatabaseConfig { - pub user: String, - pub password: String, - pub host: String, - pub port: i32, - pub database: String, - pub pool_size: u32, -} - -#[derive(Debug, Deserialize, Clone)] -pub struct FederationConfig { - pub enabled: bool, - pub allowed_instances: String, - pub blocked_instances: String, -} - -lazy_static! { - static ref SETTINGS: RwLock = RwLock::new(match Settings::init() { - Ok(c) => c, - Err(e) => panic!("{}", e), - }); -} - -impl Settings { - /// Reads config from the files and environment. - /// First, defaults are loaded from CONFIG_FILE_DEFAULTS, then these values can be overwritten - /// from CONFIG_FILE (optional). Finally, values from the environment (with prefix LEMMY) are - /// added to the config. - /// - /// Note: The env var `LEMMY_DATABASE_URL` is parsed in - /// `lemmy_db_queries/src/lib.rs::get_database_url_from_env()` - fn init() -> Result { - let mut s = Config::new(); - - s.merge(File::with_name(&Self::get_config_defaults_location()))?; - - s.merge(File::with_name(&Self::get_config_location()).required(false))?; - - // Add in settings from the environment (with a prefix of LEMMY) - // Eg.. `LEMMY_DEBUG=1 ./target/app` would set the `debug` key - // Note: we need to use double underscore here, because otherwise variables containing - // underscore cant be set from environmnet. - // https://github.com/mehcode/config-rs/issues/73 - s.merge(Environment::with_prefix("LEMMY").separator("__"))?; - - s.try_into() - } - - /// Returns the config as a struct. - pub fn get() -> Self { - SETTINGS.read().unwrap().to_owned() - } - - pub fn get_database_url(&self) -> String { - format!( - "postgres://{}:{}@{}:{}/{}", - self.database.user, - self.database.password, - self.database.host, - self.database.port, - self.database.database - ) - } - - pub fn get_config_defaults_location() -> String { - env::var("LEMMY_CONFIG_DEFAULTS_LOCATION").unwrap_or_else(|_| CONFIG_FILE_DEFAULTS.to_string()) - } - - pub fn get_config_location() -> String { - env::var("LEMMY_CONFIG_LOCATION").unwrap_or_else(|_| CONFIG_FILE.to_string()) - } - - pub fn read_config_file() -> Result { - fs::read_to_string(Self::get_config_location()) - } - - pub fn get_allowed_instances(&self) -> Vec { - let mut allowed_instances: Vec = self - .federation - .allowed_instances - .split(',') - .map(|d| d.trim().to_string()) - .collect(); - - // The defaults.hjson config always returns a [""] - allowed_instances.retain(|d| !d.eq("")); - - allowed_instances - } - - pub fn get_blocked_instances(&self) -> Vec { - let mut blocked_instances: Vec = self - .federation - .blocked_instances - .split(',') - .map(|d| d.trim().to_string()) - .collect(); - - // The defaults.hjson config always returns a [""] - blocked_instances.retain(|d| !d.eq("")); - - blocked_instances - } - - /// Returns either "http" or "https", depending on tls_enabled setting - pub fn get_protocol_string(&self) -> &'static str { - if self.tls_enabled { - "https" - } else { - "http" - } - } - - /// Returns something like `http://localhost` or `https://lemmy.ml`, - /// with the correct protocol and hostname. - pub fn get_protocol_and_hostname(&self) -> String { - format!("{}://{}", self.get_protocol_string(), self.hostname) - } - - /// When running the federation test setup in `api_tests/` or `docker/federation`, the `hostname` - /// variable will be like `lemmy-alpha:8541`. This method removes the port and returns - /// `lemmy-alpha` instead. It has no effect in production. - pub fn get_hostname_without_port(&self) -> Result { - Ok( - self - .hostname - .split(':') - .collect::>() - .first() - .context(location_info!())? - .to_string(), - ) - } - - pub fn save_config_file(data: &str) -> Result { - fs::write(CONFIG_FILE, 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().unwrap(); - *new_settings = match Settings::init() { - Ok(c) => c, - Err(e) => panic!("{}", e), - }; - - Self::read_config_file() - } -} diff --git a/crates/utils/src/settings/defaults.rs b/crates/utils/src/settings/defaults.rs new file mode 100644 index 00000000..5b733028 --- /dev/null +++ b/crates/utils/src/settings/defaults.rs @@ -0,0 +1,70 @@ +use crate::settings::structs::*; +use std::net::{IpAddr, Ipv4Addr}; + +impl Default for Settings { + fn default() -> Self { + Self { + database: DatabaseConfig::default(), + rate_limit: RateLimitConfig::default(), + federation: FederationConfig::default(), + captcha: CaptchaConfig::default(), + email: None, + setup: None, + // TODO: not sure how to handle this, its mandatory but not provided by defaults + hostname: "hostname_not_set".into(), + bind: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), + port: 8536, + tls_enabled: true, + jwt_secret: "changeme".into(), + pictrs_url: "http://pictrs:8080".into(), + iframely_url: "http://iframely".into(), + } + } +} + +impl Default for RateLimitConfig { + fn default() -> Self { + Self { + message: 180, + message_per_second: 60, + post: 6, + post_per_second: 600, + register: 3, + register_per_second: 3600, + image: 6, + image_per_second: 3600, + } + } +} + +impl Default for CaptchaConfig { + fn default() -> Self { + Self { + enabled: true, + difficulty: "medium".into(), + } + } +} + +impl Default for DatabaseConfig { + fn default() -> Self { + Self { + user: "lemmy".into(), + password: "password".into(), + host: "localhost".into(), + port: 5432, + database: "lemmy".into(), + pool_size: 5, + } + } +} + +impl Default for FederationConfig { + fn default() -> Self { + Self { + enabled: false, + allowed_instances: "".into(), + blocked_instances: "".into(), + } + } +} diff --git a/crates/utils/src/settings/environment.rs b/crates/utils/src/settings/environment.rs new file mode 100644 index 00000000..9721212f --- /dev/null +++ b/crates/utils/src/settings/environment.rs @@ -0,0 +1,73 @@ +use crate::settings::structs_opt::{ + CaptchaConfigOpt, + DatabaseConfigOpt, + EmailConfigOpt, + FederationConfigOpt, + RateLimitConfigOpt, + SettingsOpt, + SetupOpt, +}; +use std::{env, str::FromStr}; + +pub(in crate::settings) fn parse_from_env() -> SettingsOpt { + SettingsOpt { + hostname: env_var("HOSTNAME"), + bind: env_var("BIND"), + port: env_var("PORT"), + tls_enabled: env_var("TLS_ENABLED"), + jwt_secret: env_var("JWT_SECRET"), + pictrs_url: env_var("PICTRS_URL"), + iframely_url: env_var("IFRAMELY_URL"), + rate_limit: Some(RateLimitConfigOpt { + message: env_var("RATE_LIMIT__MESSAGE"), + message_per_second: env_var("RATE_LIMIT__MESSAGE_PER_SECOND"), + post: env_var("RATE_LIMIT__POST"), + post_per_second: env_var("RATE_LIMIT__POST_PER_SECOND"), + register: env_var("RATE_LIMIT__REGISTER"), + register_per_second: env_var("RATE_LIMIT__REGISTER_PER_SECOND"), + image: env_var("RATE_LIMIT__IMAGE"), + image_per_second: env_var("RATE_LIMIT__IMAGE_PER_SECOND"), + }), + email: Some(EmailConfigOpt { + smtp_server: env_var("EMAIL__SMTP_SERVER"), + smtp_login: Some(env_var("EMAIL__SMTP_LOGIN")), + smtp_password: Some(env_var("EMAIL__SMTP_PASSWORD")), + smtp_from_address: env_var("EMAIL__SMTP_FROM_ADDRESS"), + use_tls: env_var("EMAIL__USE_TLS"), + }), + federation: Some(FederationConfigOpt { + enabled: env_var("FEDERATION__ENABLED"), + allowed_instances: env_var("FEDERATION__ALLOWED_INSTANCES"), + blocked_instances: env_var("FEDERATION__BLOCKED_INSTANCES"), + }), + captcha: Some(CaptchaConfigOpt { + enabled: env_var("CAPTCHA__ENABLED"), + difficulty: env_var("CAPTCHA__DIFFICULTY"), + }), + setup: Some(SetupOpt { + admin_username: env_var("SETUP__ADMIN_USERNAME"), + admin_password: env_var("SETUP__ADMIN_PASSWORD"), + admin_email: Some(env_var("SETUP__ADMIN_EMAIL")), + site_name: env_var("SETUP__SITE_NAME"), + }), + database: Some(DatabaseConfigOpt { + user: env_var("DATABASE__USER"), + password: env_var("DATABASE__PASSWORD"), + host: env_var("DATABASE__HOST"), + port: env_var("DATABASE__PORT"), + database: env_var("DATABASE__DATABASE"), + pool_size: env_var("DATABASE__POOL_SIZE"), + }), + } +} + +fn env_var(name: &str) -> Option +where + T: FromStr, + ::Err: std::fmt::Debug, +{ + // TODO: probably remove the unwrap + env::var(format!("LEMMY_{}", name)) + .ok() + .map(|v| T::from_str(&v).unwrap()) +} diff --git a/crates/utils/src/settings/merge.rs b/crates/utils/src/settings/merge.rs new file mode 100644 index 00000000..189fc546 --- /dev/null +++ b/crates/utils/src/settings/merge.rs @@ -0,0 +1,141 @@ +use crate::settings::{structs::*, structs_opt::*}; + +pub(in crate::settings) trait Merge { + fn merge(self, opt: T) -> Self; +} + +impl Merge for Settings { + fn merge(self, opt: SettingsOpt) -> Self { + Settings { + setup: merge_structs(self.setup, opt.setup), + database: merge_structs(self.database, opt.database), + hostname: opt.hostname.unwrap_or(self.hostname), + bind: opt.bind.unwrap_or(self.bind), + port: opt.port.unwrap_or(self.port), + tls_enabled: opt.tls_enabled.unwrap_or(self.tls_enabled), + jwt_secret: opt.jwt_secret.unwrap_or(self.jwt_secret), + pictrs_url: opt.pictrs_url.unwrap_or(self.pictrs_url), + iframely_url: opt.iframely_url.unwrap_or(self.iframely_url), + rate_limit: merge_structs(self.rate_limit, opt.rate_limit), + email: merge_structs(self.email, opt.email), + federation: merge_structs(self.federation, opt.federation), + captcha: merge_structs(self.captcha, opt.captcha), + } + } +} + +impl Merge for RateLimitConfig { + fn merge(self, opt: RateLimitConfigOpt) -> Self { + RateLimitConfig { + message: opt.message.unwrap_or(self.message), + message_per_second: opt.message_per_second.unwrap_or(self.message_per_second), + post: opt.post.unwrap_or(self.post), + post_per_second: opt.post_per_second.unwrap_or(self.post_per_second), + register: opt.register.unwrap_or(self.register), + register_per_second: opt.register_per_second.unwrap_or(self.register_per_second), + image: opt.image.unwrap_or(self.image), + image_per_second: opt.image_per_second.unwrap_or(self.image_per_second), + } + } +} + +impl Merge for Option { + fn merge(self, opt: SetupOpt) -> Self { + if let Some(setup) = self { + Some(Setup { + admin_username: opt.admin_username.unwrap_or(setup.admin_username), + admin_password: opt.admin_password.unwrap_or(setup.admin_password), + admin_email: opt.admin_email.unwrap_or(setup.admin_email), + site_name: opt.site_name.unwrap_or(setup.site_name), + }) + } else if let (Some(admin_username), Some(admin_password), Some(site_name)) = + (opt.admin_username, opt.admin_password, opt.site_name) + { + Some(Setup { + admin_username, + admin_password, + admin_email: opt.admin_email.flatten(), + site_name, + }) + } else { + None + } + } +} + +impl Merge for Option { + fn merge(self, opt: EmailConfigOpt) -> Self { + if let Some(email_config) = self { + Some(EmailConfig { + smtp_server: opt.smtp_server.unwrap_or(email_config.smtp_server), + smtp_login: opt.smtp_login.unwrap_or(email_config.smtp_login), + smtp_password: opt.smtp_password.unwrap_or(email_config.smtp_password), + smtp_from_address: opt + .smtp_from_address + .unwrap_or(email_config.smtp_from_address), + use_tls: opt.use_tls.unwrap_or(email_config.use_tls), + }) + } else if let (Some(smtp_server), Some(smtp_from_address), Some(use_tls)) = + (opt.smtp_server, opt.smtp_from_address, opt.use_tls) + { + Some(EmailConfig { + smtp_server, + smtp_login: opt + .smtp_login + .or(self.clone().map(|s| s.smtp_login)) + .flatten(), + smtp_password: opt + .smtp_password + .or(self.map(|s| s.smtp_password)) + .flatten(), + smtp_from_address, + use_tls, + }) + } else { + None + } + } +} + +impl Merge for DatabaseConfig { + fn merge(self, opt: DatabaseConfigOpt) -> Self { + DatabaseConfig { + user: opt.user.unwrap_or(self.user), + password: opt.password.unwrap_or(self.password), + host: opt.host.unwrap_or(self.host), + port: opt.port.unwrap_or(self.port), + database: opt.database.unwrap_or(self.database), + pool_size: opt.pool_size.unwrap_or(self.pool_size), + } + } +} + +impl Merge for FederationConfig { + fn merge(self, opt: FederationConfigOpt) -> Self { + FederationConfig { + enabled: opt.enabled.unwrap_or(self.enabled), + allowed_instances: opt.allowed_instances.unwrap_or(self.allowed_instances), + blocked_instances: opt.blocked_instances.unwrap_or(self.blocked_instances), + } + } +} + +impl Merge for CaptchaConfig { + fn merge(self, opt: CaptchaConfigOpt) -> Self { + CaptchaConfig { + enabled: opt.enabled.unwrap_or(self.enabled), + difficulty: opt.difficulty.unwrap_or(self.difficulty), + } + } +} + +fn merge_structs(lhs: T, rhs: Option) -> T +where + T: Merge + std::clone::Clone, +{ + if let Some(x) = rhs { + lhs.merge(x) + } else { + lhs.to_owned() + } +} diff --git a/crates/utils/src/settings/mod.rs b/crates/utils/src/settings/mod.rs new file mode 100644 index 00000000..db3ebe89 --- /dev/null +++ b/crates/utils/src/settings/mod.rs @@ -0,0 +1,151 @@ +use crate::{ + location_info, + settings::{ + environment::parse_from_env, + merge::Merge, + structs::Settings, + structs_opt::SettingsOpt, + }, + LemmyError, +}; +use anyhow::{anyhow, Context}; +use deser_hjson::from_str; +use std::{env, fs, sync::RwLock}; + +pub mod defaults; +mod environment; +mod merge; +pub mod structs; +mod structs_opt; + +static CONFIG_FILE: &str = "config/config.hjson"; + +lazy_static! { + static ref SETTINGS: RwLock = RwLock::new(match Settings::init() { + Ok(c) => c, + Err(e) => panic!("{}", e), + }); +} + +impl Settings { + /// Reads config from the files and environment. + /// First, defaults are loaded from CONFIG_FILE_DEFAULTS, then these values can be overwritten + /// from CONFIG_FILE (optional). Finally, values from the environment (with prefix LEMMY) are + /// added to the config. + /// + /// Note: The env var `LEMMY_DATABASE_URL` is parsed in + /// `lemmy_db_queries/src/lib.rs::get_database_url_from_env()` + fn init() -> Result { + let mut config = Settings::default(); + + // Read the config file + if let Some(config_file) = &Self::read_config_file() { + config = config.merge(from_str::(config_file)?); + } + + // Read env vars + config = config.merge(parse_from_env()); + + if config.hostname == Settings::default().hostname { + return Err(anyhow!("Hostname variable is not set!").into()); + } + + Ok(config) + } + + /// Returns the config as a struct. + pub fn get() -> Self { + SETTINGS.read().unwrap().to_owned() + } + + pub fn get_database_url(&self) -> String { + let conf = self.database.to_owned(); + format!( + "postgres://{}:{}@{}:{}/{}", + conf.user, conf.password, conf.host, conf.port, conf.database, + ) + } + + pub fn get_config_location() -> String { + env::var("LEMMY_CONFIG_LOCATION").unwrap_or_else(|_| CONFIG_FILE.to_string()) + } + + pub fn read_config_file() -> Option { + fs::read_to_string(Self::get_config_location()).ok() + } + + pub fn get_allowed_instances(&self) -> Vec { + let mut allowed_instances: Vec = self + .federation + .to_owned() + .allowed_instances + .split(',') + .map(|d| d.trim().to_string()) + .collect(); + + allowed_instances.retain(|d| !d.eq("")); + allowed_instances + } + + pub fn get_blocked_instances(&self) -> Vec { + let mut blocked_instances: Vec = self + .federation + .to_owned() + .blocked_instances + .split(',') + .map(|d| d.trim().to_string()) + .collect(); + + blocked_instances.retain(|d| !d.eq("")); + blocked_instances + } + + /// Returns either "http" or "https", depending on tls_enabled setting + pub fn get_protocol_string(&self) -> &'static str { + if self.tls_enabled { + "https" + } else { + "http" + } + } + + /// Returns something like `http://localhost` or `https://lemmy.ml`, + /// with the correct protocol and hostname. + pub fn get_protocol_and_hostname(&self) -> String { + format!( + "{}://{}", + self.get_protocol_string(), + self.hostname.to_owned() + ) + } + + /// When running the federation test setup in `api_tests/` or `docker/federation`, the `hostname` + /// variable will be like `lemmy-alpha:8541`. This method removes the port and returns + /// `lemmy-alpha` instead. It has no effect in production. + pub fn get_hostname_without_port(&self) -> Result { + Ok( + self + .hostname + .to_owned() + .split(':') + .collect::>() + .first() + .context(location_info!())? + .to_string(), + ) + } + + pub fn save_config_file(data: &str) -> Result { + fs::write(CONFIG_FILE, 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().unwrap(); + *new_settings = match Settings::init() { + Ok(c) => c, + Err(e) => panic!("{}", e), + }; + + Self::read_config_file().ok_or(anyhow!("Failed to read config").into()) + } +} diff --git a/crates/utils/src/settings/structs.rs b/crates/utils/src/settings/structs.rs new file mode 100644 index 00000000..1e92e93d --- /dev/null +++ b/crates/utils/src/settings/structs.rs @@ -0,0 +1,72 @@ +use serde::Deserialize; +use std::net::IpAddr; + +#[derive(Debug, Deserialize, Clone)] +pub struct Settings { + pub setup: Option, + pub database: DatabaseConfig, + pub hostname: String, + pub bind: IpAddr, + pub port: u16, + pub tls_enabled: bool, + pub jwt_secret: String, + pub pictrs_url: String, + pub iframely_url: String, + pub rate_limit: RateLimitConfig, + pub email: Option, + pub federation: FederationConfig, + pub captcha: CaptchaConfig, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct Setup { + pub admin_username: String, + pub admin_password: String, + pub admin_email: Option, + pub site_name: String, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct RateLimitConfig { + pub message: i32, + pub message_per_second: i32, + pub post: i32, + pub post_per_second: i32, + pub register: i32, + pub register_per_second: i32, + pub image: i32, + pub image_per_second: i32, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct EmailConfig { + pub smtp_server: String, + pub smtp_login: Option, + pub smtp_password: Option, + pub smtp_from_address: String, + pub use_tls: bool, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct CaptchaConfig { + pub enabled: bool, + // TODO: use enum for this + pub difficulty: String, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct DatabaseConfig { + pub user: String, + pub password: String, + pub host: String, + pub port: i32, + pub database: String, + pub pool_size: u32, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct FederationConfig { + pub enabled: bool, + pub allowed_instances: String, + pub blocked_instances: String, +} diff --git a/crates/utils/src/settings/structs_opt.rs b/crates/utils/src/settings/structs_opt.rs new file mode 100644 index 00000000..1635c090 --- /dev/null +++ b/crates/utils/src/settings/structs_opt.rs @@ -0,0 +1,71 @@ +use serde::Deserialize; +use std::net::IpAddr; + +#[derive(Debug, Deserialize, Clone)] +pub struct SettingsOpt { + pub setup: Option, + pub database: Option, + pub hostname: Option, + pub bind: Option, + pub port: Option, + pub tls_enabled: Option, + pub jwt_secret: Option, + pub pictrs_url: Option, + pub iframely_url: Option, + pub rate_limit: Option, + pub email: Option, + pub federation: Option, + pub captcha: Option, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct SetupOpt { + pub admin_username: Option, + pub admin_password: Option, + pub admin_email: Option>, + pub site_name: Option, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct RateLimitConfigOpt { + pub message: Option, + pub message_per_second: Option, + pub post: Option, + pub post_per_second: Option, + pub register: Option, + pub register_per_second: Option, + pub image: Option, + pub image_per_second: Option, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct EmailConfigOpt { + pub smtp_server: Option, + pub smtp_login: Option>, + pub smtp_password: Option>, + pub smtp_from_address: Option, + pub use_tls: Option, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct CaptchaConfigOpt { + pub enabled: Option, + pub difficulty: Option, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct DatabaseConfigOpt { + pub user: Option, + pub password: Option, + pub host: Option, + pub port: Option, + pub database: Option, + pub pool_size: Option, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct FederationConfigOpt { + pub enabled: Option, + pub allowed_instances: Option, + pub blocked_instances: Option, +} diff --git a/crates/utils/src/utils.rs b/crates/utils/src/utils.rs index 62974356..9ce4c3d9 100644 --- a/crates/utils/src/utils.rs +++ b/crates/utils/src/utils.rs @@ -1,4 +1,4 @@ -use crate::{settings::Settings, APIError}; +use crate::{settings::structs::Settings, APIError}; use actix_web::dev::ConnectionInfo; use chrono::{DateTime, FixedOffset, NaiveDateTime}; use itertools::Itertools; diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml index 78a8484e..6b0519d0 100644 --- a/docker/prod/docker-compose.yml +++ b/docker/prod/docker-compose.yml @@ -28,7 +28,7 @@ services: lemmy-ui: image: dessalines/lemmy-ui:0.9.7 ports: - - "1235:1234" + - "127.0.0.1:1235:1234" restart: always environment: - LEMMY_INTERNAL_HOST=lemmy:8536 diff --git a/src/code_migrations.rs b/src/code_migrations.rs index 7478d5af..d520664f 100644 --- a/src/code_migrations.rs +++ b/src/code_migrations.rs @@ -24,7 +24,7 @@ use lemmy_db_schema::{ user::{UserForm, User_}, }, }; -use lemmy_utils::{apub::generate_actor_keypair, settings::Settings, LemmyError}; +use lemmy_utils::{apub::generate_actor_keypair, settings::structs::Settings, LemmyError}; use log::info; pub fn run_advanced_migrations(conn: &PgConnection) -> Result<(), LemmyError> { diff --git a/src/main.rs b/src/main.rs index 4ebedb4f..21c4e457 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ use lemmy_server::{code_migrations::run_advanced_migrations, scheduled_tasks}; use lemmy_structs::blocking; use lemmy_utils::{ rate_limit::{rate_limiter::RateLimiter, RateLimit}, - settings::Settings, + settings::structs::Settings, LemmyError, }; use lemmy_websocket::{chat_server::ChatServer, LemmyContext}; diff --git a/tests/integration_test.rs b/tests/integration_test.rs index f205ceb5..e82ac9e2 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -39,7 +39,7 @@ use lemmy_server::code_migrations::run_advanced_migrations; use lemmy_utils::{ apub::generate_actor_keypair, rate_limit::{rate_limiter::RateLimiter, RateLimit}, - settings::Settings, + settings::structs::Settings, }; use lemmy_websocket::{chat_server::ChatServer, LemmyContext}; use reqwest::Client;