]> Untitled Git - lemmy.git/commitdiff
Rewrite settings implementation. Fixes #1270 (#1433)
authorDessalines <dessalines@users.noreply.github.com>
Mon, 1 Mar 2021 17:24:11 +0000 (12:24 -0500)
committerGitHub <noreply@github.com>
Mon, 1 Mar 2021 17:24:11 +0000 (17:24 +0000)
* A first attempt at using deser-hjson. Fixes #1270

* Trying to fix tests, try 1

* Trying to fix tests, try 2

* A few fixes to deser_hjson

- Removing unwrap_or_defaults, using impl functions.
- Reorganized settings

* Make clippy happy

* hjson list strings must be quoted.

* Adding support for env vars.

* Moving to structs and defaults file.

* Moving settings default and struct.

47 files changed:
Cargo.lock
ansible/templates/config.hjson
api_tests/prepare-drone-federation-test.sh
config/defaults.hjson
crates/api/src/lib.rs
crates/api/src/site.rs
crates/api/src/user.rs
crates/api_structs/src/lib.rs
crates/api_structs/src/site.rs
crates/apub/src/activities/send/comment.rs
crates/apub/src/activities/send/mod.rs
crates/apub/src/activity_queue.rs
crates/apub/src/fetcher/search.rs
crates/apub/src/http/mod.rs
crates/apub/src/inbox/mod.rs
crates/apub/src/lib.rs
crates/apub/src/objects/mod.rs
crates/apub/src/objects/user.rs
crates/apub/src/routes.rs
crates/db_queries/src/source/user.rs
crates/routes/src/feeds.rs
crates/routes/src/images.rs
crates/routes/src/nodeinfo.rs
crates/routes/src/webfinger.rs
crates/utils/Cargo.toml
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.rs [deleted file]
crates/utils/src/settings/defaults.rs [new file with mode: 0644]
crates/utils/src/settings/mod.rs [new file with mode: 0644]
crates/utils/src/settings/structs.rs [new file with mode: 0644]
crates/utils/src/utils.rs
docker/dev/Dockerfile
docker/federation/docker-compose.yml
docker/federation/lemmy_alpha.hjson [new file with mode: 0644]
docker/federation/lemmy_beta.hjson [new file with mode: 0644]
docker/federation/lemmy_delta.hjson [new file with mode: 0644]
docker/federation/lemmy_epsilon.hjson [new file with mode: 0644]
docker/federation/lemmy_gamma.hjson [new file with mode: 0644]
docker/lemmy.hjson
docker/prod/Dockerfile
docker/prod/Dockerfile.arm
src/code_migrations.rs
src/main.rs

index 13d67faa538a184924c088abd5a7f6b6f570adef..69b22f9561d7ade226dbbd64bcce320dec7cf658 100644 (file)
@@ -10,7 +10,7 @@ checksum = "fe7ceed015dfca322d3bcec3653909c77557e7e57df72e98cb8806e2c93cc919"
 dependencies = [
  "chrono",
  "mime",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "thiserror",
  "url",
@@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bb8e19a0810cc25df3535061a08b7d8f8a734d309ea4411c57a9767e4a2ffa0e"
 dependencies = [
  "activitystreams",
- "serde 1.0.123",
+ "serde",
  "serde_json",
 ]
 
@@ -130,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",
@@ -158,7 +158,7 @@ dependencies = [
  "http",
  "log",
  "regex",
- "serde 1.0.123",
+ "serde",
 ]
 
 [[package]]
@@ -302,7 +302,7 @@ dependencies = [
  "pin-project 1.0.4",
  "regex",
  "rustls",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "serde_urlencoded",
  "socket2",
@@ -391,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"
@@ -466,7 +460,7 @@ dependencies = [
  "percent-encoding",
  "rand 0.7.3",
  "rustls",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "serde_urlencoded",
 ]
@@ -496,7 +490,7 @@ dependencies = [
  "log",
  "num_cpus",
  "rand 0.7.3",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "thiserror",
  "tokio 0.2.25",
@@ -515,7 +509,7 @@ dependencies = [
  "async-trait",
  "chrono",
  "log",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "thiserror",
  "tokio 0.2.25",
@@ -735,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",
 ]
@@ -783,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"
@@ -997,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"
@@ -1112,6 +1103,15 @@ dependencies = [
  "termcolor",
 ]
 
+[[package]]
+name = "envy"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "event-listener"
 version = "2.5.1"
@@ -1592,7 +1592,7 @@ dependencies = [
  "jpeg-decoder",
  "num-iter",
  "num-rational",
- "num-traits 0.2.14",
+ "num-traits",
  "png",
  "scoped_threadpool",
  "tiff",
@@ -1686,7 +1686,7 @@ dependencies = [
  "base64 0.12.3",
  "pem",
  "ring",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "simple_asn1",
 ]
@@ -1747,7 +1747,7 @@ dependencies = [
  "openssl",
  "rand 0.8.3",
  "reqwest",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "sha2",
  "strum",
@@ -1772,7 +1772,7 @@ dependencies = [
  "lemmy_db_views_moderator",
  "lemmy_utils",
  "log",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "url",
 ]
@@ -1813,7 +1813,7 @@ dependencies = [
  "percent-encoding",
  "rand 0.8.3",
  "reqwest",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "sha2",
  "strum",
@@ -1837,7 +1837,7 @@ dependencies = [
  "lemmy_utils",
  "log",
  "regex",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "serial_test",
  "sha2",
@@ -1853,7 +1853,7 @@ dependencies = [
  "chrono",
  "diesel",
  "log",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "url",
 ]
@@ -1866,7 +1866,7 @@ dependencies = [
  "lemmy_db_queries",
  "lemmy_db_schema",
  "log",
- "serde 1.0.123",
+ "serde",
  "serial_test",
  "url",
 ]
@@ -1878,7 +1878,7 @@ dependencies = [
  "diesel",
  "lemmy_db_queries",
  "lemmy_db_schema",
- "serde 1.0.123",
+ "serde",
 ]
 
 [[package]]
@@ -1888,7 +1888,7 @@ dependencies = [
  "diesel",
  "lemmy_db_queries",
  "lemmy_db_schema",
- "serde 1.0.123",
+ "serde",
 ]
 
 [[package]]
@@ -1912,7 +1912,7 @@ dependencies = [
  "lemmy_websocket",
  "log",
  "rss",
- "serde 1.0.123",
+ "serde",
  "sha2",
  "strum",
  "url",
@@ -1948,7 +1948,7 @@ dependencies = [
  "log",
  "openssl",
  "reqwest",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "strum",
  "tokio 0.3.7",
@@ -1964,8 +1964,9 @@ dependencies = [
  "anyhow",
  "chrono",
  "comrak",
- "config",
+ "deser-hjson",
  "diesel",
+ "envy",
  "futures",
  "http",
  "itertools",
@@ -1973,12 +1974,13 @@ dependencies = [
  "lazy_static",
  "lettre",
  "log",
+ "merge",
  "openssl",
  "percent-encoding",
  "rand 0.8.3",
  "regex",
  "reqwest",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "strum",
  "strum_macros",
@@ -2005,7 +2007,7 @@ dependencies = [
  "log",
  "rand 0.8.3",
  "reqwest",
- "serde 1.0.123",
+ "serde",
  "serde_json",
  "strum",
  "strum_macros",
@@ -2024,46 +2026,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"
@@ -2106,7 +2085,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]]
@@ -2148,6 +2127,28 @@ dependencies = [
  "autocfg",
 ]
 
+[[package]]
+name = "merge"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
+dependencies = [
+ "merge_derive",
+ "num-traits",
+]
+
+[[package]]
+name = "merge_derive"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
+dependencies = [
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "migrations_internals"
 version = "1.4.1"
@@ -2275,17 +2276,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"
@@ -2305,7 +2295,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
 dependencies = [
  "autocfg",
  "num-integer",
- "num-traits 0.2.14",
+ "num-traits",
 ]
 
 [[package]]
@@ -2315,7 +2305,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
 dependencies = [
  "autocfg",
- "num-traits 0.2.14",
+ "num-traits",
 ]
 
 [[package]]
@@ -2326,7 +2316,7 @@ checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
 dependencies = [
  "autocfg",
  "num-integer",
- "num-traits 0.2.14",
+ "num-traits",
 ]
 
 [[package]]
@@ -2337,16 +2327,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]]
@@ -2601,6 +2582,30 @@ dependencies = [
  "vcpkg",
 ]
 
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
 [[package]]
 name = "proc-macro-hack"
 version = "0.5.19"
@@ -2842,7 +2847,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",
@@ -3012,12 +3017,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"
@@ -3027,19 +3026,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"
@@ -3060,16 +3046,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]]
@@ -3081,7 +3058,7 @@ dependencies = [
  "form_urlencoded",
  "itoa",
  "ryu",
- "serde 1.0.123",
+ "serde",
 ]
 
 [[package]]
@@ -3173,7 +3150,7 @@ checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b"
 dependencies = [
  "chrono",
  "num-bigint",
- "num-traits 0.2.14",
+ "num-traits",
 ]
 
 [[package]]
@@ -3214,12 +3191,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"
@@ -3242,7 +3213,7 @@ checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
 dependencies = [
  "proc-macro2",
  "quote",
- "serde 1.0.123",
+ "serde",
  "serde_derive",
  "syn",
 ]
@@ -3256,7 +3227,7 @@ dependencies = [
  "base-x",
  "proc-macro2",
  "quote",
- "serde 1.0.123",
+ "serde",
  "serde_derive",
  "serde_json",
  "sha1",
@@ -3692,7 +3663,7 @@ dependencies = [
  "idna",
  "matches",
  "percent-encoding",
- "serde 1.0.123",
+ "serde",
 ]
 
 [[package]]
@@ -3702,7 +3673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
 dependencies = [
  "getrandom 0.2.2",
- "serde 1.0.123",
+ "serde",
 ]
 
 [[package]]
@@ -3746,7 +3717,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",
 ]
index 29da81c3455abb4480b8f133417a3c9416f32827..55537ca50ca944114ab2d2b8b30b69f6c7b9ec59 100644 (file)
@@ -29,8 +29,9 @@
     # https://join.lemmy.ml/docs/en/federation/administration.html#instance-allowlist-and-blocklist
     #
     # comma separated list of instances with which federation is allowed
-    # allowed_instances: ""
+    # Only one of these blocks should be uncommented
+    # allowed_instances: ["instance1.tld","instance2.tld"]
     # comma separated list of instances which are blocked from federating
-    # blocked_instances: ""
+    # blocked_instances: []
   }
 }
index de9b7b8444311e47981c367757d941b34fb9ee5b..dd357db83e83e1927ae37618fa490148eed2bd35 100755 (executable)
@@ -1,13 +1,6 @@
 #!/bin/bash
 set -e
 
-export LEMMY_JWT_SECRET=changeme
-export LEMMY_FEDERATION__ENABLED=true
-export LEMMY_TLS_ENABLED=false
-export LEMMY_SETUP__ADMIN_PASSWORD=lemmy
-export LEMMY_RATE_LIMIT__POST=99999
-export LEMMY_RATE_LIMIT__REGISTER=99999
-export LEMMY_CAPTCHA__ENABLED=false
 export LEMMY_TEST_SEND_SYNC=1
 export RUST_BACKTRACE=1
 
@@ -35,52 +28,40 @@ fi
 
 killall lemmy_server || true
 
+echo "$PWD"
+
 echo "start alpha"
 LEMMY_HOSTNAME=lemmy-alpha:8541 \
-  LEMMY_PORT=8541 \
+  LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_alpha.hjson \
   LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_alpha" \
-  LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon \
-  LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha \
-  LEMMY_SETUP__SITE_NAME=lemmy-alpha \
-  target/lemmy_server >/dev/null 2>&1 &
+  LEMMY_HOSTNAME="lemmy-alpha:8541" \
+  target/lemmy_server >/tmp/lemmy_alpha.out 2>&1 &
 
 echo "start beta"
 LEMMY_HOSTNAME=lemmy-beta:8551 \
-  LEMMY_PORT=8551 \
+  LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_beta.hjson \
   LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_beta" \
-  LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon \
-  LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta \
-  LEMMY_SETUP__SITE_NAME=lemmy-beta \
-  target/lemmy_server >/dev/null 2>&1 &
+  target/lemmy_server >/tmp/lemmy_beta.out 2>&1 &
 
 echo "start gamma"
 LEMMY_HOSTNAME=lemmy-gamma:8561 \
-  LEMMY_PORT=8561 \
+  LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_gamma.hjson \
   LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_gamma" \
-  LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon \
-  LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma \
-  LEMMY_SETUP__SITE_NAME=lemmy-gamma \
-  target/lemmy_server >/dev/null 2>&1 &
+  target/lemmy_server >/tmp/lemmy_gamma.out 2>&1 &
 
 echo "start delta"
 # An instance with only an allowlist for beta
 LEMMY_HOSTNAME=lemmy-delta:8571 \
-  LEMMY_PORT=8571 \
+  LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_delta.hjson \
   LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_delta" \
-  LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta \
-  LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta \
-  LEMMY_SETUP__SITE_NAME=lemmy-delta \
-  target/lemmy_server >/dev/null 2>&1 &
+  target/lemmy_server >/tmp/lemmy_delta.out 2>&1 &
 
 echo "start epsilon"
 # An instance who has a blocklist, with lemmy-alpha blocked
 LEMMY_HOSTNAME=lemmy-epsilon:8581 \
-  LEMMY_PORT=8581 \
+  LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_epsilon.hjson \
   LEMMY_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_epsilon" \
-  LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha \
-  LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon \
-  LEMMY_SETUP__SITE_NAME=lemmy-epsilon \
-  target/lemmy_server >/dev/null 2>&1 &
+  target/lemmy_server >/tmp/lemmy_epsilon.out 2>&1 &
 
 echo "wait for all instances to start"
 while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8541/api/v2/site')" != "200" ]]; do sleep 1; done
index 6c6a68fc2d55c896f4759f021b383986d77ccef7..c3eaba6e5aa316f2effde3018f2732f26aece1ee 100644 (file)
     # https://join.lemmy.ml/docs/en/federation/administration.html#instance-allowlist-and-blocklist
     #
     # comma separated list of instances with which federation is allowed
-    allowed_instances: ""
+    # Only one of these blocks should be uncommented
+    # allowed_instances: ["instance1.tld","instance2.tld"]
     # comma separated list of instances which are blocked from federating
-    blocked_instances: ""
+    # blocked_instances: []
   }
   captcha: {
     enabled: true
index 871e8e9d8b21f81493b1b0420ba2e18f8a67e868..6f4ea8f4dec508fb392b5b09613f9e2e39c8b3ef 100644 (file)
@@ -27,7 +27,13 @@ use lemmy_db_views_actor::{
   community_user_ban_view::CommunityUserBanView,
   community_view::CommunityView,
 };
-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;
@@ -192,7 +198,7 @@ pub(crate) fn check_optional_url(item: &Option<Option<String>>) -> Result<(), Le
 pub(crate) async fn build_federated_instances(
   pool: &DbPool,
 ) -> Result<Option<FederatedInstances>, LemmyError> {
-  if Settings::get().federation.enabled {
+  if Settings::get().federation().enabled {
     let distinct_communities = blocking(pool, move |conn| {
       Community::distinct_federated_communities(conn)
     })
@@ -206,8 +212,13 @@ pub(crate) async fn build_federated_instances(
       .map(|actor_id| Ok(Url::parse(actor_id)?.host_str().unwrap_or("").to_string()))
       .collect::<Result<Vec<String>, LemmyError>>()?;
 
-    linked.extend_from_slice(&allowed);
-    linked.retain(|a| !blocked.contains(a) && !a.eq("") && !a.eq(&Settings::get().hostname));
+    if let Some(allowed) = allowed.as_ref() {
+      linked.extend_from_slice(allowed);
+    }
+
+    if let Some(blocked) = blocked.as_ref() {
+      linked.retain(|a| !blocked.contains(a) && !a.eq(&Settings::get().hostname()));
+    }
 
     // Sort and remove dupes
     linked.sort_unstable();
index 716b67237eb65f502e87dbda0f7fbaad58797e34..c4792f369c3e047c5ee827c35513595f30d6d531 100644 (file)
@@ -41,7 +41,7 @@ use lemmy_db_views_moderator::{
 };
 use lemmy_utils::{
   location_info,
-  settings::Settings,
+  settings::structs::Settings,
   utils::{check_slurs, check_slurs_opt},
   version,
   ApiError,
@@ -245,7 +245,7 @@ impl Perform 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) = Settings::get().setup().as_ref() {
           let register = Register {
             username: setup.admin_username.to_owned(),
             email: setup.admin_email.to_owned(),
index d6395e6b743691abaf1ad3c077cf99934213e974..6d37581e08fca0b96f152883e774c11c4b61bbb8 100644 (file)
@@ -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,
@@ -121,7 +121,7 @@ impl Perform for Login {
 
     // Return the jwt
     Ok(LoginResponse {
-      jwt: Claims::jwt(user.id, Settings::get().hostname)?,
+      jwt: Claims::jwt(user.id, Settings::get().hostname())?,
     })
   }
 }
@@ -161,7 +161,7 @@ impl Perform for Register {
     .await??;
 
     // If its not the admin, check the captcha
-    if !no_admins && Settings::get().captcha.enabled {
+    if !no_admins && Settings::get().captcha().enabled {
       let check = context
         .chat_server()
         .send(CheckCaptcha {
@@ -302,7 +302,7 @@ impl Perform for Register {
 
     // Return the jwt
     Ok(LoginResponse {
-      jwt: Claims::jwt(inserted_user.id, Settings::get().hostname)?,
+      jwt: Claims::jwt(inserted_user.id, Settings::get().hostname())?,
     })
   }
 }
@@ -316,7 +316,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 = Settings::get().captcha();
 
     if !captcha_settings.enabled {
       return Ok(GetCaptchaResponse { ok: None });
@@ -475,7 +475,7 @@ impl Perform for SaveUserSettings {
 
     // Return the jwt
     Ok(LoginResponse {
-      jwt: Claims::jwt(updated_user.id, Settings::get().hostname)?,
+      jwt: Claims::jwt(updated_user.id, Settings::get().hostname())?,
     })
   }
 }
@@ -1011,7 +1011,7 @@ impl Perform for PasswordChange {
 
     // Return the jwt
     Ok(LoginResponse {
-      jwt: Claims::jwt(updated_user.id, Settings::get().hostname)?,
+      jwt: Claims::jwt(updated_user.id, Settings::get().hostname())?,
     })
   }
 }
index 8b56fab6b9c970c63e3dea3810a079b049ac9a06..800fe6c8bb6d27aa18283edc5bb3cc4194f79599 100644 (file)
@@ -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;
@@ -152,7 +152,7 @@ pub fn send_email_to_user(user: User_, subject_text: &str, body_text: &str, comm
     let subject = &format!(
       "{} - {} {}",
       subject_text,
-      Settings::get().hostname,
+      Settings::get().hostname(),
       user.name,
     );
     let html = &format!(
index ef878ba523d3c1664f75bba552b8cdabdaf13c06..edee17a85bc151517d601660e9a0a2bdab921b0b 100644 (file)
@@ -126,6 +126,6 @@ pub struct SaveSiteConfig {
 #[derive(Serialize)]
 pub struct FederatedInstances {
   pub linked: Vec<String>,
-  pub allowed: Vec<String>,
-  pub blocked: Vec<String>,
+  pub allowed: Option<Vec<String>>,
+  pub blocked: Option<Vec<String>>,
 }
index f33de2ba7300701189c6b301665fa502cc2bfc01..ac7e884a959252db416f1246b22a8b2f11fb6955 100644 (file)
@@ -31,7 +31,7 @@ use lemmy_db_queries::{Crud, DbPool};
 use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post, user::User_};
 use lemmy_utils::{
   request::{retry, RecvError},
-  settings::Settings,
+  settings::structs::Settings,
   utils::{scrape_text_for_mentions, MentionData},
   LemmyError,
 };
index 166855e204c7592f674fd7f1da7edff1e4412a97..2da0b48c2d28bb152893739e071634ccdcbfb3c8 100644 (file)
@@ -1,4 +1,4 @@
-use lemmy_utils::settings::Settings;
+use lemmy_utils::settings::structs::Settings;
 use url::{ParseError, Url};
 use uuid::Uuid;
 
index c0c4ac46808759053e1245f56ad561014b5c5947..152fcaf9b716a719e62cb3692323263fda8a2b7c 100644 (file)
@@ -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;
@@ -88,7 +88,7 @@ where
     .await?
     .iter()
     .unique()
-    .filter(|inbox| inbox.host_str() != Some(&Settings::get().hostname))
+    .filter(|inbox| inbox.host_str() != Some(&Settings::get().hostname()))
     .filter(|inbox| check_is_apub_id_valid(inbox).is_ok())
     .map(|inbox| inbox.to_owned())
     .collect();
@@ -215,7 +215,7 @@ where
   Kind: Serialize,
   <T as Extends<Kind>>::Error: From<serde_json::Error> + Send + Sync + 'static,
 {
-  if !Settings::get().federation.enabled || inboxes.is_empty() {
+  if !Settings::get().federation().enabled || inboxes.is_empty() {
     return Ok(());
   }
 
index 6cbc42dc69fd8aba73b8ddaebc85a631cf709a45..acaccff280855d28fc767c9ea25e90b454d61f08 100644 (file)
@@ -35,7 +35,7 @@ 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_utils::{settings::Settings, LemmyError};
+use lemmy_utils::{settings::structs::Settings, LemmyError};
 use lemmy_websocket::LemmyContext;
 use log::debug;
 use url::Url;
index ae8a3632aa59310b23732b0383b6f1b189a74a9d..f117b6ea2d27a681d1f88aa93fb092549ff35f0c 100644 (file)
@@ -4,7 +4,7 @@ use http::StatusCode;
 use lemmy_api_structs::blocking;
 use lemmy_db_queries::source::activity::Activity_;
 use lemmy_db_schema::source::activity::Activity;
-use lemmy_utils::{settings::Settings, LemmyError};
+use lemmy_utils::{settings::structs::Settings, LemmyError};
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 
index 4f5b04633c9de00596ada84e22b699e2ad20d6b8..2adefabe7893144323179905fb4f8edb0f5e8a24 100644 (file)
@@ -19,7 +19,7 @@ use lemmy_db_queries::{
   DbPool,
 };
 use lemmy_db_schema::source::{activity::Activity, 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 serde::Serialize;
 use std::fmt::Debug;
@@ -167,7 +167,7 @@ where
   let id = activity.id_unchecked().context(location_info!())?;
   let activity_domain = id.domain().context(location_info!())?;
 
-  if activity_domain == Settings::get().hostname {
+  if activity_domain == Settings::get().hostname() {
     return Err(
       anyhow!(
         "Error: received activity which was sent by local instance: {:?}",
index c010a29bdf83c75c1c4de7d08559801434e4f426..5c0b267a6d4a64f328fc54230f8e3d4af2b241bb 100644 (file)
@@ -34,7 +34,7 @@ use lemmy_db_schema::source::{
   private_message::PrivateMessage,
   user::User_,
 };
-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;
@@ -64,7 +64,7 @@ fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> {
   let domain = apub_id.domain().context(location_info!())?.to_string();
   let local_instance = settings.get_hostname_without_port()?;
 
-  if !settings.federation.enabled {
+  if !settings.federation().enabled {
     return if domain == local_instance {
       Ok(())
     } else {
@@ -88,22 +88,23 @@ fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> {
     return Err(anyhow!("invalid apub id scheme {}: {}", apub_id.scheme(), apub_id).into());
   }
 
-  let mut allowed_instances = Settings::get().get_allowed_instances();
+  let allowed_instances = Settings::get().get_allowed_instances();
   let blocked_instances = Settings::get().get_blocked_instances();
-  if allowed_instances.is_empty() && blocked_instances.is_empty() {
+
+  if allowed_instances.is_none() && blocked_instances.is_none() {
     Ok(())
-  } else if !allowed_instances.is_empty() {
+  } else if let Some(mut allowed) = allowed_instances {
     // need to allow this explicitly because apub receive might contain objects from our local
     // instance. split is needed to remove the port in our federation test setup.
-    allowed_instances.push(local_instance);
+    allowed.push(local_instance);
 
-    if allowed_instances.contains(&domain) {
+    if allowed.contains(&domain) {
       Ok(())
     } else {
       Err(anyhow!("{} not in federation allowlist", domain).into())
     }
-  } else if !blocked_instances.is_empty() {
-    if blocked_instances.contains(&domain) {
+  } else if let Some(blocked) = blocked_instances {
+    if blocked.contains(&domain) {
       Err(anyhow!("{} is in federation blocklist", domain).into())
     } else {
       Ok(())
index 42e8bb6285cce1086510ded20d084fcb4cd59a00..5667e1001143f4f59c663952145c8cf7d3e33a0b 100644 (file)
@@ -17,7 +17,7 @@ use lemmy_db_queries::{ApubObject, Crud, DbPool};
 use lemmy_db_schema::source::community::Community;
 use lemmy_utils::{
   location_info,
-  settings::Settings,
+  settings::structs::Settings,
   utils::{convert_datetime, markdown_to_html},
   LemmyError,
 };
@@ -187,7 +187,7 @@ where
   let domain = object_id.domain().context(location_info!())?;
 
   // if its a local object, return it directly from the database
-  if Settings::get().hostname == domain {
+  if Settings::get().hostname() == domain {
     let object = blocking(context.pool(), move |conn| {
       To::read_from_apub_id(conn, &object_id.into())
     })
index aad89567404bad9006ac96844bc16ec8c3de71b4..c979e3ee4a979f13802cfce6b00742e72529f90a 100644 (file)
@@ -26,7 +26,7 @@ use lemmy_db_schema::{
 };
 use lemmy_utils::{
   location_info,
-  settings::Settings,
+  settings::structs::Settings,
   utils::{check_slurs, check_slurs_opt, convert_datetime},
   LemmyError,
 };
@@ -96,7 +96,7 @@ impl FromApub for User_ {
   ) -> Result<User_, LemmyError> {
     let user_id = person.id_unchecked().context(location_info!())?.to_owned();
     let domain = user_id.domain().context(location_info!())?;
-    if domain == Settings::get().hostname {
+    if domain == Settings::get().hostname() {
       let user = blocking(context.pool(), move |conn| {
         User_::read_from_apub_id(conn, &user_id.into())
       })
index 6fa82ea84ce526d2e656e500cf2bb72ca9a1f212..07dcc7f88e5fa84d915bba0b1957ac0edecb86cc 100644 (file)
@@ -16,15 +16,15 @@ 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 =
   "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);
+  if Settings::get().federation().enabled {
+    println!("federation enabled, host is {}", Settings::get().hostname());
     let digest_verifier = VerifyDigest::new(Sha256::new());
 
     let header_guard_accept = guard::Any(guard::Header("Accept", APUB_JSON_CONTENT_TYPE))
index 20b187b46fbe3ae686fba42e3c4b35eebf472ed0..56023f09f29d518fff6f304d1772556eb8fc7e16 100644 (file)
@@ -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;
index b8858f3f9ed54e4f8c5eb053a4feac47dd3c3db3..40d80f25ac2bfd83646234ef0ffca9be74e5807c 100644 (file)
@@ -15,7 +15,12 @@ use lemmy_db_views::{
   site_view::SiteView,
 };
 use lemmy_db_views_actor::user_mention_view::{UserMentionQueryBuilder, UserMentionView};
-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,
@@ -163,7 +168,7 @@ fn get_feed_user(
 ) -> Result<ChannelBuilder, LemmyError> {
   let site_view = SiteView::read(&conn)?;
   let user = User_::find_by_username(&conn, &user_name)?;
-  let user_url = user.get_profile_url(&Settings::get().hostname);
+  let user_url = user.get_profile_url(&Settings::get().hostname());
 
   let posts = PostQueryBuilder::create(&conn)
     .listing_type(&ListingType::All)
index 4d7656e1b2436abf8919a7cf910912d05c671aca..fe23fe029aaae601472652f9c529ad3b051ae137 100644 (file)
@@ -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) {
@@ -54,8 +54,10 @@ async fn upload(
     return Ok(HttpResponse::Unauthorized().finish());
   };
 
-  let mut client_req =
-    client.request_from(format!("{}/image", Settings::get().pictrs_url), req.head());
+  let mut client_req = client.request_from(
+    format!("{}/image", Settings::get().pictrs_url()),
+    req.head(),
+  );
 
   if let Some(addr) = req.head().peer_addr {
     client_req = client_req.header("X-Forwarded-For", addr.to_string())
@@ -78,14 +80,14 @@ async fn full_res(
 
   // If there are no query params, the URL is original
   let url = if params.format.is_none() && params.thumbnail.is_none() {
-    format!("{}/image/original/{}", Settings::get().pictrs_url, name,)
+    format!("{}/image/original/{}", Settings::get().pictrs_url(), 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={}",
-      Settings::get().pictrs_url,
+      Settings::get().pictrs_url(),
       format,
       name,
     );
@@ -134,7 +136,7 @@ async fn delete(
 
   let url = format!(
     "{}/image/delete/{}/{}",
-    Settings::get().pictrs_url,
+    Settings::get().pictrs_url(),
     &token,
     &file
   );
index 058ba8816e1e63527763c92d8ee09dfe28b020d7..1333279cc6bc7d11849a028f576847aca0ad7f87 100644 (file)
@@ -2,7 +2,7 @@ use actix_web::{body::Body, error::ErrorBadRequest, *};
 use anyhow::anyhow;
 use lemmy_api_structs::blocking;
 use lemmy_db_views::site_view::SiteView;
-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;
@@ -31,7 +31,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 Settings::get().federation().enabled {
     vec!["activitypub".to_string()]
   } else {
     vec![]
index 5c5387d58451a438116e5101bd6ec0f9c6dfff76..e044373473355a23970837772905482514388daf 100644 (file)
@@ -4,7 +4,7 @@ use lemmy_api_structs::{blocking, WebFingerLink, WebFingerResponse};
 use lemmy_db_queries::source::{community::Community_, user::User};
 use lemmy_db_schema::source::{community::Community, user::User_};
 use lemmy_utils::{
-  settings::Settings,
+  settings::structs::Settings,
   LemmyError,
   WEBFINGER_COMMUNITY_REGEX,
   WEBFINGER_USER_REGEX,
@@ -18,7 +18,7 @@ struct Params {
 }
 
 pub fn config(cfg: &mut web::ServiceConfig) {
-  if Settings::get().federation.enabled {
+  if Settings::get().federation().enabled {
     cfg.route(
       ".well-known/webfinger",
       web::get().to(get_webfinger_response),
index 3308669a4463464d72882c5ee1344c3debd42b41..bb87cd3014c12ed54219597bf7494cc28ca51234 100644 (file)
@@ -10,7 +10,6 @@ doctest = false
 
 [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"
@@ -35,3 +34,6 @@ futures = "0.3.12"
 diesel = "1.4.5"
 http = "0.2.3"
 jsonwebtoken = "7.2.0"
+deser-hjson = "0.1.12"
+merge = "0.1.0"
+envy = "0.4.2"
index dff79d859ce623fdc6df38d39d5ac04e6aa92088..3d9232e6bf3568b80d6d085d8eeea4109a2747c9 100644 (file)
@@ -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};
 
@@ -18,7 +18,7 @@ impl Claims {
     };
     decode::<Claims>(
       &jwt,
-      &DecodingKey::from_secret(Settings::get().jwt_secret.as_ref()),
+      &DecodingKey::from_secret(Settings::get().jwt_secret().as_ref()),
       &v,
     )
   }
@@ -31,7 +31,7 @@ impl Claims {
     encode(
       &Header::default(),
       &my_claims,
-      &EncodingKey::from_secret(Settings::get().jwt_secret.as_ref()),
+      &EncodingKey::from_secret(Settings::get().jwt_secret().as_ref()),
     )
   }
 }
index 8e61500c0f5190aff6ca249f4bef832dcfd3bec0..ead5349247d3089144d4cb20fc5c1b0b36c8a729 100644 (file)
@@ -1,4 +1,4 @@
-use crate::settings::Settings;
+use crate::settings::structs::Settings;
 use lettre::{
   message::{header, Mailbox, MultiPart, SinglePart},
   transport::smtp::{
@@ -19,8 +19,8 @@ pub fn send_email(
   to_username: &str,
   html: &str,
 ) -> Result<(), String> {
-  let email_config = Settings::get().email.ok_or("no_email_setup")?;
-  let domain = Settings::get().hostname;
+  let email_config = Settings::get().email().ok_or("no_email_setup")?;
+  let domain = Settings::get().hostname();
 
   let (smtp_server, smtp_port) = {
     let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>();
index e64271568118e5399f858f3d1d7417a77ed4c989..58d2abb9d7f5769f6e01f86aebb7cbf9bda0c9e3 100644 (file)
@@ -9,12 +9,13 @@ pub mod email;
 pub mod rate_limit;
 pub mod request;
 pub mod settings;
+
 #[cfg(test)]
 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;
@@ -83,12 +84,12 @@ impl actix_web::error::ResponseError for LemmyError {
 lazy_static! {
   pub static ref WEBFINGER_COMMUNITY_REGEX: Regex = Regex::new(&format!(
     "^group:([a-z0-9_]{{3, 20}})@{}$",
-    Settings::get().hostname
+    Settings::get().hostname()
   ))
   .unwrap();
   pub static ref WEBFINGER_USER_REGEX: Regex = Regex::new(&format!(
     "^acct:([a-z0-9_]{{3, 20}})@{}$",
-    Settings::get().hostname
+    Settings::get().hostname()
   ))
   .unwrap();
 }
index 5a18ffd5494943bb32c141d23737d76b42ad38b6..d3e74ed5bc40ad97360d55b9fa5b91618333d2c8 100644 (file)
@@ -1,5 +1,5 @@
 use crate::{
-  settings::{RateLimitConfig, Settings},
+  settings::structs::{RateLimitConfig, Settings},
   utils::get_ip,
   LemmyError,
 };
@@ -70,7 +70,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;
+    let rate_limit: RateLimitConfig = Settings::get().rate_limit();
 
     // before
     {
index c3207ddddbf1ef07535b8ef7a5539a8d6d5a4a19..428d7897463cc614e60fe0ef1f1910ee03824bef 100644 (file)
@@ -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};
@@ -58,7 +58,7 @@ pub(crate) async fn fetch_iframely(
   client: &Client,
   url: &str,
 ) -> Result<IframelyResponse, LemmyError> {
-  let fetch_url = format!("{}/oembed?url={}", Settings::get().iframely_url, url);
+  let fetch_url = format!("{}/oembed?url={}", Settings::get().iframely_url(), url);
 
   let response = retry(|| client.get(&fetch_url).send()).await?;
 
@@ -89,7 +89,7 @@ pub(crate) async fn fetch_pictrs(
 
   let fetch_url = format!(
     "{}/image/download?url={}",
-    Settings::get().pictrs_url,
+    Settings::get().pictrs_url(),
     utf8_percent_encode(image_url, NON_ALPHANUMERIC) // TODO this might not be needed
   );
 
diff --git a/crates/utils/src/settings.rs b/crates/utils/src/settings.rs
deleted file mode 100644 (file)
index 8301dce..0000000
+++ /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<Setup>,
-  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<EmailConfig>,
-  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<String>,
-  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<String>,
-  pub smtp_password: Option<String>,
-  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<Settings> = 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<Self, ConfigError> {
-    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<String, Error> {
-    fs::read_to_string(Self::get_config_location())
-  }
-
-  pub fn get_allowed_instances(&self) -> Vec<String> {
-    let mut allowed_instances: Vec<String> = 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<String> {
-    let mut blocked_instances: Vec<String> = 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<String, anyhow::Error> {
-    Ok(
-      self
-        .hostname
-        .split(':')
-        .collect::<Vec<&str>>()
-        .first()
-        .context(location_info!())?
-        .to_string(),
-    )
-  }
-
-  pub fn save_config_file(data: &str) -> Result<String, Error> {
-    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 (file)
index 0000000..56d24c7
--- /dev/null
@@ -0,0 +1,69 @@
+use crate::settings::{CaptchaConfig, DatabaseConfig, FederationConfig, RateLimitConfig, Settings};
+use std::net::{IpAddr, Ipv4Addr};
+
+impl Default for Settings {
+  fn default() -> Self {
+    Self {
+      database: Some(DatabaseConfig::default()),
+      rate_limit: Some(RateLimitConfig::default()),
+      federation: Some(FederationConfig::default()),
+      captcha: Some(CaptchaConfig::default()),
+      email: None,
+      setup: None,
+      hostname: None,
+      bind: Some(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))),
+      port: Some(8536),
+      tls_enabled: Some(true),
+      jwt_secret: Some("changeme".into()),
+      pictrs_url: Some("http://pictrs:8080".into()),
+      iframely_url: Some("http://iframely".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 CaptchaConfig {
+  fn default() -> Self {
+    Self {
+      enabled: true,
+      difficulty: "medium".into(),
+    }
+  }
+}
+
+impl Default for FederationConfig {
+  fn default() -> Self {
+    Self {
+      enabled: false,
+      allowed_instances: None,
+      blocked_instances: None,
+    }
+  }
+}
+
+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,
+    }
+  }
+}
diff --git a/crates/utils/src/settings/mod.rs b/crates/utils/src/settings/mod.rs
new file mode 100644 (file)
index 0000000..abd6f73
--- /dev/null
@@ -0,0 +1,172 @@
+use crate::{
+  location_info,
+  settings::structs::{
+    CaptchaConfig,
+    DatabaseConfig,
+    EmailConfig,
+    FederationConfig,
+    RateLimitConfig,
+    Settings,
+    SetupConfig,
+  },
+  LemmyError,
+};
+use anyhow::{anyhow, Context};
+use deser_hjson::from_str;
+use merge::Merge;
+use std::{env, fs, io::Error, net::IpAddr, sync::RwLock};
+
+pub(crate) mod defaults;
+pub mod structs;
+
+static CONFIG_FILE: &str = "config/config.hjson";
+
+lazy_static! {
+  static ref SETTINGS: RwLock<Settings> = 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<Self, LemmyError> {
+    // Read the config file
+    let mut custom_config = from_str::<Settings>(&Self::read_config_file()?)?;
+
+    // Merge with env vars
+    custom_config.merge(envy::prefixed("LEMMY_").from_env::<Settings>()?);
+
+    // Merge with default
+    custom_config.merge(Settings::default());
+
+    if custom_config.hostname == Settings::default().hostname {
+      return Err(anyhow!("Hostname variable is not set!").into());
+    }
+
+    Ok(custom_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();
+    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() -> Result<String, Error> {
+    fs::read_to_string(Self::get_config_location())
+  }
+
+  pub fn get_allowed_instances(&self) -> Option<Vec<String>> {
+    self.federation().allowed_instances
+  }
+
+  pub fn get_blocked_instances(&self) -> Option<Vec<String>> {
+    self.federation().blocked_instances
+  }
+
+  /// Returns either "http" or "https", depending on tls_enabled setting
+  pub fn get_protocol_string(&self) -> &'static str {
+    if let Some(tls_enabled) = self.tls_enabled {
+      if tls_enabled {
+        "https"
+      } else {
+        "http"
+      }
+    } 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<String, anyhow::Error> {
+    Ok(
+      self
+        .hostname()
+        .split(':')
+        .collect::<Vec<&str>>()
+        .first()
+        .context(location_info!())?
+        .to_string(),
+    )
+  }
+
+  pub fn save_config_file(data: &str) -> Result<String, Error> {
+    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()
+  }
+
+  pub fn database(&self) -> DatabaseConfig {
+    self.database.to_owned().unwrap_or_default()
+  }
+  pub fn hostname(&self) -> String {
+    self.hostname.to_owned().unwrap_or_default()
+  }
+  pub fn bind(&self) -> IpAddr {
+    self.bind.unwrap()
+  }
+  pub fn port(&self) -> u16 {
+    self.port.unwrap_or_default()
+  }
+  pub fn tls_enabled(&self) -> bool {
+    self.tls_enabled.unwrap_or_default()
+  }
+  pub fn jwt_secret(&self) -> String {
+    self.jwt_secret.to_owned().unwrap_or_default()
+  }
+  pub fn pictrs_url(&self) -> String {
+    self.pictrs_url.to_owned().unwrap_or_default()
+  }
+  pub fn iframely_url(&self) -> String {
+    self.iframely_url.to_owned().unwrap_or_default()
+  }
+  pub fn rate_limit(&self) -> RateLimitConfig {
+    self.rate_limit.to_owned().unwrap_or_default()
+  }
+  pub fn federation(&self) -> FederationConfig {
+    self.federation.to_owned().unwrap_or_default()
+  }
+  pub fn captcha(&self) -> CaptchaConfig {
+    self.captcha.to_owned().unwrap_or_default()
+  }
+  pub fn email(&self) -> Option<EmailConfig> {
+    self.email.to_owned()
+  }
+  pub fn setup(&self) -> Option<SetupConfig> {
+    self.setup.to_owned()
+  }
+}
diff --git a/crates/utils/src/settings/structs.rs b/crates/utils/src/settings/structs.rs
new file mode 100644 (file)
index 0000000..21d89b9
--- /dev/null
@@ -0,0 +1,72 @@
+use merge::Merge;
+use serde::Deserialize;
+use std::net::IpAddr;
+
+#[derive(Debug, Deserialize, Clone, Merge)]
+pub struct Settings {
+  pub(crate) database: Option<DatabaseConfig>,
+  pub(crate) rate_limit: Option<RateLimitConfig>,
+  pub(crate) federation: Option<FederationConfig>,
+  pub(crate) hostname: Option<String>,
+  pub(crate) bind: Option<IpAddr>,
+  pub(crate) port: Option<u16>,
+  pub(crate) tls_enabled: Option<bool>,
+  pub(crate) jwt_secret: Option<String>,
+  pub(crate) pictrs_url: Option<String>,
+  pub(crate) iframely_url: Option<String>,
+  pub(crate) captcha: Option<CaptchaConfig>,
+  pub(crate) email: Option<EmailConfig>,
+  pub(crate) setup: Option<SetupConfig>,
+}
+
+#[derive(Debug, Deserialize, Clone)]
+pub struct CaptchaConfig {
+  pub enabled: bool,
+  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 EmailConfig {
+  pub smtp_server: String,
+  pub smtp_login: Option<String>,
+  pub smtp_password: Option<String>,
+  pub smtp_from_address: String,
+  pub use_tls: bool,
+}
+
+#[derive(Debug, Deserialize, Clone)]
+pub struct FederationConfig {
+  pub enabled: bool,
+  pub allowed_instances: Option<Vec<String>>,
+  pub blocked_instances: Option<Vec<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 SetupConfig {
+  pub admin_username: String,
+  pub admin_password: String,
+  pub admin_email: Option<String>,
+  pub site_name: String,
+}
index e0bbb88e784f7ef4c2d28e4cd6674ff946bca87a..98eada07edbe67fabaf606acb75942b6214bdd98 100644 (file)
@@ -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;
@@ -85,7 +85,7 @@ pub struct MentionData {
 
 impl MentionData {
   pub fn is_local(&self) -> bool {
-    Settings::get().hostname.eq(&self.domain)
+    Settings::get().hostname().eq(&self.domain)
   }
   pub fn full_name(&self) -> String {
     format!("@{}@{}", &self.name, &self.domain)
index 3e3963d295d85a33b6e7a1f73c6ff413d653967f..1d3775ff3c08a592cb81c19b3cbcbaf4bd2fb0ce 100644 (file)
@@ -56,7 +56,6 @@ RUN addgroup -g 1000 lemmy
 RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
 
 # Copy resources
-COPY --chown=lemmy:lemmy config/defaults.hjson /config/defaults.hjson
 COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy
 
 RUN chown lemmy:lemmy /app/lemmy
index b2b5ef7ea0f4c3909e626e13ee3ad5ee35e09991..c40de902272353b08107c6312caa25d238e2fd68 100644 (file)
@@ -38,20 +38,9 @@ services:
       - lemmy-alpha
   lemmy-alpha:
     image: lemmy-federation:latest
+    volumes:
+      - ./lemmy_alpha.hjson:/config/config.hjson
     environment:
-      - LEMMY_HOSTNAME=lemmy-alpha:8541
-      - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_alpha:5432/lemmy
-      - LEMMY_JWT_SECRET=changeme
-      - LEMMY_FEDERATION__ENABLED=true
-      - LEMMY_TLS_ENABLED=false
-      - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon
-      - LEMMY_PORT=8541
-      - LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
-      - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
-      - LEMMY_SETUP__SITE_NAME=lemmy-alpha
-      - LEMMY_RATE_LIMIT__POST=99999
-      - LEMMY_RATE_LIMIT__REGISTER=99999
-      - LEMMY_CAPTCHA__ENABLED=false
       - LEMMY_TEST_SEND_SYNC=1
       - RUST_BACKTRACE=1
       - RUST_LOG=debug
@@ -78,20 +67,9 @@ services:
       - lemmy-beta
   lemmy-beta:
     image: lemmy-federation:latest
+    volumes:
+      - ./lemmy_beta.hjson:/config/config.hjson
     environment:
-      - LEMMY_HOSTNAME=lemmy-beta:8551
-      - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_beta:5432/lemmy
-      - LEMMY_JWT_SECRET=changeme
-      - LEMMY_FEDERATION__ENABLED=true
-      - LEMMY_TLS_ENABLED=false
-      - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon
-      - LEMMY_PORT=8551
-      - LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
-      - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
-      - LEMMY_SETUP__SITE_NAME=lemmy-beta
-      - LEMMY_RATE_LIMIT__POST=99999
-      - LEMMY_RATE_LIMIT__REGISTER=99999
-      - LEMMY_CAPTCHA__ENABLED=false
       - LEMMY_TEST_SEND_SYNC=1
       - RUST_BACKTRACE=1
       - RUST_LOG=debug
@@ -118,20 +96,9 @@ services:
       - lemmy-gamma
   lemmy-gamma:
     image: lemmy-federation:latest
+    volumes:
+      - ./lemmy_gamma.hjson:/config/config.hjson
     environment:
-      - LEMMY_HOSTNAME=lemmy-gamma:8561
-      - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_gamma:5432/lemmy
-      - LEMMY_JWT_SECRET=changeme
-      - LEMMY_FEDERATION__ENABLED=true
-      - LEMMY_TLS_ENABLED=false
-      - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon
-      - LEMMY_PORT=8561
-      - LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
-      - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
-      - LEMMY_SETUP__SITE_NAME=lemmy-gamma
-      - LEMMY_RATE_LIMIT__POST=99999
-      - LEMMY_RATE_LIMIT__REGISTER=99999
-      - LEMMY_CAPTCHA__ENABLED=false
       - LEMMY_TEST_SEND_SYNC=1
       - RUST_BACKTRACE=1
       - RUST_LOG=debug
@@ -159,20 +126,9 @@ services:
       - lemmy-delta
   lemmy-delta:
     image: lemmy-federation:latest
+    volumes:
+      - ./lemmy_delta.hjson:/config/config.hjson
     environment:
-      - LEMMY_HOSTNAME=lemmy-delta:8571
-      - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_delta:5432/lemmy
-      - LEMMY_JWT_SECRET=changeme
-      - LEMMY_FEDERATION__ENABLED=true
-      - LEMMY_TLS_ENABLED=false
-      - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta
-      - LEMMY_PORT=8571
-      - LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta
-      - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
-      - LEMMY_SETUP__SITE_NAME=lemmy-delta
-      - LEMMY_RATE_LIMIT__POST=99999
-      - LEMMY_RATE_LIMIT__REGISTER=99999
-      - LEMMY_CAPTCHA__ENABLED=false
       - LEMMY_TEST_SEND_SYNC=1
       - RUST_BACKTRACE=1
       - RUST_LOG=debug
@@ -200,20 +156,9 @@ services:
       - lemmy-epsilon
   lemmy-epsilon:
     image: lemmy-federation:latest
+    volumes:
+      - ./lemmy_epsilon.hjson:/config/config.hjson
     environment:
-      - LEMMY_HOSTNAME=lemmy-epsilon:8581
-      - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_epsilon:5432/lemmy
-      - LEMMY_JWT_SECRET=changeme
-      - LEMMY_FEDERATION__ENABLED=true
-      - LEMMY_TLS_ENABLED=false
-      - LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha
-      - LEMMY_PORT=8581
-      - LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon
-      - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
-      - LEMMY_SETUP__SITE_NAME=lemmy-epsilon
-      - LEMMY_RATE_LIMIT__POST=99999
-      - LEMMY_RATE_LIMIT__REGISTER=99999
-      - LEMMY_CAPTCHA__ENABLED=false
       - LEMMY_TEST_SEND_SYNC=1
       - RUST_BACKTRACE=1
       - RUST_LOG=debug
diff --git a/docker/federation/lemmy_alpha.hjson b/docker/federation/lemmy_alpha.hjson
new file mode 100644 (file)
index 0000000..e806397
--- /dev/null
@@ -0,0 +1,36 @@
+{
+  port: 8541
+  tls_enabled: false
+  jwt_secret: changeme
+  setup: {
+    admin_username: lemmy_alpha
+    admin_password: lemmy
+    site_name: lemmy-alpha
+  }
+  database: {
+    database: lemmy
+    user: lemmy
+    password: password
+    host: postgres_alpha
+    port: 5432
+    pool_size: 5
+  }
+  federation: {
+    enabled: true
+    allowed_instances: ["lemmy-beta","lemmy-gamma","lemmy-delta","lemmy-epsilon"]
+  }
+  captcha: {
+    enabled: false
+    difficulty: medium
+  }
+  rate_limit: {
+    message: 180
+    message_per_second: 60
+    post: 99999
+    post_per_second: 600
+    register: 99999
+    register_per_second: 3600
+    image: 6
+    image_per_second: 3600
+  }
+}
diff --git a/docker/federation/lemmy_beta.hjson b/docker/federation/lemmy_beta.hjson
new file mode 100644 (file)
index 0000000..e16ecd5
--- /dev/null
@@ -0,0 +1,37 @@
+{
+  hostname: lemmy-beta:8551
+  port: 8551
+  tls_enabled: false
+  jwt_secret: changeme
+  setup: {
+    admin_username: lemmy_beta
+    admin_password: lemmy
+    site_name: lemmy-beta
+  }
+  database: {
+    database: lemmy
+    user: lemmy
+    password: password
+    host: postgres_beta
+    port: 5432
+    pool_size: 5
+  }
+  federation: {
+    enabled: true
+    allowed_instances: ["lemmy-alpha","lemmy-gamma","lemmy-delta","lemmy-epsilon"]
+  }
+  captcha: {
+    enabled: false
+    difficulty: medium
+  }
+  rate_limit: {
+    message: 180
+    message_per_second: 60
+    post: 99999
+    post_per_second: 600
+    register: 99999
+    register_per_second: 3600
+    image: 6
+    image_per_second: 3600
+  }
+}
diff --git a/docker/federation/lemmy_delta.hjson b/docker/federation/lemmy_delta.hjson
new file mode 100644 (file)
index 0000000..321775f
--- /dev/null
@@ -0,0 +1,37 @@
+{
+  hostname: lemmy-delta:8571
+  port: 8571
+  tls_enabled: false
+  jwt_secret: changeme
+  setup: {
+    admin_username: lemmy_delta
+    admin_password: lemmy
+    site_name: lemmy-delta
+  }
+  database: {
+    database: lemmy
+    user: lemmy
+    password: password
+    host: postgres_delta
+    port: 5432
+    pool_size: 5
+  }
+  federation: {
+    enabled: true
+    allowed_instances: ["lemmy-beta"]
+  }
+  captcha: {
+    enabled: false
+    difficulty: medium
+  }
+  rate_limit: {
+    message: 180
+    message_per_second: 60
+    post: 99999
+    post_per_second: 600
+    register: 99999
+    register_per_second: 3600
+    image: 6
+    image_per_second: 3600
+  }
+}
diff --git a/docker/federation/lemmy_epsilon.hjson b/docker/federation/lemmy_epsilon.hjson
new file mode 100644 (file)
index 0000000..20fb2c3
--- /dev/null
@@ -0,0 +1,37 @@
+{
+  hostname: lemmy-epsilon:8581
+  port: 8581
+  tls_enabled: false
+  jwt_secret: changeme
+  setup: {
+    admin_username: lemmy_epsilon
+    admin_password: lemmy
+    site_name: lemmy-epsilon
+  }
+  database: {
+    database: lemmy
+    user: lemmy
+    password: password
+    host: postgres_epsilon
+    port: 5432
+    pool_size: 5
+  }
+  federation: {
+    enabled: true
+    blocked_instances: ["lemmy-alpha"]
+  }
+  captcha: {
+    enabled: false
+    difficulty: medium
+  }
+  rate_limit: {
+    message: 180
+    message_per_second: 60
+    post: 99999
+    post_per_second: 600
+    register: 99999
+    register_per_second: 3600
+    image: 6
+    image_per_second: 3600
+  }
+}
diff --git a/docker/federation/lemmy_gamma.hjson b/docker/federation/lemmy_gamma.hjson
new file mode 100644 (file)
index 0000000..784f98e
--- /dev/null
@@ -0,0 +1,37 @@
+{
+  hostname: lemmy-gamma:8561
+  port: 8561
+  tls_enabled: false
+  jwt_secret: changeme
+  setup: {
+    admin_username: lemmy_gamma
+    admin_password: lemmy
+    site_name: lemmy-gamma
+  }
+  database: {
+    database: lemmy
+    user: lemmy
+    password: password
+    host: postgres_gamma
+    port: 5432
+    pool_size: 5
+  }
+  federation: {
+    enabled: true
+    allowed_instances: ["lemmy-alpha","lemmy-beta","lemmy-delta","lemmy-epsilon"]
+  }
+  captcha: {
+    enabled: false
+    difficulty: medium
+  }
+  rate_limit: {
+    message: 180
+    message_per_second: 60
+    post: 99999
+    post_per_second: 600
+    register: 99999
+    register_per_second: 3600
+    image: 6
+    image_per_second: 3600
+  }
+}
index bea65d8f9d9d9d1af39e3addded0a74cb03b2702..bceb5f6cd46265e90c3ca8ae8d86bd61222ecdfa 100644 (file)
     password: "password"
     # host where postgres is running
     host: "postgres"
+    # port where postgres can be accessed
+    port: 5432
+    # maximum number of active sql connections
+    pool_size: 5
   }
 #  # optional: email sending configuration
 #  email: {
index 66e8217fe6294a1c8e17574d3cc1699f6312a78d..2f2418e49ac8ac89e199a18ef76090bb7eef3251 100644 (file)
@@ -56,7 +56,6 @@ RUN addgroup -g 1000 lemmy
 RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy
 
 # Copy resources
-COPY --chown=lemmy:lemmy config/defaults.hjson /config/defaults.hjson
 COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy
 
 RUN chown lemmy:lemmy /app/lemmy
index bcf590034ba422120c648f69f4a3b015d6373ef5..a6e698f0d7d148330b2dd852767bdcc40675204d 100644 (file)
@@ -31,7 +31,6 @@ RUN addgroup --gid 1000 lemmy
 RUN adduser --no-create-home --shell /bin/sh --uid 1000 --gid 1000 lemmy
 
 # Copy resources
-COPY --chown=lemmy:lemmy config/defaults.hjson /config/defaults.hjson
 COPY --chown=lemmy:lemmy --from=builder /app/lemmy_server /app/lemmy
 
 RUN chown lemmy:lemmy /app/lemmy
index ea11e32d3be60b9c4f3a8fed2e64555f04b6aad4..f3bc3df53f193149c33d41d440b9ceb59a0eafe4 100644 (file)
@@ -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> {
index a18201c73f43307134f6df16336238a4f879fe8e..fa110b51e17ce1fb1957ba27bbe8974061058a51 100644 (file)
@@ -15,7 +15,7 @@ use lemmy_routes::{feeds, images, nodeinfo, webfinger};
 use lemmy_server::{code_migrations::run_advanced_migrations, scheduled_tasks};
 use lemmy_utils::{
   rate_limit::{rate_limiter::RateLimiter, RateLimit},
-  settings::Settings,
+  settings::structs::Settings,
   LemmyError,
 };
 use lemmy_websocket::{chat_server::ChatServer, LemmyContext};
@@ -37,7 +37,7 @@ async fn main() -> Result<(), LemmyError> {
   };
   let manager = ConnectionManager::<PgConnection>::new(&db_url);
   let pool = Pool::builder()
-    .max_size(settings.database.pool_size)
+    .max_size(settings.database().pool_size)
     .build(manager)
     .unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
 
@@ -61,7 +61,8 @@ async fn main() -> Result<(), LemmyError> {
 
   println!(
     "Starting http server at {}:{}",
-    settings.bind, settings.port
+    settings.bind(),
+    settings.port()
   );
 
   let activity_queue = create_activity_queue();
@@ -94,7 +95,7 @@ async fn main() -> Result<(), LemmyError> {
       .configure(nodeinfo::config)
       .configure(webfinger::config)
   })
-  .bind((settings.bind, settings.port))?
+  .bind((settings.bind(), settings.port()))?
   .run()
   .await?;