Merge remote-tracking branch 'origin/main' into 1462-jwt-revocation-on-pwd-change
* origin/main: revert Compose file version from 3.3 to 2.2 Adding more mem limits bump memory limit of iframely Remove extra category_id s . Fixes #1429 Fixing wrong user_ and community icon and banner urls. Remove category from activitypub context Adding a password length check to other API actions. (#1474) Update test script Use URL type in most outstanding struct fields (#1468) Forbid usage of unwrap Upgrade Rust version Rewrite settings implementation. Fixes #1270 (#1433) Rename `lemmy_structs` to `lemmy_api_structs` # Conflicts: # crates/db_schema/src/source/user.rs
This commit is contained in:
commit
7b0a09e84e
122 changed files with 1212 additions and 925 deletions
13
.drone.yml
13
.drone.yml
|
@ -9,7 +9,7 @@ platform:
|
|||
steps:
|
||||
|
||||
- name: chown repo
|
||||
image: ekidd/rust-musl-builder:1.47.0
|
||||
image: ekidd/rust-musl-builder:1.50.0
|
||||
user: root
|
||||
commands:
|
||||
- chown 1000:1000 . -R
|
||||
|
@ -20,12 +20,13 @@ steps:
|
|||
- /root/.cargo/bin/cargo fmt -- --check
|
||||
|
||||
- name: cargo clippy
|
||||
image: ekidd/rust-musl-builder:1.47.0
|
||||
image: ekidd/rust-musl-builder:1.50.0
|
||||
commands:
|
||||
- cargo clippy --workspace --tests --all-targets --all-features -- -D warnings -D deprecated -D clippy::perf -D clippy::complexity -D clippy::dbg_macro
|
||||
- cargo clippy --workspace -- -D clippy::unwrap_used
|
||||
|
||||
- name: cargo test
|
||||
image: ekidd/rust-musl-builder:1.47.0
|
||||
image: ekidd/rust-musl-builder:1.50.0
|
||||
environment:
|
||||
LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
|
||||
RUST_BACKTRACE: 1
|
||||
|
@ -35,7 +36,7 @@ steps:
|
|||
- cargo test --workspace --no-fail-fast
|
||||
|
||||
- name: cargo build
|
||||
image: ekidd/rust-musl-builder:1.47.0
|
||||
image: ekidd/rust-musl-builder:1.50.0
|
||||
commands:
|
||||
- cargo build
|
||||
- mv target/x86_64-unknown-linux-musl/debug/lemmy_server target/lemmy_server
|
||||
|
@ -102,7 +103,7 @@ platform:
|
|||
steps:
|
||||
|
||||
- name: cargo test
|
||||
image: rust:1.47-slim-buster
|
||||
image: rust:1.50-slim-buster
|
||||
environment:
|
||||
LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
|
||||
RUST_BACKTRACE: 1
|
||||
|
@ -114,7 +115,7 @@ steps:
|
|||
|
||||
# Using Debian here because there seems to be no official Alpine-based Rust docker image for ARM.
|
||||
- name: cargo build
|
||||
image: rust:1.47-slim-buster
|
||||
image: rust:1.50-slim-buster
|
||||
commands:
|
||||
- apt-get update
|
||||
- apt-get -y install --no-install-recommends libssl-dev pkg-config libpq-dev
|
||||
|
|
293
Cargo.lock
generated
293
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
@ -1734,20 +1734,20 @@ dependencies = [
|
|||
"http-signature-normalization-actix",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"lemmy_api_structs",
|
||||
"lemmy_apub",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"lemmy_db_views",
|
||||
"lemmy_db_views_actor",
|
||||
"lemmy_db_views_moderator",
|
||||
"lemmy_structs",
|
||||
"lemmy_utils",
|
||||
"lemmy_websocket",
|
||||
"log",
|
||||
"openssl",
|
||||
"rand 0.8.3",
|
||||
"reqwest",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"strum",
|
||||
|
@ -1758,6 +1758,25 @@ dependencies = [
|
|||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lemmy_api_structs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"chrono",
|
||||
"diesel",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"lemmy_db_views",
|
||||
"lemmy_db_views_actor",
|
||||
"lemmy_db_views_moderator",
|
||||
"lemmy_utils",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lemmy_apub"
|
||||
version = "0.1.0"
|
||||
|
@ -1782,11 +1801,11 @@ dependencies = [
|
|||
"http-signature-normalization-reqwest",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"lemmy_api_structs",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"lemmy_db_views",
|
||||
"lemmy_db_views_actor",
|
||||
"lemmy_structs",
|
||||
"lemmy_utils",
|
||||
"lemmy_websocket",
|
||||
"log",
|
||||
|
@ -1794,7 +1813,7 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"rand 0.8.3",
|
||||
"reqwest",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"strum",
|
||||
|
@ -1818,7 +1837,7 @@ dependencies = [
|
|||
"lemmy_utils",
|
||||
"log",
|
||||
"regex",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serial_test",
|
||||
"sha2",
|
||||
|
@ -1834,7 +1853,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"diesel",
|
||||
"log",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
@ -1847,7 +1866,7 @@ dependencies = [
|
|||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"log",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
"serial_test",
|
||||
"url",
|
||||
]
|
||||
|
@ -1859,7 +1878,7 @@ dependencies = [
|
|||
"diesel",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1869,7 +1888,7 @@ dependencies = [
|
|||
"diesel",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1884,16 +1903,16 @@ dependencies = [
|
|||
"chrono",
|
||||
"diesel",
|
||||
"lazy_static",
|
||||
"lemmy_api_structs",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"lemmy_db_views",
|
||||
"lemmy_db_views_actor",
|
||||
"lemmy_structs",
|
||||
"lemmy_utils",
|
||||
"lemmy_websocket",
|
||||
"log",
|
||||
"rss",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
"sha2",
|
||||
"strum",
|
||||
"url",
|
||||
|
@ -1916,6 +1935,7 @@ dependencies = [
|
|||
"env_logger",
|
||||
"http-signature-normalization-actix",
|
||||
"lemmy_api",
|
||||
"lemmy_api_structs",
|
||||
"lemmy_apub",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
|
@ -1923,38 +1943,18 @@ dependencies = [
|
|||
"lemmy_db_views_actor",
|
||||
"lemmy_db_views_moderator",
|
||||
"lemmy_routes",
|
||||
"lemmy_structs",
|
||||
"lemmy_utils",
|
||||
"lemmy_websocket",
|
||||
"log",
|
||||
"openssl",
|
||||
"reqwest",
|
||||
"serde 1.0.123",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
"tokio 0.3.7",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lemmy_structs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"chrono",
|
||||
"diesel",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"lemmy_db_views",
|
||||
"lemmy_db_views_actor",
|
||||
"lemmy_db_views_moderator",
|
||||
"lemmy_utils",
|
||||
"log",
|
||||
"serde 1.0.123",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lemmy_utils"
|
||||
version = "0.1.0"
|
||||
|
@ -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",
|
||||
|
@ -1998,14 +2000,14 @@ dependencies = [
|
|||
"background-jobs",
|
||||
"chrono",
|
||||
"diesel",
|
||||
"lemmy_api_structs",
|
||||
"lemmy_db_queries",
|
||||
"lemmy_db_schema",
|
||||
"lemmy_structs",
|
||||
"lemmy_utils",
|
||||
"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",
|
||||
|
@ -3684,15 +3655,15 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
|||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.0"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
|
||||
checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"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",
|
||||
]
|
||||
|
|
|
@ -19,7 +19,7 @@ members = [
|
|||
"crates/db_views",
|
||||
"crates/db_views_actor",
|
||||
"crates/db_views_actor",
|
||||
"crates/structs",
|
||||
"crates/api_structs",
|
||||
"crates/websocket",
|
||||
"crates/routes"
|
||||
]
|
||||
|
@ -33,7 +33,7 @@ lemmy_db_queries = { path = "./crates/db_queries" }
|
|||
lemmy_db_views = { path = "./crates/db_views" }
|
||||
lemmy_db_views_moderator = { path = "./crates/db_views_moderator" }
|
||||
lemmy_db_views_actor = { path = "./crates/db_views_actor" }
|
||||
lemmy_structs = { path = "./crates/structs" }
|
||||
lemmy_api_structs = { path = "crates/api_structs" }
|
||||
lemmy_websocket = { path = "./crates/websocket" }
|
||||
lemmy_routes = { path = "./crates/routes" }
|
||||
diesel = "1.4.5"
|
||||
|
@ -45,7 +45,7 @@ actix-web = { version = "3.3.2", default-features = false, features = ["rustls"]
|
|||
log = "0.4.14"
|
||||
env_logger = "0.8.2"
|
||||
strum = "0.20.0"
|
||||
url = { version = "2.2.0", features = ["serde"] }
|
||||
url = { version = "2.2.1", features = ["serde"] }
|
||||
openssl = "0.10.32"
|
||||
http-signature-normalization-actix = { version = "0.4.1", default-features = false, features = ["sha-2"] }
|
||||
tokio = "0.3.6"
|
||||
|
|
|
@ -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: []
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: '3.3'
|
||||
version: '2.2'
|
||||
|
||||
services:
|
||||
lemmy:
|
||||
|
@ -53,6 +53,7 @@ services:
|
|||
volumes:
|
||||
- ./iframely.config.local.js:/iframely/config.local.js:ro
|
||||
restart: always
|
||||
mem_limit: 200m
|
||||
|
||||
postfix:
|
||||
image: mwader/postfix-relay
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -4,7 +4,7 @@ set -e
|
|||
export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432
|
||||
|
||||
pushd ..
|
||||
cargo +1.47.0 build
|
||||
cargo build
|
||||
rm target/lemmy_server || true
|
||||
cp target/debug/lemmy_server target/lemmy_server
|
||||
./api_tests/prepare-drone-federation-test.sh
|
||||
|
|
|
@ -66,9 +66,10 @@
|
|||
# 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
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
[package]
|
||||
name = "lemmy_api"
|
||||
version = "0.1.0"
|
||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
|
@ -17,7 +16,7 @@ lemmy_db_schema = { path = "../db_schema" }
|
|||
lemmy_db_views = { path = "../db_views" }
|
||||
lemmy_db_views_moderator = { path = "../db_views_moderator" }
|
||||
lemmy_db_views_actor = { path = "../db_views_actor" }
|
||||
lemmy_structs = { path = "../structs" }
|
||||
lemmy_api_structs = { path = "../api_structs" }
|
||||
lemmy_websocket = { path = "../websocket" }
|
||||
diesel = "1.4.5"
|
||||
bcrypt = "0.9.0"
|
||||
|
@ -33,7 +32,7 @@ rand = "0.8.3"
|
|||
strum = "0.20.0"
|
||||
strum_macros = "0.20.1"
|
||||
lazy_static = "1.4.0"
|
||||
url = { version = "2.2.0", features = ["serde"] }
|
||||
url = { version = "2.2.1", features = ["serde"] }
|
||||
openssl = "0.10.32"
|
||||
http = "0.2.3"
|
||||
http-signature-normalization-actix = { version = "0.4.1", default-features = false, features = ["sha-2"] }
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
|||
Perform,
|
||||
};
|
||||
use actix_web::web::Data;
|
||||
use lemmy_api_structs::{blocking, comment::*, send_local_notifs};
|
||||
use lemmy_apub::{generate_apub_endpoint, ApubLikeableType, ApubObjectType, EndpointType};
|
||||
use lemmy_db_queries::{
|
||||
source::comment::Comment_,
|
||||
|
@ -24,7 +25,6 @@ use lemmy_db_views::{
|
|||
comment_report_view::{CommentReportQueryBuilder, CommentReportView},
|
||||
comment_view::{CommentQueryBuilder, CommentView},
|
||||
};
|
||||
use lemmy_structs::{blocking, comment::*, send_local_notifs};
|
||||
use lemmy_utils::{
|
||||
utils::{remove_slurs, scrape_text_for_mentions},
|
||||
ApiError,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::{
|
||||
check_community_ban,
|
||||
check_optional_url,
|
||||
get_user_from_jwt,
|
||||
get_user_from_jwt_opt,
|
||||
is_admin,
|
||||
|
@ -9,6 +8,7 @@ use crate::{
|
|||
};
|
||||
use actix_web::web::Data;
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::{blocking, community::*};
|
||||
use lemmy_apub::{
|
||||
generate_apub_endpoint,
|
||||
generate_followers_url,
|
||||
|
@ -18,7 +18,7 @@ use lemmy_apub::{
|
|||
EndpointType,
|
||||
};
|
||||
use lemmy_db_queries::{
|
||||
diesel_option_overwrite,
|
||||
diesel_option_overwrite_to_url,
|
||||
source::{
|
||||
comment::Comment_,
|
||||
community::{CommunityModerator_, Community_},
|
||||
|
@ -43,7 +43,6 @@ use lemmy_db_views_actor::{
|
|||
community_view::{CommunityQueryBuilder, CommunityView},
|
||||
user_view::UserViewSafe,
|
||||
};
|
||||
use lemmy_structs::{blocking, community::*};
|
||||
use lemmy_utils::{
|
||||
apub::generate_actor_keypair,
|
||||
location_info,
|
||||
|
@ -155,11 +154,8 @@ impl Perform for CreateCommunity {
|
|||
}
|
||||
|
||||
// Check to make sure the icon and banners are urls
|
||||
let icon = diesel_option_overwrite(&data.icon);
|
||||
let banner = diesel_option_overwrite(&data.banner);
|
||||
|
||||
check_optional_url(&icon)?;
|
||||
check_optional_url(&banner)?;
|
||||
let icon = diesel_option_overwrite_to_url(&data.icon)?;
|
||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||
|
||||
// When you create a community, make sure the user becomes a moderator and a follower
|
||||
let keypair = generate_actor_keypair()?;
|
||||
|
@ -260,11 +256,8 @@ impl Perform for EditCommunity {
|
|||
})
|
||||
.await??;
|
||||
|
||||
let icon = diesel_option_overwrite(&data.icon);
|
||||
let banner = diesel_option_overwrite(&data.banner);
|
||||
|
||||
check_optional_url(&icon)?;
|
||||
check_optional_url(&banner)?;
|
||||
let icon = diesel_option_overwrite_to_url(&data.icon)?;
|
||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||
|
||||
let community_form = CommunityForm {
|
||||
name: read_community.name,
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
use actix_web::{web, web::Data};
|
||||
use lemmy_api_structs::{
|
||||
blocking,
|
||||
comment::*,
|
||||
community::*,
|
||||
post::*,
|
||||
site::*,
|
||||
user::*,
|
||||
websocket::*,
|
||||
};
|
||||
use lemmy_db_queries::{
|
||||
source::{
|
||||
community::{CommunityModerator_, Community_},
|
||||
|
@ -18,8 +27,13 @@ use lemmy_db_views_actor::{
|
|||
community_user_ban_view::CommunityUserBanView,
|
||||
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::{env, process::Command};
|
||||
|
@ -182,19 +196,10 @@ pub(crate) async fn collect_moderated_communities(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn check_optional_url(item: &Option<Option<String>>) -> Result<(), LemmyError> {
|
||||
if let Some(Some(item)) = &item {
|
||||
if Url::parse(item).is_err() {
|
||||
return Err(ApiError::err("invalid_url").into());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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)
|
||||
})
|
||||
|
@ -208,8 +213,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();
|
||||
|
@ -469,6 +479,15 @@ pub(crate) fn espeak_wav_base64(text: &str) -> Result<String, LemmyError> {
|
|||
Ok(base64)
|
||||
}
|
||||
|
||||
/// Checks the password length
|
||||
pub(crate) fn password_length_check(pass: &str) -> Result<(), LemmyError> {
|
||||
if pass.len() > 60 {
|
||||
Err(ApiError::err("invalid_password").into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{captcha_espeak_wav_base64, get_user_from_jwt};
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{
|
||||
check_community_ban,
|
||||
check_downvotes_enabled,
|
||||
check_optional_url,
|
||||
collect_moderated_communities,
|
||||
get_user_from_jwt,
|
||||
get_user_from_jwt_opt,
|
||||
|
@ -9,6 +8,7 @@ use crate::{
|
|||
Perform,
|
||||
};
|
||||
use actix_web::web::Data;
|
||||
use lemmy_api_structs::{blocking, post::*};
|
||||
use lemmy_apub::{generate_apub_endpoint, ApubLikeableType, ApubObjectType, EndpointType};
|
||||
use lemmy_db_queries::{
|
||||
source::post::Post_,
|
||||
|
@ -36,7 +36,6 @@ use lemmy_db_views_actor::{
|
|||
community_moderator_view::CommunityModeratorView,
|
||||
community_view::CommunityView,
|
||||
};
|
||||
use lemmy_structs::{blocking, post::*};
|
||||
use lemmy_utils::{
|
||||
request::fetch_iframely_and_pictrs_data,
|
||||
utils::{check_slurs, check_slurs_opt, is_valid_post_title},
|
||||
|
@ -72,15 +71,14 @@ impl Perform for CreatePost {
|
|||
|
||||
check_community_ban(user.id, data.community_id, context.pool()).await?;
|
||||
|
||||
check_optional_url(&Some(data.url.to_owned()))?;
|
||||
|
||||
// Fetch Iframely and pictrs cached image
|
||||
let data_url = data.url.as_ref();
|
||||
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
||||
fetch_iframely_and_pictrs_data(context.client(), data.url.to_owned()).await;
|
||||
fetch_iframely_and_pictrs_data(context.client(), data_url).await;
|
||||
|
||||
let post_form = PostForm {
|
||||
name: data.name.trim().to_owned(),
|
||||
url: data.url.to_owned(),
|
||||
url: data_url.map(|u| u.to_owned().into()),
|
||||
body: data.body.to_owned(),
|
||||
community_id: data.community_id,
|
||||
creator_id: user.id,
|
||||
|
@ -93,7 +91,7 @@ impl Perform for CreatePost {
|
|||
embed_title: iframely_title,
|
||||
embed_description: iframely_description,
|
||||
embed_html: iframely_html,
|
||||
thumbnail_url: pictrs_thumbnail,
|
||||
thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
|
||||
ap_id: None,
|
||||
local: true,
|
||||
published: None,
|
||||
|
@ -385,12 +383,13 @@ impl Perform for EditPost {
|
|||
}
|
||||
|
||||
// Fetch Iframely and Pictrs cached image
|
||||
let data_url = data.url.as_ref();
|
||||
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
||||
fetch_iframely_and_pictrs_data(context.client(), data.url.to_owned()).await;
|
||||
fetch_iframely_and_pictrs_data(context.client(), data_url).await;
|
||||
|
||||
let post_form = PostForm {
|
||||
name: data.name.trim().to_owned(),
|
||||
url: data.url.to_owned(),
|
||||
url: data_url.map(|u| u.to_owned().into()),
|
||||
body: data.body.to_owned(),
|
||||
nsfw: data.nsfw,
|
||||
creator_id: orig_post.creator_id.to_owned(),
|
||||
|
@ -403,7 +402,7 @@ impl Perform for EditPost {
|
|||
embed_title: iframely_title,
|
||||
embed_description: iframely_description,
|
||||
embed_html: iframely_html,
|
||||
thumbnail_url: pictrs_thumbnail,
|
||||
thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
|
||||
ap_id: Some(orig_post.ap_id),
|
||||
local: orig_post.local,
|
||||
published: None,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::Perform;
|
||||
use actix_web::{error::ErrorBadRequest, *};
|
||||
use lemmy_structs::{comment::*, community::*, post::*, site::*, user::*, websocket::*};
|
||||
use lemmy_api_structs::{comment::*, community::*, post::*, site::*, user::*, websocket::*};
|
||||
use lemmy_utils::rate_limit::RateLimit;
|
||||
use lemmy_websocket::{routes::chat_route, LemmyContext};
|
||||
use serde::Deserialize;
|
||||
|
|
|
@ -9,8 +9,15 @@ use crate::{
|
|||
};
|
||||
use actix_web::web::Data;
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::{blocking, site::*, user::Register};
|
||||
use lemmy_apub::fetcher::search::search_by_apub_id;
|
||||
use lemmy_db_queries::{diesel_option_overwrite, source::site::Site_, Crud, SearchType, SortType};
|
||||
use lemmy_db_queries::{
|
||||
diesel_option_overwrite_to_url,
|
||||
source::site::Site_,
|
||||
Crud,
|
||||
SearchType,
|
||||
SortType,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
naive_now,
|
||||
source::{
|
||||
|
@ -38,10 +45,9 @@ use lemmy_db_views_moderator::{
|
|||
mod_remove_post_view::ModRemovePostView,
|
||||
mod_sticky_post_view::ModStickyPostView,
|
||||
};
|
||||
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,
|
||||
|
@ -157,8 +163,8 @@ impl Perform for CreateSite {
|
|||
let site_form = SiteForm {
|
||||
name: data.name.to_owned(),
|
||||
description: data.description.to_owned(),
|
||||
icon: Some(data.icon.to_owned()),
|
||||
banner: Some(data.banner.to_owned()),
|
||||
icon: Some(data.icon.to_owned().map(|url| url.into())),
|
||||
banner: Some(data.banner.to_owned().map(|url| url.into())),
|
||||
creator_id: user.id,
|
||||
enable_downvotes: data.enable_downvotes,
|
||||
open_registration: data.open_registration,
|
||||
|
@ -196,8 +202,8 @@ impl Perform for EditSite {
|
|||
|
||||
let found_site = blocking(context.pool(), move |conn| Site::read_simple(conn)).await??;
|
||||
|
||||
let icon = diesel_option_overwrite(&data.icon);
|
||||
let banner = diesel_option_overwrite(&data.banner);
|
||||
let icon = diesel_option_overwrite_to_url(&data.icon)?;
|
||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||
|
||||
let site_form = SiteForm {
|
||||
name: data.name.to_owned(),
|
||||
|
@ -245,7 +251,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(),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::{
|
||||
captcha_espeak_wav_base64,
|
||||
check_optional_url,
|
||||
collect_moderated_communities,
|
||||
get_user_from_jwt,
|
||||
get_user_from_jwt_opt,
|
||||
is_admin,
|
||||
password_length_check,
|
||||
Perform,
|
||||
};
|
||||
use actix_web::web::Data;
|
||||
|
@ -12,6 +12,7 @@ use anyhow::Context;
|
|||
use bcrypt::verify;
|
||||
use captcha::{gen, Difficulty};
|
||||
use chrono::Duration;
|
||||
use lemmy_api_structs::{blocking, send_email_to_user, user::*};
|
||||
use lemmy_apub::{
|
||||
generate_apub_endpoint,
|
||||
generate_followers_url,
|
||||
|
@ -22,6 +23,7 @@ use lemmy_apub::{
|
|||
};
|
||||
use lemmy_db_queries::{
|
||||
diesel_option_overwrite,
|
||||
diesel_option_overwrite_to_url,
|
||||
source::{
|
||||
comment::Comment_,
|
||||
community::Community_,
|
||||
|
@ -65,13 +67,12 @@ use lemmy_db_views_actor::{
|
|||
user_mention_view::{UserMentionQueryBuilder, UserMentionView},
|
||||
user_view::UserViewSafe,
|
||||
};
|
||||
use lemmy_structs::{blocking, send_email_to_user, user::*};
|
||||
use lemmy_utils::{
|
||||
apub::generate_actor_keypair,
|
||||
claims::Claims,
|
||||
email::send_email,
|
||||
location_info,
|
||||
settings::Settings,
|
||||
settings::structs::Settings,
|
||||
utils::{
|
||||
check_slurs,
|
||||
generate_random_string,
|
||||
|
@ -121,7 +122,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())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -144,10 +145,7 @@ impl Perform for Register {
|
|||
}
|
||||
}
|
||||
|
||||
// Password length check
|
||||
if data.password.len() > 60 {
|
||||
return Err(ApiError::err("invalid_password").into());
|
||||
}
|
||||
password_length_check(&data.password)?;
|
||||
|
||||
// Make sure passwords match
|
||||
if data.password != data.password_verify {
|
||||
|
@ -161,7 +159,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 +300,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 +314,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 });
|
||||
|
@ -366,17 +364,13 @@ impl Perform for SaveUserSettings {
|
|||
let data: &SaveUserSettings = &self;
|
||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let avatar = diesel_option_overwrite(&data.avatar);
|
||||
let banner = diesel_option_overwrite(&data.banner);
|
||||
let avatar = diesel_option_overwrite_to_url(&data.avatar)?;
|
||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||
let email = diesel_option_overwrite(&data.email);
|
||||
let bio = diesel_option_overwrite(&data.bio);
|
||||
let preferred_username = diesel_option_overwrite(&data.preferred_username);
|
||||
let matrix_user_id = diesel_option_overwrite(&data.matrix_user_id);
|
||||
|
||||
// Check to make sure the avatar and banners are urls
|
||||
check_optional_url(&avatar)?;
|
||||
check_optional_url(&banner)?;
|
||||
|
||||
if let Some(Some(bio)) = &bio {
|
||||
if bio.chars().count() > 300 {
|
||||
return Err(ApiError::err("bio_length_overflow").into());
|
||||
|
@ -394,6 +388,8 @@ impl Perform for SaveUserSettings {
|
|||
Some(new_password) => {
|
||||
match &data.new_password_verify {
|
||||
Some(new_password_verify) => {
|
||||
password_length_check(&new_password)?;
|
||||
|
||||
// Make sure passwords match
|
||||
if new_password != new_password_verify {
|
||||
return Err(ApiError::err("passwords_dont_match").into());
|
||||
|
@ -475,7 +471,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())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -993,6 +989,8 @@ impl Perform for PasswordChange {
|
|||
})
|
||||
.await??;
|
||||
|
||||
password_length_check(&data.password)?;
|
||||
|
||||
// Make sure passwords match
|
||||
if data.password != data.password_verify {
|
||||
return Err(ApiError::err("passwords_dont_match").into());
|
||||
|
@ -1011,7 +1009,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())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{get_user_from_jwt, Perform};
|
||||
use actix_web::web::Data;
|
||||
use lemmy_structs::websocket::*;
|
||||
use lemmy_api_structs::websocket::*;
|
||||
use lemmy_utils::{ConnectionId, LemmyError};
|
||||
use lemmy_websocket::{
|
||||
messages::{JoinCommunityRoom, JoinModRoom, JoinPostRoom, JoinUserRoom},
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
[package]
|
||||
name = "lemmy_structs"
|
||||
name = "lemmy_api_structs"
|
||||
version = "0.1.0"
|
||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "lemmy_structs"
|
||||
name = "lemmy_api_structs"
|
||||
path = "src/lib.rs"
|
||||
doctest = false
|
||||
|
||||
|
@ -22,4 +21,4 @@ diesel = "1.4.5"
|
|||
actix-web = "3.3.2"
|
||||
chrono = { version = "0.4.19", features = ["serde"] }
|
||||
serde_json = { version = "1.0.61", features = ["preserve_order"] }
|
||||
url = "2.2.0"
|
||||
url = "2.2.1"
|
|
@ -27,7 +27,6 @@ pub struct CreateCommunity {
|
|||
pub description: Option<String>,
|
||||
pub icon: Option<String>,
|
||||
pub banner: Option<String>,
|
||||
pub category_id: i32,
|
||||
pub nsfw: bool,
|
||||
pub auth: String,
|
||||
}
|
||||
|
@ -88,7 +87,6 @@ pub struct EditCommunity {
|
|||
pub description: Option<String>,
|
||||
pub icon: Option<String>,
|
||||
pub banner: Option<String>,
|
||||
pub category_id: i32,
|
||||
pub nsfw: bool,
|
||||
pub auth: String,
|
||||
}
|
|
@ -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!(
|
|
@ -8,11 +8,12 @@ use lemmy_db_views_actor::{
|
|||
community_view::CommunityView,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct CreatePost {
|
||||
pub name: String,
|
||||
pub url: Option<String>,
|
||||
pub url: Option<Url>,
|
||||
pub body: Option<String>,
|
||||
pub nsfw: bool,
|
||||
pub community_id: i32,
|
||||
|
@ -66,7 +67,7 @@ pub struct CreatePostLike {
|
|||
pub struct EditPost {
|
||||
pub post_id: i32,
|
||||
pub name: String,
|
||||
pub url: Option<String>,
|
||||
pub url: Option<Url>,
|
||||
pub body: Option<String>,
|
||||
pub nsfw: bool,
|
||||
pub auth: String,
|
|
@ -13,6 +13,7 @@ use lemmy_db_views_moderator::{
|
|||
mod_sticky_post_view::ModStickyPostView,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Search {
|
||||
|
@ -60,8 +61,8 @@ pub struct GetModlogResponse {
|
|||
pub struct CreateSite {
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub icon: Option<String>,
|
||||
pub banner: Option<String>,
|
||||
pub icon: Option<Url>,
|
||||
pub banner: Option<Url>,
|
||||
pub enable_downvotes: bool,
|
||||
pub open_registration: bool,
|
||||
pub enable_nsfw: bool,
|
||||
|
@ -126,6 +127,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>>,
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
[package]
|
||||
name = "lemmy_apub"
|
||||
version = "0.1.0"
|
||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
|
@ -15,7 +14,7 @@ lemmy_db_queries = { path = "../db_queries" }
|
|||
lemmy_db_schema = { path = "../db_schema" }
|
||||
lemmy_db_views = { path = "../db_views" }
|
||||
lemmy_db_views_actor = { path = "../db_views_actor" }
|
||||
lemmy_structs = { path = "../structs" }
|
||||
lemmy_api_structs = { path = "../api_structs" }
|
||||
lemmy_websocket = { path = "../websocket" }
|
||||
diesel = "1.4.5"
|
||||
activitystreams = "0.7.0-alpha.10"
|
||||
|
@ -33,7 +32,7 @@ rand = "0.8.3"
|
|||
strum = "0.20.0"
|
||||
strum_macros = "0.20.1"
|
||||
lazy_static = "1.4.0"
|
||||
url = { version = "2.2.0", features = ["serde"] }
|
||||
url = { version = "2.2.1", features = ["serde"] }
|
||||
percent-encoding = "2.1.0"
|
||||
openssl = "0.10.32"
|
||||
http = "0.2.3"
|
||||
|
|
|
@ -4,13 +4,13 @@ use activitystreams::{
|
|||
base::ExtendsExt,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::{blocking, comment::CommentResponse, send_local_notifs};
|
||||
use lemmy_db_queries::{source::comment::Comment_, Crud, Likeable};
|
||||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentLike, CommentLikeForm},
|
||||
post::Post,
|
||||
};
|
||||
use lemmy_db_views::comment_view::CommentView;
|
||||
use lemmy_structs::{blocking, comment::CommentResponse, send_local_notifs};
|
||||
use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
|
||||
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::activities::receive::get_actor_as_user;
|
||||
use activitystreams::activity::{Dislike, Like};
|
||||
use lemmy_api_structs::{blocking, comment::CommentResponse};
|
||||
use lemmy_db_queries::{source::comment::Comment_, Likeable};
|
||||
use lemmy_db_schema::source::comment::{Comment, CommentLike};
|
||||
use lemmy_db_views::comment_view::CommentView;
|
||||
use lemmy_structs::{blocking, comment::CommentResponse};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ use activitystreams::{
|
|||
base::{AnyBase, ExtendsExt},
|
||||
};
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::{blocking, community::CommunityResponse};
|
||||
use lemmy_db_queries::{source::community::Community_, ApubObject};
|
||||
use lemmy_db_schema::source::community::Community;
|
||||
use lemmy_db_views_actor::community_view::CommunityView;
|
||||
use lemmy_structs::{blocking, community::CommunityResponse};
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
|
||||
use url::Url;
|
||||
|
|
|
@ -4,10 +4,10 @@ use activitystreams::{
|
|||
prelude::*,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::{blocking, post::PostResponse};
|
||||
use lemmy_db_queries::{source::post::Post_, Likeable};
|
||||
use lemmy_db_schema::source::post::{Post, PostLike, PostLikeForm};
|
||||
use lemmy_db_views::post_view::PostView;
|
||||
use lemmy_structs::{blocking, post::PostResponse};
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::activities::receive::get_actor_as_user;
|
||||
use activitystreams::activity::{Dislike, Like};
|
||||
use lemmy_api_structs::{blocking, post::PostResponse};
|
||||
use lemmy_db_queries::{source::post::Post_, Likeable};
|
||||
use lemmy_db_schema::source::post::{Post, PostLike};
|
||||
use lemmy_db_views::post_view::PostView;
|
||||
use lemmy_structs::{blocking, post::PostResponse};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ use activitystreams::{
|
|||
public,
|
||||
};
|
||||
use anyhow::{anyhow, Context};
|
||||
use lemmy_api_structs::{blocking, user::PrivateMessageResponse};
|
||||
use lemmy_db_queries::source::private_message::PrivateMessage_;
|
||||
use lemmy_db_schema::source::private_message::PrivateMessage;
|
||||
use lemmy_db_views::private_message_view::PrivateMessageView;
|
||||
use lemmy_structs::{blocking, user::PrivateMessageResponse};
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
|
||||
use url::Url;
|
||||
|
|
|
@ -26,12 +26,12 @@ use activitystreams::{
|
|||
};
|
||||
use anyhow::anyhow;
|
||||
use itertools::Itertools;
|
||||
use lemmy_api_structs::{blocking, WebFingerResponse};
|
||||
use lemmy_db_queries::{Crud, DbPool};
|
||||
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post, user::User_};
|
||||
use lemmy_structs::{blocking, WebFingerResponse};
|
||||
use lemmy_utils::{
|
||||
request::{retry, RecvError},
|
||||
settings::Settings,
|
||||
settings::structs::Settings,
|
||||
utils::{scrape_text_for_mentions, MentionData},
|
||||
LemmyError,
|
||||
};
|
||||
|
|
|
@ -23,10 +23,10 @@ use activitystreams::{
|
|||
};
|
||||
use anyhow::Context;
|
||||
use itertools::Itertools;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::DbPool;
|
||||
use lemmy_db_schema::source::community::Community;
|
||||
use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use lemmy_utils::settings::Settings;
|
||||
use lemmy_utils::settings::structs::Settings;
|
||||
use url::{ParseError, Url};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
|
|
@ -21,9 +21,9 @@ use activitystreams::{
|
|||
prelude::*,
|
||||
public,
|
||||
};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_db_schema::source::{community::Community, post::Post, user::User_};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ use activitystreams::{
|
|||
},
|
||||
prelude::*,
|
||||
};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_db_schema::source::{private_message::PrivateMessage, user::User_};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@ use activitystreams::{
|
|||
base::{AnyBase, BaseExt, ExtendsExt},
|
||||
object::ObjectExt,
|
||||
};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{ApubObject, DbPool, Followable};
|
||||
use lemmy_db_schema::source::{
|
||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||
user::User_,
|
||||
};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
|
|
@ -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(());
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ where
|
|||
let hostname = Settings::get().get_hostname_without_port()?;
|
||||
let inboxes: Vec<&Url> = inboxes
|
||||
.iter()
|
||||
.filter(|i| i.domain().unwrap() != hostname)
|
||||
.filter(|i| i.domain().expect("valid inbox url") != hostname)
|
||||
.collect();
|
||||
|
||||
let activity = activity.into_any_base()?;
|
||||
|
|
|
@ -6,7 +6,6 @@ pub(crate) fn lemmy_context() -> Result<Vec<AnyBase>, LemmyError> {
|
|||
let context_ext = AnyBase::from_arbitrary_json(json!(
|
||||
{
|
||||
"sc": "http://schema.org#",
|
||||
"category": "sc:category",
|
||||
"sensitive": "as:sensitive",
|
||||
"stickied": "as:stickied",
|
||||
"comments_enabled": {
|
||||
|
|
|
@ -16,9 +16,9 @@ use activitystreams::{
|
|||
};
|
||||
use anyhow::Context;
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{source::community::Community_, ApubObject, Joinable};
|
||||
use lemmy_db_schema::source::community::{Community, CommunityModerator, CommunityModeratorForm};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use log::debug;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::{fetcher::fetch::fetch_remote_object, objects::FromApub, NoteExt, PageExt};
|
||||
use anyhow::anyhow;
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{ApubObject, Crud};
|
||||
use lemmy_db_schema::source::{comment::Comment, post::Post};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use log::debug;
|
||||
|
|
|
@ -15,6 +15,7 @@ use crate::{
|
|||
};
|
||||
use activitystreams::base::BaseExt;
|
||||
use anyhow::{anyhow, Context};
|
||||
use lemmy_api_structs::{blocking, site::SearchResponse};
|
||||
use lemmy_db_queries::{
|
||||
source::{
|
||||
comment::Comment_,
|
||||
|
@ -34,8 +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_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;
|
||||
|
|
|
@ -5,9 +5,9 @@ use crate::{
|
|||
};
|
||||
use anyhow::anyhow;
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{source::user::User, ApubObject};
|
||||
use lemmy_db_schema::source::user::User_;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use log::debug;
|
||||
|
|
|
@ -4,9 +4,9 @@ use crate::{
|
|||
};
|
||||
use actix_web::{body::Body, web, web::Path, HttpResponse};
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_db_schema::source::comment::Comment;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use serde::Deserialize;
|
||||
|
|
|
@ -9,10 +9,10 @@ use activitystreams::{
|
|||
collection::{CollectionExt, OrderedCollection, UnorderedCollection},
|
||||
};
|
||||
use actix_web::{body::Body, web, HttpResponse};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::source::{activity::Activity_, community::Community_};
|
||||
use lemmy_db_schema::source::{activity::Activity, community::Community};
|
||||
use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use serde::Deserialize;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::APUB_JSON_CONTENT_TYPE;
|
||||
use actix_web::{body::Body, web, HttpResponse};
|
||||
use http::StatusCode;
|
||||
use lemmy_api_structs::blocking;
|
||||
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};
|
||||
use url::Url;
|
||||
|
||||
pub mod comment;
|
||||
pub mod community;
|
||||
|
@ -46,12 +47,13 @@ pub async fn get_activity(
|
|||
context: web::Data<LemmyContext>,
|
||||
) -> Result<HttpResponse<Body>, LemmyError> {
|
||||
let settings = Settings::get();
|
||||
let activity_id = format!(
|
||||
let activity_id = Url::parse(&format!(
|
||||
"{}/activities/{}/{}",
|
||||
settings.get_protocol_and_hostname(),
|
||||
info.type_,
|
||||
info.id
|
||||
);
|
||||
))?
|
||||
.into();
|
||||
let activity = blocking(context.pool(), move |conn| {
|
||||
Activity::read_from_apub_id(&conn, &activity_id)
|
||||
})
|
||||
|
|
|
@ -4,9 +4,9 @@ use crate::{
|
|||
};
|
||||
use actix_web::{body::Body, web, HttpResponse};
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_db_schema::source::post::Post;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use serde::Deserialize;
|
||||
|
|
|
@ -9,9 +9,9 @@ use activitystreams::{
|
|||
collection::{CollectionExt, OrderedCollection},
|
||||
};
|
||||
use actix_web::{body::Body, web, HttpResponse};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::source::user::User;
|
||||
use lemmy_db_schema::source::user::User_;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use serde::Deserialize;
|
||||
|
|
|
@ -26,13 +26,13 @@ use activitystreams::{
|
|||
};
|
||||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
use anyhow::{anyhow, Context};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{source::community::Community_, ApubObject, DbPool, Followable};
|
||||
use lemmy_db_schema::source::{
|
||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||
user::User_,
|
||||
};
|
||||
use lemmy_db_views_actor::community_user_ban_view::CommunityUserBanView;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use log::info;
|
||||
|
|
|
@ -12,14 +12,14 @@ use activitystreams::{
|
|||
};
|
||||
use actix_web::HttpRequest;
|
||||
use anyhow::{anyhow, Context};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{
|
||||
source::{activity::Activity_, community::Community_},
|
||||
ApubObject,
|
||||
DbPool,
|
||||
};
|
||||
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;
|
||||
|
@ -45,7 +45,7 @@ pub(crate) async fn is_activity_already_known(
|
|||
pool: &DbPool,
|
||||
activity_id: &Url,
|
||||
) -> Result<bool, LemmyError> {
|
||||
let activity_id = activity_id.to_string();
|
||||
let activity_id = activity_id.to_owned().into();
|
||||
let existing = blocking(pool, move |conn| {
|
||||
Activity::read_from_apub_id(&conn, &activity_id)
|
||||
})
|
||||
|
@ -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: {:?}",
|
||||
|
|
|
@ -43,9 +43,9 @@ use activitystreams::{
|
|||
};
|
||||
use anyhow::Context;
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_db_schema::source::site::Site;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use strum_macros::EnumString;
|
||||
|
@ -120,9 +120,9 @@ pub(in crate::inbox) async fn receive_like_for_community(
|
|||
.as_single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||
PostOrComment::Post(post) => receive_like_post(like, post, context, request_counter).await,
|
||||
PostOrComment::Post(post) => receive_like_post(like, *post, context, request_counter).await,
|
||||
PostOrComment::Comment(comment) => {
|
||||
receive_like_comment(like, comment, context, request_counter).await
|
||||
receive_like_comment(like, *comment, context, request_counter).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,10 +152,10 @@ pub(in crate::inbox) async fn receive_dislike_for_community(
|
|||
.context(location_info!())?;
|
||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||
PostOrComment::Post(post) => {
|
||||
receive_dislike_post(dislike, post, context, request_counter).await
|
||||
receive_dislike_post(dislike, *post, context, request_counter).await
|
||||
}
|
||||
PostOrComment::Comment(comment) => {
|
||||
receive_dislike_comment(dislike, comment, context, request_counter).await
|
||||
receive_dislike_comment(dislike, *comment, context, request_counter).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,8 +177,8 @@ pub(in crate::inbox) async fn receive_delete_for_community(
|
|||
.context(location_info!())?;
|
||||
|
||||
match find_post_or_comment_by_id(context, object).await {
|
||||
Ok(PostOrComment::Post(p)) => receive_delete_post(context, p).await,
|
||||
Ok(PostOrComment::Comment(c)) => receive_delete_comment(context, c).await,
|
||||
Ok(PostOrComment::Post(p)) => receive_delete_post(context, *p).await,
|
||||
Ok(PostOrComment::Comment(c)) => receive_delete_comment(context, *c).await,
|
||||
// if we dont have the object, no need to do anything
|
||||
Err(_) => Ok(()),
|
||||
}
|
||||
|
@ -215,8 +215,8 @@ pub(in crate::inbox) async fn receive_remove_for_community(
|
|||
remove.id(community_id.domain().context(location_info!())?)?;
|
||||
|
||||
match find_post_or_comment_by_id(context, object).await {
|
||||
Ok(PostOrComment::Post(p)) => receive_remove_post(context, remove, p).await,
|
||||
Ok(PostOrComment::Comment(c)) => receive_remove_comment(context, remove, c).await,
|
||||
Ok(PostOrComment::Post(p)) => receive_remove_post(context, remove, *p).await,
|
||||
Ok(PostOrComment::Comment(c)) => receive_remove_comment(context, remove, *c).await,
|
||||
// if we dont have the object, no need to do anything
|
||||
Err(_) => Ok(()),
|
||||
}
|
||||
|
@ -276,8 +276,8 @@ pub(in crate::inbox) async fn receive_undo_delete_for_community(
|
|||
.single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
match find_post_or_comment_by_id(context, object).await {
|
||||
Ok(PostOrComment::Post(p)) => receive_undo_delete_post(context, p).await,
|
||||
Ok(PostOrComment::Comment(c)) => receive_undo_delete_comment(context, c).await,
|
||||
Ok(PostOrComment::Post(p)) => receive_undo_delete_post(context, *p).await,
|
||||
Ok(PostOrComment::Comment(c)) => receive_undo_delete_comment(context, *c).await,
|
||||
// if we dont have the object, no need to do anything
|
||||
Err(_) => Ok(()),
|
||||
}
|
||||
|
@ -300,8 +300,8 @@ pub(in crate::inbox) async fn receive_undo_remove_for_community(
|
|||
.single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
match find_post_or_comment_by_id(context, object).await {
|
||||
Ok(PostOrComment::Post(p)) => receive_undo_remove_post(context, p).await,
|
||||
Ok(PostOrComment::Comment(c)) => receive_undo_remove_comment(context, c).await,
|
||||
Ok(PostOrComment::Post(p)) => receive_undo_remove_post(context, *p).await,
|
||||
Ok(PostOrComment::Comment(c)) => receive_undo_remove_comment(context, *c).await,
|
||||
// if we dont have the object, no need to do anything
|
||||
Err(_) => Ok(()),
|
||||
}
|
||||
|
@ -325,10 +325,10 @@ pub(in crate::inbox) async fn receive_undo_like_for_community(
|
|||
.context(location_info!())?;
|
||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||
PostOrComment::Post(post) => {
|
||||
receive_undo_like_post(&like, post, context, request_counter).await
|
||||
receive_undo_like_post(&like, *post, context, request_counter).await
|
||||
}
|
||||
PostOrComment::Comment(comment) => {
|
||||
receive_undo_like_comment(&like, comment, context, request_counter).await
|
||||
receive_undo_like_comment(&like, *comment, context, request_counter).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -351,10 +351,10 @@ pub(in crate::inbox) async fn receive_undo_dislike_for_community(
|
|||
.context(location_info!())?;
|
||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||
PostOrComment::Post(post) => {
|
||||
receive_undo_dislike_post(&dislike, post, context, request_counter).await
|
||||
receive_undo_dislike_post(&dislike, *post, context, request_counter).await
|
||||
}
|
||||
PostOrComment::Comment(comment) => {
|
||||
receive_undo_dislike_comment(&dislike, comment, context, request_counter).await
|
||||
receive_undo_dislike_comment(&dislike, *comment, context, request_counter).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -365,11 +365,11 @@ async fn fetch_post_or_comment_by_id(
|
|||
request_counter: &mut i32,
|
||||
) -> Result<PostOrComment, LemmyError> {
|
||||
if let Ok(post) = get_or_fetch_and_insert_post(apub_id, context, request_counter).await {
|
||||
return Ok(PostOrComment::Post(post));
|
||||
return Ok(PostOrComment::Post(Box::new(post)));
|
||||
}
|
||||
|
||||
if let Ok(comment) = get_or_fetch_and_insert_comment(apub_id, context, request_counter).await {
|
||||
return Ok(PostOrComment::Comment(comment));
|
||||
return Ok(PostOrComment::Comment(Box::new(comment)));
|
||||
}
|
||||
|
||||
Err(NotFound.into())
|
||||
|
|
|
@ -15,9 +15,9 @@ use crate::{
|
|||
use activitystreams::{activity::ActorAndObject, prelude::*};
|
||||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{ApubObject, DbPool};
|
||||
use lemmy_db_schema::source::community::Community;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
|
@ -48,13 +48,13 @@ use activitystreams::{
|
|||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
use anyhow::{anyhow, Context};
|
||||
use diesel::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{source::user::User, ApubObject, Followable};
|
||||
use lemmy_db_schema::source::{
|
||||
community::{Community, CommunityFollower},
|
||||
private_message::PrivateMessage,
|
||||
user::User_,
|
||||
};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use log::debug;
|
||||
|
@ -143,7 +143,14 @@ pub(crate) async fn user_receive_message(
|
|||
let actor_url = actor.actor_id();
|
||||
match kind {
|
||||
UserValidTypes::Accept => {
|
||||
receive_accept(&context, any_base, actor, to_user.unwrap(), request_counter).await?;
|
||||
receive_accept(
|
||||
&context,
|
||||
any_base,
|
||||
actor,
|
||||
to_user.expect("user provided"),
|
||||
request_counter,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
UserValidTypes::Announce => {
|
||||
receive_announce(&context, any_base, actor, request_counter).await?
|
||||
|
|
|
@ -24,17 +24,20 @@ use activitystreams::{
|
|||
use activitystreams_ext::{Ext1, Ext2};
|
||||
use anyhow::{anyhow, Context};
|
||||
use diesel::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{source::activity::Activity_, ApubObject, DbPool};
|
||||
use lemmy_db_schema::source::{
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
activity::Activity,
|
||||
comment::Comment,
|
||||
community::Community,
|
||||
post::Post,
|
||||
private_message::PrivateMessage,
|
||||
user::User_,
|
||||
},
|
||||
DbUrl,
|
||||
};
|
||||
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;
|
||||
|
@ -64,7 +67,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 +91,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(())
|
||||
|
@ -215,7 +219,7 @@ pub enum EndpointType {
|
|||
pub fn generate_apub_endpoint(
|
||||
endpoint_type: EndpointType,
|
||||
name: &str,
|
||||
) -> Result<lemmy_db_schema::Url, ParseError> {
|
||||
) -> Result<DbUrl, ParseError> {
|
||||
let point = match endpoint_type {
|
||||
EndpointType::Community => "c",
|
||||
EndpointType::User => "u",
|
||||
|
@ -235,21 +239,15 @@ pub fn generate_apub_endpoint(
|
|||
)
|
||||
}
|
||||
|
||||
pub fn generate_followers_url(
|
||||
actor_id: &lemmy_db_schema::Url,
|
||||
) -> Result<lemmy_db_schema::Url, ParseError> {
|
||||
pub fn generate_followers_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
|
||||
Ok(Url::parse(&format!("{}/followers", actor_id))?.into())
|
||||
}
|
||||
|
||||
pub fn generate_inbox_url(
|
||||
actor_id: &lemmy_db_schema::Url,
|
||||
) -> Result<lemmy_db_schema::Url, ParseError> {
|
||||
pub fn generate_inbox_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
|
||||
Ok(Url::parse(&format!("{}/inbox", actor_id))?.into())
|
||||
}
|
||||
|
||||
pub fn generate_shared_inbox_url(
|
||||
actor_id: &lemmy_db_schema::Url,
|
||||
) -> Result<lemmy_db_schema::Url, LemmyError> {
|
||||
pub fn generate_shared_inbox_url(actor_id: &DbUrl) -> Result<DbUrl, LemmyError> {
|
||||
let actor_id = actor_id.clone().into_inner();
|
||||
let url = format!(
|
||||
"{}://{}{}/inbox",
|
||||
|
@ -276,7 +274,7 @@ pub(crate) async fn insert_activity<T>(
|
|||
where
|
||||
T: Serialize + std::fmt::Debug + Send + 'static,
|
||||
{
|
||||
let ap_id = ap_id.to_string();
|
||||
let ap_id = ap_id.to_owned().into();
|
||||
blocking(pool, move |conn| {
|
||||
Activity::insert(conn, ap_id, &activity, local, sensitive)
|
||||
})
|
||||
|
@ -285,8 +283,8 @@ where
|
|||
}
|
||||
|
||||
pub(crate) enum PostOrComment {
|
||||
Comment(Comment),
|
||||
Post(Post),
|
||||
Comment(Box<Comment>),
|
||||
Post(Box<Post>),
|
||||
}
|
||||
|
||||
/// Tries to find a post or comment in the local database, without any network requests.
|
||||
|
@ -302,7 +300,7 @@ pub(crate) async fn find_post_or_comment_by_id(
|
|||
})
|
||||
.await?;
|
||||
if let Ok(p) = post {
|
||||
return Ok(PostOrComment::Post(p));
|
||||
return Ok(PostOrComment::Post(Box::new(p)));
|
||||
}
|
||||
|
||||
let ap_id = apub_id.clone();
|
||||
|
@ -311,7 +309,7 @@ pub(crate) async fn find_post_or_comment_by_id(
|
|||
})
|
||||
.await?;
|
||||
if let Ok(c) = comment {
|
||||
return Ok(PostOrComment::Comment(c));
|
||||
return Ok(PostOrComment::Comment(Box::new(c)));
|
||||
}
|
||||
|
||||
Err(NotFound.into())
|
||||
|
@ -332,8 +330,8 @@ pub(crate) async fn find_object_by_id(
|
|||
let ap_id = apub_id.clone();
|
||||
if let Ok(pc) = find_post_or_comment_by_id(context, ap_id.to_owned()).await {
|
||||
return Ok(match pc {
|
||||
PostOrComment::Post(p) => Object::Post(p),
|
||||
PostOrComment::Comment(c) => Object::Comment(c),
|
||||
PostOrComment::Post(p) => Object::Post(*p),
|
||||
PostOrComment::Comment(c) => Object::Comment(*c),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@ use activitystreams::{
|
|||
public,
|
||||
};
|
||||
use anyhow::{anyhow, Context};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{Crud, DbPool};
|
||||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentForm},
|
||||
post::Post,
|
||||
user::User_,
|
||||
};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{
|
||||
location_info,
|
||||
utils::{convert_datetime, remove_slurs},
|
||||
|
|
|
@ -22,13 +22,13 @@ use activitystreams::{
|
|||
};
|
||||
use activitystreams_ext::Ext2;
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::DbPool;
|
||||
use lemmy_db_schema::{
|
||||
naive_now,
|
||||
source::community::{Community, CommunityForm},
|
||||
};
|
||||
use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{
|
||||
location_info,
|
||||
utils::{check_slurs, check_slurs_opt, convert_datetime},
|
||||
|
@ -73,13 +73,13 @@ impl ToApub for Community {
|
|||
|
||||
if let Some(icon_url) = &self.icon {
|
||||
let mut image = Image::new();
|
||||
image.set_url(Url::parse(icon_url)?);
|
||||
image.set_url::<Url>(icon_url.to_owned().into());
|
||||
group.set_icon(image.into_any_base()?);
|
||||
}
|
||||
|
||||
if let Some(banner_url) = &self.banner {
|
||||
let mut image = Image::new();
|
||||
image.set_url(Url::parse(banner_url)?);
|
||||
image.set_url::<Url>(banner_url.to_owned().into());
|
||||
group.set_image(image.into_any_base()?);
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ impl FromApubToForm<GroupExt> for CommunityForm {
|
|||
.url()
|
||||
.context(location_info!())?
|
||||
.as_single_xsd_any_uri()
|
||||
.map(|u| u.to_string()),
|
||||
.map(|u| u.to_owned().into()),
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
|
@ -185,7 +185,7 @@ impl FromApubToForm<GroupExt> for CommunityForm {
|
|||
.url()
|
||||
.context(location_info!())?
|
||||
.as_single_xsd_any_uri()
|
||||
.map(|u| u.to_string()),
|
||||
.map(|u| u.to_owned().into()),
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
|
|
|
@ -12,12 +12,12 @@ use activitystreams::{
|
|||
use anyhow::{anyhow, Context};
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{ApubObject, Crud, DbPool};
|
||||
use lemmy_db_schema::source::community::Community;
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_db_schema::{source::community::Community, DbUrl};
|
||||
use lemmy_utils::{
|
||||
location_info,
|
||||
settings::Settings,
|
||||
settings::structs::Settings,
|
||||
utils::{convert_datetime, markdown_to_html},
|
||||
LemmyError,
|
||||
};
|
||||
|
@ -96,7 +96,7 @@ where
|
|||
pub(in crate::objects) fn check_object_domain<T, Kind>(
|
||||
apub: &T,
|
||||
expected_domain: Url,
|
||||
) -> Result<lemmy_db_schema::Url, LemmyError>
|
||||
) -> Result<DbUrl, LemmyError>
|
||||
where
|
||||
T: Base + AsBase<Kind>,
|
||||
{
|
||||
|
@ -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())
|
||||
})
|
||||
|
|
|
@ -22,13 +22,16 @@ use activitystreams::{
|
|||
};
|
||||
use activitystreams_ext::Ext1;
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{Crud, DbPool};
|
||||
use lemmy_db_schema::source::{
|
||||
use lemmy_db_schema::{
|
||||
self,
|
||||
source::{
|
||||
community::Community,
|
||||
post::{Post, PostForm},
|
||||
user::User_,
|
||||
},
|
||||
};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{
|
||||
location_info,
|
||||
request::fetch_iframely_and_pictrs_data,
|
||||
|
@ -70,16 +73,13 @@ impl ToApub for Post {
|
|||
set_content_and_source(&mut page, &body)?;
|
||||
}
|
||||
|
||||
// TODO: hacky code because we get self.url == Some("")
|
||||
// https://github.com/LemmyNet/lemmy/issues/602
|
||||
let url = self.url.as_ref().filter(|u| !u.is_empty());
|
||||
if let Some(u) = url {
|
||||
page.set_url(Url::parse(u)?);
|
||||
if let Some(url) = &self.url {
|
||||
page.set_url::<Url>(url.to_owned().into());
|
||||
}
|
||||
|
||||
if let Some(thumbnail_url) = &self.thumbnail_url {
|
||||
let mut image = Image::new();
|
||||
image.set_url(Url::parse(thumbnail_url)?);
|
||||
image.set_url::<Url>(thumbnail_url.to_owned().into());
|
||||
page.set_image(image.into_any_base()?);
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ impl FromApubToForm<PageExt> for PostForm {
|
|||
|
||||
let community = get_to_community(page, context, request_counter).await?;
|
||||
|
||||
let thumbnail_url = match &page.inner.image() {
|
||||
let thumbnail_url: Option<Url> = match &page.inner.image() {
|
||||
Some(any_image) => Image::from_any_base(
|
||||
any_image
|
||||
.to_owned()
|
||||
|
@ -158,7 +158,7 @@ impl FromApubToForm<PageExt> for PostForm {
|
|||
.url()
|
||||
.context(location_info!())?
|
||||
.as_single_xsd_any_uri()
|
||||
.map(|u| u.to_string()),
|
||||
.map(|url| url.to_owned()),
|
||||
None => None,
|
||||
};
|
||||
let url = page
|
||||
|
@ -166,11 +166,11 @@ impl FromApubToForm<PageExt> for PostForm {
|
|||
.url()
|
||||
.map(|u| u.as_single_xsd_any_uri())
|
||||
.flatten()
|
||||
.map(|s| s.to_string());
|
||||
.map(|u| u.to_owned());
|
||||
|
||||
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
||||
if let Some(url) = &url {
|
||||
fetch_iframely_and_pictrs_data(context.client(), Some(url.to_owned())).await
|
||||
fetch_iframely_and_pictrs_data(context.client(), Some(url)).await
|
||||
} else {
|
||||
(None, None, None, thumbnail_url)
|
||||
};
|
||||
|
@ -192,7 +192,7 @@ impl FromApubToForm<PageExt> for PostForm {
|
|||
let body_slurs_removed = body.map(|b| remove_slurs(&b));
|
||||
Ok(PostForm {
|
||||
name,
|
||||
url,
|
||||
url: url.map(|u| u.into()),
|
||||
body: body_slurs_removed,
|
||||
creator_id: creator.id,
|
||||
community_id: community.id,
|
||||
|
@ -214,7 +214,7 @@ impl FromApubToForm<PageExt> for PostForm {
|
|||
embed_title: iframely_title,
|
||||
embed_description: iframely_description,
|
||||
embed_html: iframely_html,
|
||||
thumbnail_url: pictrs_thumbnail,
|
||||
thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
|
||||
ap_id: Some(check_object_domain(page, expected_domain)?),
|
||||
local: false,
|
||||
})
|
||||
|
|
|
@ -19,12 +19,12 @@ use activitystreams::{
|
|||
prelude::*,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{Crud, DbPool};
|
||||
use lemmy_db_schema::source::{
|
||||
private_message::{PrivateMessage, PrivateMessageForm},
|
||||
user::User_,
|
||||
};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{location_info, utils::convert_datetime, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
|
|
@ -18,15 +18,15 @@ use activitystreams::{
|
|||
};
|
||||
use activitystreams_ext::Ext1;
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{ApubObject, DbPool};
|
||||
use lemmy_db_schema::{
|
||||
naive_now,
|
||||
source::user::{UserForm, User_},
|
||||
};
|
||||
use lemmy_structs::blocking;
|
||||
use lemmy_utils::{
|
||||
location_info,
|
||||
settings::Settings,
|
||||
settings::structs::Settings,
|
||||
utils::{check_slurs, check_slurs_opt, convert_datetime},
|
||||
LemmyError,
|
||||
};
|
||||
|
@ -50,13 +50,13 @@ impl ToApub for User_ {
|
|||
|
||||
if let Some(avatar_url) = &self.avatar {
|
||||
let mut image = Image::new();
|
||||
image.set_url(Url::parse(avatar_url)?);
|
||||
image.set_url::<Url>(avatar_url.to_owned().into());
|
||||
person.set_icon(image.into_any_base()?);
|
||||
}
|
||||
|
||||
if let Some(banner_url) = &self.banner {
|
||||
let mut image = Image::new();
|
||||
image.set_url(Url::parse(banner_url)?);
|
||||
image.set_url::<Url>(banner_url.to_owned().into());
|
||||
person.set_image(image.into_any_base()?);
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
})
|
||||
|
@ -126,7 +126,7 @@ impl FromApubToForm<PersonExt> for UserForm {
|
|||
.url()
|
||||
.context(location_info!())?
|
||||
.as_single_xsd_any_uri()
|
||||
.map(|u| u.to_string()),
|
||||
.map(|url| url.to_owned()),
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
|
@ -139,7 +139,7 @@ impl FromApubToForm<PersonExt> for UserForm {
|
|||
.url()
|
||||
.context(location_info!())?
|
||||
.as_single_xsd_any_uri()
|
||||
.map(|u| u.to_string()),
|
||||
.map(|url| url.to_owned()),
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
|
@ -174,8 +174,8 @@ impl FromApubToForm<PersonExt> for UserForm {
|
|||
admin: false,
|
||||
banned: None,
|
||||
email: None,
|
||||
avatar,
|
||||
banner,
|
||||
avatar: avatar.map(|o| o.map(|i| i.into())),
|
||||
banner: banner.map(|o| o.map(|i| i.into())),
|
||||
published: person.inner.published().map(|u| u.to_owned().naive_local()),
|
||||
updated: person.updated().map(|u| u.to_owned().naive_local()),
|
||||
show_nsfw: false,
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -20,7 +20,7 @@ strum = "0.20.0"
|
|||
strum_macros = "0.20.1"
|
||||
log = "0.4.14"
|
||||
sha2 = "0.9.3"
|
||||
url = { version = "2.2.0", features = ["serde"] }
|
||||
url = { version = "2.2.1", features = ["serde"] }
|
||||
lazy_static = "1.4.0"
|
||||
regex = "1.4.3"
|
||||
bcrypt = "0.9.0"
|
||||
|
|
|
@ -13,10 +13,12 @@ extern crate diesel_migrations;
|
|||
extern crate serial_test;
|
||||
|
||||
use diesel::{result::Error, *};
|
||||
use lemmy_db_schema::Url;
|
||||
use lemmy_db_schema::DbUrl;
|
||||
use lemmy_utils::ApiError;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{env, env::VarError};
|
||||
use url::Url;
|
||||
|
||||
pub mod aggregates;
|
||||
pub mod source;
|
||||
|
@ -112,7 +114,7 @@ pub trait Reportable<T> {
|
|||
}
|
||||
|
||||
pub trait ApubObject<T> {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &Url) -> Result<Self, Error>
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error>
|
||||
where
|
||||
Self: Sized;
|
||||
fn upsert(conn: &PgConnection, user_form: &T) -> Result<Self, Error>
|
||||
|
@ -219,6 +221,20 @@ pub fn diesel_option_overwrite(opt: &Option<String>) -> Option<Option<String>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn diesel_option_overwrite_to_url(
|
||||
opt: &Option<String>,
|
||||
) -> Result<Option<Option<DbUrl>>, ApiError> {
|
||||
match opt.as_ref().map(|s| s.as_str()) {
|
||||
// An empty string is an erase
|
||||
Some("") => Ok(Some(None)),
|
||||
Some(str_url) => match Url::parse(str_url) {
|
||||
Ok(url) => Ok(Some(Some(url.into()))),
|
||||
Err(_) => Err(ApiError::err("invalid_url")),
|
||||
},
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
embed_migrations!();
|
||||
|
||||
pub fn establish_unpooled_connection() -> PgConnection {
|
||||
|
@ -231,7 +247,7 @@ pub fn establish_unpooled_connection() -> PgConnection {
|
|||
};
|
||||
let conn =
|
||||
PgConnection::establish(&db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
|
||||
embedded_migrations::run(&conn).unwrap();
|
||||
embedded_migrations::run(&conn).expect("load migrations");
|
||||
conn
|
||||
}
|
||||
|
||||
|
@ -264,7 +280,8 @@ pub fn establish_pooled_connection(
|
|||
|
||||
lazy_static! {
|
||||
static ref EMAIL_REGEX: Regex =
|
||||
Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap();
|
||||
Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
|
||||
.expect("compile email regex");
|
||||
}
|
||||
|
||||
pub mod functions {
|
||||
|
@ -277,7 +294,7 @@ pub mod functions {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::fuzzy_search;
|
||||
use super::{fuzzy_search, *};
|
||||
use crate::is_email_regex;
|
||||
|
||||
#[test]
|
||||
|
@ -291,4 +308,32 @@ mod tests {
|
|||
assert!(is_email_regex("gush@gmail.com"));
|
||||
assert!(!is_email_regex("nada_neutho"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_diesel_option_overwrite() {
|
||||
assert_eq!(diesel_option_overwrite(&None), None);
|
||||
assert_eq!(diesel_option_overwrite(&Some("".to_string())), Some(None));
|
||||
assert_eq!(
|
||||
diesel_option_overwrite(&Some("test".to_string())),
|
||||
Some(Some("test".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_diesel_option_overwrite_to_url() {
|
||||
assert!(matches!(diesel_option_overwrite_to_url(&None), Ok(None)));
|
||||
assert!(matches!(
|
||||
diesel_option_overwrite_to_url(&Some("".to_string())),
|
||||
Ok(Some(None))
|
||||
));
|
||||
assert!(matches!(
|
||||
diesel_option_overwrite_to_url(&Some("invalid_url".to_string())),
|
||||
Err(_)
|
||||
));
|
||||
let example_url = "https://example.com";
|
||||
assert!(matches!(
|
||||
diesel_option_overwrite_to_url(&Some(example_url.to_string())),
|
||||
Ok(Some(Some(url))) if url == Url::parse(&example_url).unwrap().into()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::Crud;
|
||||
use diesel::{dsl::*, result::Error, sql_types::Text, *};
|
||||
use lemmy_db_schema::{source::activity::*, Url};
|
||||
use lemmy_db_schema::{source::activity::*, DbUrl};
|
||||
use log::debug;
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
|
@ -41,7 +41,7 @@ impl Crud<ActivityForm> for Activity {
|
|||
pub trait Activity_ {
|
||||
fn insert<T>(
|
||||
conn: &PgConnection,
|
||||
ap_id: String,
|
||||
ap_id: DbUrl,
|
||||
data: &T,
|
||||
local: bool,
|
||||
sensitive: bool,
|
||||
|
@ -49,20 +49,20 @@ pub trait Activity_ {
|
|||
where
|
||||
T: Serialize + Debug;
|
||||
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &str) -> Result<Activity, Error>;
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Activity, Error>;
|
||||
fn delete_olds(conn: &PgConnection) -> Result<usize, Error>;
|
||||
|
||||
/// Returns up to 20 activities of type `Announce/Create/Page` from the community
|
||||
fn read_community_outbox(
|
||||
conn: &PgConnection,
|
||||
community_actor_id: &Url,
|
||||
community_actor_id: &DbUrl,
|
||||
) -> Result<Vec<Value>, Error>;
|
||||
}
|
||||
|
||||
impl Activity_ for Activity {
|
||||
fn insert<T>(
|
||||
conn: &PgConnection,
|
||||
ap_id: String,
|
||||
ap_id: DbUrl,
|
||||
data: &T,
|
||||
local: bool,
|
||||
sensitive: bool,
|
||||
|
@ -88,7 +88,7 @@ impl Activity_ for Activity {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &str) -> Result<Activity, Error> {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Activity, Error> {
|
||||
use lemmy_db_schema::schema::activity::dsl::*;
|
||||
activity.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ impl Activity_ for Activity {
|
|||
|
||||
fn read_community_outbox(
|
||||
conn: &PgConnection,
|
||||
community_actor_id: &Url,
|
||||
community_actor_id: &DbUrl,
|
||||
) -> Result<Vec<Value>, Error> {
|
||||
use lemmy_db_schema::schema::activity::dsl::*;
|
||||
let res: Vec<Value> = activity
|
||||
|
@ -121,6 +121,7 @@ impl Activity_ for Activity {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
establish_unpooled_connection,
|
||||
source::activity::Activity_,
|
||||
|
@ -134,6 +135,7 @@ mod tests {
|
|||
};
|
||||
use serde_json::Value;
|
||||
use serial_test::serial;
|
||||
use url::Url;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
|
@ -171,8 +173,11 @@ mod tests {
|
|||
|
||||
let inserted_creator = User_::create(&conn, &creator_form).unwrap();
|
||||
|
||||
let ap_id =
|
||||
"https://enterprise.lemmy.ml/activities/delete/f1b5d57c-80f8-4e03-a615-688d552e946c";
|
||||
let ap_id: DbUrl = Url::parse(
|
||||
"https://enterprise.lemmy.ml/activities/delete/f1b5d57c-80f8-4e03-a615-688d552e946c",
|
||||
)
|
||||
.unwrap()
|
||||
.into();
|
||||
let test_json: Value = serde_json::from_str(
|
||||
r#"{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
|
@ -188,7 +193,7 @@ mod tests {
|
|||
)
|
||||
.unwrap();
|
||||
let activity_form = ActivityForm {
|
||||
ap_id: ap_id.to_string(),
|
||||
ap_id: ap_id.clone(),
|
||||
data: test_json.to_owned(),
|
||||
local: true,
|
||||
sensitive: false,
|
||||
|
@ -198,7 +203,7 @@ mod tests {
|
|||
let inserted_activity = Activity::create(&conn, &activity_form).unwrap();
|
||||
|
||||
let expected_activity = Activity {
|
||||
ap_id: Some(ap_id.to_string()),
|
||||
ap_id: Some(ap_id.clone()),
|
||||
id: inserted_activity.id,
|
||||
data: test_json,
|
||||
local: true,
|
||||
|
@ -208,7 +213,7 @@ mod tests {
|
|||
};
|
||||
|
||||
let read_activity = Activity::read(&conn, inserted_activity.id).unwrap();
|
||||
let read_activity_by_apub_id = Activity::read_from_apub_id(&conn, ap_id).unwrap();
|
||||
let read_activity_by_apub_id = Activity::read_from_apub_id(&conn, &ap_id).unwrap();
|
||||
User_::delete(&conn, inserted_creator.id).unwrap();
|
||||
Activity::delete(&conn, inserted_activity.id).unwrap();
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ use lemmy_db_schema::{
|
|||
CommentSaved,
|
||||
CommentSavedForm,
|
||||
},
|
||||
Url,
|
||||
DbUrl,
|
||||
};
|
||||
|
||||
pub trait Comment_ {
|
||||
fn update_ap_id(conn: &PgConnection, comment_id: i32, apub_id: Url) -> Result<Comment, Error>;
|
||||
fn update_ap_id(conn: &PgConnection, comment_id: i32, apub_id: DbUrl) -> Result<Comment, Error>;
|
||||
fn permadelete_for_creator(
|
||||
conn: &PgConnection,
|
||||
for_creator_id: i32,
|
||||
|
@ -43,7 +43,7 @@ pub trait Comment_ {
|
|||
}
|
||||
|
||||
impl Comment_ for Comment {
|
||||
fn update_ap_id(conn: &PgConnection, comment_id: i32, apub_id: Url) -> Result<Self, Error> {
|
||||
fn update_ap_id(conn: &PgConnection, comment_id: i32, apub_id: DbUrl) -> Result<Self, Error> {
|
||||
use lemmy_db_schema::schema::comment::dsl::*;
|
||||
|
||||
diesel::update(comment.find(comment_id))
|
||||
|
@ -145,7 +145,7 @@ impl Crud<CommentForm> for Comment {
|
|||
}
|
||||
|
||||
impl ApubObject<CommentForm> for Comment {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &Url) -> Result<Self, Error> {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
|
||||
use lemmy_db_schema::schema::comment::dsl::*;
|
||||
comment.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use lemmy_db_schema::{
|
|||
CommunityUserBan,
|
||||
CommunityUserBanForm,
|
||||
},
|
||||
Url,
|
||||
DbUrl,
|
||||
};
|
||||
|
||||
mod safe_type {
|
||||
|
@ -90,7 +90,7 @@ impl Crud<CommunityForm> for Community {
|
|||
}
|
||||
|
||||
impl ApubObject<CommunityForm> for Community {
|
||||
fn read_from_apub_id(conn: &PgConnection, for_actor_id: &Url) -> Result<Self, Error> {
|
||||
fn read_from_apub_id(conn: &PgConnection, for_actor_id: &DbUrl) -> Result<Self, Error> {
|
||||
use lemmy_db_schema::schema::community::dsl::*;
|
||||
community
|
||||
.filter(actor_id.eq(for_actor_id))
|
||||
|
@ -131,7 +131,10 @@ pub trait Community_ {
|
|||
new_creator_id: i32,
|
||||
) -> Result<Community, Error>;
|
||||
fn distinct_federated_communities(conn: &PgConnection) -> Result<Vec<String>, Error>;
|
||||
fn read_from_followers_url(conn: &PgConnection, followers_url: &Url) -> Result<Community, Error>;
|
||||
fn read_from_followers_url(
|
||||
conn: &PgConnection,
|
||||
followers_url: &DbUrl,
|
||||
) -> Result<Community, Error>;
|
||||
}
|
||||
|
||||
impl Community_ for Community {
|
||||
|
@ -194,7 +197,7 @@ impl Community_ for Community {
|
|||
|
||||
fn read_from_followers_url(
|
||||
conn: &PgConnection,
|
||||
followers_url_: &Url,
|
||||
followers_url_: &DbUrl,
|
||||
) -> Result<Community, Error> {
|
||||
use lemmy_db_schema::schema::community::dsl::*;
|
||||
community
|
||||
|
|
|
@ -12,7 +12,7 @@ use lemmy_db_schema::{
|
|||
PostSaved,
|
||||
PostSavedForm,
|
||||
},
|
||||
Url,
|
||||
DbUrl,
|
||||
};
|
||||
|
||||
impl Crud<PostForm> for Post {
|
||||
|
@ -42,7 +42,7 @@ impl Crud<PostForm> for Post {
|
|||
pub trait Post_ {
|
||||
//fn read(conn: &PgConnection, post_id: i32) -> Result<Post, Error>;
|
||||
fn list_for_community(conn: &PgConnection, the_community_id: i32) -> Result<Vec<Post>, Error>;
|
||||
fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: Url) -> Result<Post, Error>;
|
||||
fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: DbUrl) -> Result<Post, Error>;
|
||||
fn permadelete_for_creator(conn: &PgConnection, for_creator_id: i32) -> Result<Vec<Post>, Error>;
|
||||
fn update_deleted(conn: &PgConnection, post_id: i32, new_deleted: bool) -> Result<Post, Error>;
|
||||
fn update_removed(conn: &PgConnection, post_id: i32, new_removed: bool) -> Result<Post, Error>;
|
||||
|
@ -68,7 +68,7 @@ impl Post_ for Post {
|
|||
.load::<Self>(conn)
|
||||
}
|
||||
|
||||
fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: Url) -> Result<Self, Error> {
|
||||
fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: DbUrl) -> Result<Self, Error> {
|
||||
use lemmy_db_schema::schema::post::dsl::*;
|
||||
|
||||
diesel::update(post.find(post_id))
|
||||
|
@ -147,7 +147,7 @@ impl Post_ for Post {
|
|||
}
|
||||
|
||||
impl ApubObject<PostForm> for Post {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &Url) -> Result<Self, Error> {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
|
||||
use lemmy_db_schema::schema::post::dsl::*;
|
||||
post.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{ApubObject, Crud};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
use lemmy_db_schema::{naive_now, source::private_message::*, Url};
|
||||
use lemmy_db_schema::{naive_now, source::private_message::*, DbUrl};
|
||||
|
||||
impl Crud<PrivateMessageForm> for PrivateMessage {
|
||||
fn read(conn: &PgConnection, private_message_id: i32) -> Result<Self, Error> {
|
||||
|
@ -28,7 +28,7 @@ impl Crud<PrivateMessageForm> for PrivateMessage {
|
|||
}
|
||||
|
||||
impl ApubObject<PrivateMessageForm> for PrivateMessage {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &Url) -> Result<Self, Error>
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ pub trait PrivateMessage_ {
|
|||
fn update_ap_id(
|
||||
conn: &PgConnection,
|
||||
private_message_id: i32,
|
||||
apub_id: Url,
|
||||
apub_id: DbUrl,
|
||||
) -> Result<PrivateMessage, Error>;
|
||||
fn update_content(
|
||||
conn: &PgConnection,
|
||||
|
@ -80,7 +80,7 @@ impl PrivateMessage_ for PrivateMessage {
|
|||
fn update_ap_id(
|
||||
conn: &PgConnection,
|
||||
private_message_id: i32,
|
||||
apub_id: Url,
|
||||
apub_id: DbUrl,
|
||||
) -> Result<PrivateMessage, Error> {
|
||||
use lemmy_db_schema::schema::private_message::dsl::*;
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ use lemmy_db_schema::{
|
|||
naive_now,
|
||||
schema::user_::dsl::*,
|
||||
source::user::{UserForm, UserSafeSettings, User_},
|
||||
Url,
|
||||
DbUrl,
|
||||
};
|
||||
use lemmy_utils::settings::Settings;
|
||||
use lemmy_utils::settings::structs::Settings;
|
||||
|
||||
mod safe_type {
|
||||
use crate::ToSafe;
|
||||
|
@ -244,7 +244,7 @@ impl Crud<UserForm> for User_ {
|
|||
}
|
||||
|
||||
impl ApubObject<UserForm> for User_ {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &Url) -> Result<Self, Error> {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
|
||||
use lemmy_db_schema::schema::user_::dsl::*;
|
||||
user_
|
||||
.filter(deleted.eq(false))
|
||||
|
|
|
@ -12,4 +12,4 @@ chrono = { version = "0.4.19", features = ["serde"] }
|
|||
serde = { version = "1.0.123", features = ["derive"] }
|
||||
serde_json = { version = "1.0.61", features = ["preserve_order"] }
|
||||
log = "0.4.14"
|
||||
url = { version = "2.2.0", features = ["serde"] }
|
||||
url = { version = "2.2.1", features = ["serde"] }
|
||||
|
|
|
@ -8,21 +8,22 @@ use diesel::{
|
|||
serialize::{Output, ToSql},
|
||||
sql_types::Text,
|
||||
};
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt::{Display, Formatter},
|
||||
io::Write,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
pub mod schema;
|
||||
pub mod source;
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, PartialEq, Serialize, Debug, AsExpression, FromSqlRow)]
|
||||
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, FromSqlRow)]
|
||||
#[sql_type = "Text"]
|
||||
pub struct Url(url::Url);
|
||||
pub struct DbUrl(Url);
|
||||
|
||||
impl<DB: Backend> ToSql<Text, DB> for Url
|
||||
impl<DB: Backend> ToSql<Text, DB> for DbUrl
|
||||
where
|
||||
String: ToSql<Text, DB>,
|
||||
{
|
||||
|
@ -31,37 +32,37 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<DB: Backend> FromSql<Text, DB> for Url
|
||||
impl<DB: Backend> FromSql<Text, DB> for DbUrl
|
||||
where
|
||||
String: FromSql<Text, DB>,
|
||||
{
|
||||
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
|
||||
let str = String::from_sql(bytes)?;
|
||||
Ok(Url(url::Url::parse(&str)?))
|
||||
Ok(DbUrl(Url::parse(&str)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Url {
|
||||
pub fn into_inner(self) -> url::Url {
|
||||
impl DbUrl {
|
||||
pub fn into_inner(self) -> Url {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Url {
|
||||
impl Display for DbUrl {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
self.to_owned().into_inner().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Url> for url::Url {
|
||||
fn from(url: Url) -> Self {
|
||||
impl From<DbUrl> for Url {
|
||||
fn from(url: DbUrl) -> Self {
|
||||
url.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<url::Url> for Url {
|
||||
fn from(url: url::Url) -> Self {
|
||||
Url(url)
|
||||
impl From<Url> for DbUrl {
|
||||
fn from(url: Url) -> Self {
|
||||
DbUrl(url)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::schema::activity;
|
||||
use crate::{schema::activity, DbUrl};
|
||||
use serde_json::Value;
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
@ -10,7 +10,7 @@ pub struct Activity {
|
|||
pub local: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub ap_id: Option<String>,
|
||||
pub ap_id: Option<DbUrl>,
|
||||
pub sensitive: Option<bool>,
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,6 @@ pub struct ActivityForm {
|
|||
pub data: Value,
|
||||
pub local: bool,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub ap_id: String,
|
||||
pub ap_id: DbUrl,
|
||||
pub sensitive: bool,
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
schema::{comment, comment_alias_1, comment_like, comment_saved},
|
||||
source::post::Post,
|
||||
Url,
|
||||
DbUrl,
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
|
@ -26,7 +26,7 @@ pub struct Comment {
|
|||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub deleted: bool,
|
||||
pub ap_id: Url,
|
||||
pub ap_id: DbUrl,
|
||||
pub local: bool,
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ pub struct CommentAlias1 {
|
|||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub deleted: bool,
|
||||
pub ap_id: Url,
|
||||
pub ap_id: DbUrl,
|
||||
pub local: bool,
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ pub struct CommentForm {
|
|||
pub published: Option<chrono::NaiveDateTime>,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub deleted: Option<bool>,
|
||||
pub ap_id: Option<Url>,
|
||||
pub ap_id: Option<DbUrl>,
|
||||
pub local: bool,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
schema::{community, community_follower, community_moderator, community_user_ban},
|
||||
Url,
|
||||
DbUrl,
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
|
@ -17,16 +17,16 @@ pub struct Community {
|
|||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub deleted: bool,
|
||||
pub nsfw: bool,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub icon: Option<String>,
|
||||
pub banner: Option<String>,
|
||||
pub followers_url: Url,
|
||||
pub inbox_url: Url,
|
||||
pub shared_inbox_url: Option<Url>,
|
||||
pub icon: Option<DbUrl>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub followers_url: DbUrl,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
/// A safe representation of community, without the sensitive info
|
||||
|
@ -43,10 +43,10 @@ pub struct CommunitySafe {
|
|||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub deleted: bool,
|
||||
pub nsfw: bool,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub local: bool,
|
||||
pub icon: Option<String>,
|
||||
pub banner: Option<String>,
|
||||
pub icon: Option<DbUrl>,
|
||||
pub banner: Option<DbUrl>,
|
||||
}
|
||||
|
||||
#[derive(Insertable, AsChangeset, Debug)]
|
||||
|
@ -61,16 +61,16 @@ pub struct CommunityForm {
|
|||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub deleted: Option<bool>,
|
||||
pub nsfw: bool,
|
||||
pub actor_id: Option<Url>,
|
||||
pub actor_id: Option<DbUrl>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
|
||||
pub icon: Option<Option<String>>,
|
||||
pub banner: Option<Option<String>>,
|
||||
pub followers_url: Option<Url>,
|
||||
pub inbox_url: Option<Url>,
|
||||
pub shared_inbox_url: Option<Option<Url>>,
|
||||
pub icon: Option<Option<DbUrl>>,
|
||||
pub banner: Option<Option<DbUrl>>,
|
||||
pub followers_url: Option<DbUrl>,
|
||||
pub inbox_url: Option<DbUrl>,
|
||||
pub shared_inbox_url: Option<Option<DbUrl>>,
|
||||
}
|
||||
|
||||
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
schema::{post, post_like, post_read, post_saved},
|
||||
Url,
|
||||
DbUrl,
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
|
@ -9,7 +9,7 @@ use serde::Serialize;
|
|||
pub struct Post {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub url: Option<String>,
|
||||
pub url: Option<DbUrl>,
|
||||
pub body: Option<String>,
|
||||
pub creator_id: i32,
|
||||
pub community_id: i32,
|
||||
|
@ -23,8 +23,8 @@ pub struct Post {
|
|||
pub embed_title: Option<String>,
|
||||
pub embed_description: Option<String>,
|
||||
pub embed_html: Option<String>,
|
||||
pub thumbnail_url: Option<String>,
|
||||
pub ap_id: Url,
|
||||
pub thumbnail_url: Option<DbUrl>,
|
||||
pub ap_id: DbUrl,
|
||||
pub local: bool,
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ pub struct Post {
|
|||
#[table_name = "post"]
|
||||
pub struct PostForm {
|
||||
pub name: String,
|
||||
pub url: Option<String>,
|
||||
pub url: Option<DbUrl>,
|
||||
pub body: Option<String>,
|
||||
pub creator_id: i32,
|
||||
pub community_id: i32,
|
||||
|
@ -46,8 +46,8 @@ pub struct PostForm {
|
|||
pub embed_title: Option<String>,
|
||||
pub embed_description: Option<String>,
|
||||
pub embed_html: Option<String>,
|
||||
pub thumbnail_url: Option<String>,
|
||||
pub ap_id: Option<Url>,
|
||||
pub thumbnail_url: Option<DbUrl>,
|
||||
pub ap_id: Option<DbUrl>,
|
||||
pub local: bool,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{schema::post_report, source::post::Post};
|
||||
use crate::{schema::post_report, source::post::Post, DbUrl};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(
|
||||
|
@ -11,7 +11,7 @@ pub struct PostReport {
|
|||
pub creator_id: i32,
|
||||
pub post_id: i32,
|
||||
pub original_post_name: String,
|
||||
pub original_post_url: Option<String>,
|
||||
pub original_post_url: Option<DbUrl>,
|
||||
pub original_post_body: Option<String>,
|
||||
pub reason: String,
|
||||
pub resolved: bool,
|
||||
|
@ -26,7 +26,7 @@ pub struct PostReportForm {
|
|||
pub creator_id: i32,
|
||||
pub post_id: i32,
|
||||
pub original_post_name: String,
|
||||
pub original_post_url: Option<String>,
|
||||
pub original_post_url: Option<DbUrl>,
|
||||
pub original_post_body: Option<String>,
|
||||
pub reason: String,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{schema::private_message, Url};
|
||||
use crate::{schema::private_message, DbUrl};
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)]
|
||||
|
@ -12,7 +12,7 @@ pub struct PrivateMessage {
|
|||
pub read: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub ap_id: Url,
|
||||
pub ap_id: DbUrl,
|
||||
pub local: bool,
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,6 @@ pub struct PrivateMessageForm {
|
|||
pub read: Option<bool>,
|
||||
pub published: Option<chrono::NaiveDateTime>,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub ap_id: Option<Url>,
|
||||
pub ap_id: Option<DbUrl>,
|
||||
pub local: bool,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::schema::site;
|
||||
use crate::{schema::site, DbUrl};
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Queryable, Identifiable, PartialEq, Debug, Clone, Serialize)]
|
||||
|
@ -13,8 +13,8 @@ pub struct Site {
|
|||
pub enable_downvotes: bool,
|
||||
pub open_registration: bool,
|
||||
pub enable_nsfw: bool,
|
||||
pub icon: Option<String>,
|
||||
pub banner: Option<String>,
|
||||
pub icon: Option<DbUrl>,
|
||||
pub banner: Option<DbUrl>,
|
||||
}
|
||||
|
||||
#[derive(Insertable, AsChangeset)]
|
||||
|
@ -28,6 +28,6 @@ pub struct SiteForm {
|
|||
pub open_registration: bool,
|
||||
pub enable_nsfw: bool,
|
||||
// when you want to null out a column, you have to send Some(None)), since sending None means you just don't want to update that column.
|
||||
pub icon: Option<Option<String>>,
|
||||
pub banner: Option<Option<String>>,
|
||||
pub icon: Option<Option<DbUrl>>,
|
||||
pub banner: Option<Option<DbUrl>>,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
schema::{user_, user_alias_1, user_alias_2},
|
||||
Url,
|
||||
DbUrl,
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
|
@ -12,7 +12,7 @@ pub struct User_ {
|
|||
pub preferred_username: Option<String>,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
|
@ -25,16 +25,16 @@ pub struct User_ {
|
|||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<String>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: Url,
|
||||
pub shared_inbox_url: Option<Url>,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
pub validator_time: chrono::NaiveDateTime,
|
||||
}
|
||||
|
||||
|
@ -45,19 +45,19 @@ pub struct UserSafe {
|
|||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<String>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: Url,
|
||||
pub shared_inbox_url: Option<Url>,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
/// A safe user view with only settings
|
||||
|
@ -68,7 +68,7 @@ pub struct UserSafeSettings {
|
|||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub email: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
|
@ -81,11 +81,11 @@ pub struct UserSafeSettings {
|
|||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<String>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub validator_time: chrono::NaiveDateTime,
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ pub struct UserAlias1 {
|
|||
pub preferred_username: Option<String>,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
|
@ -111,13 +111,13 @@ pub struct UserAlias1 {
|
|||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<String>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
|
@ -127,16 +127,16 @@ pub struct UserSafeAlias1 {
|
|||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<String>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ pub struct UserAlias2 {
|
|||
pub preferred_username: Option<String>,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
|
@ -161,13 +161,13 @@ pub struct UserAlias2 {
|
|||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<String>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
|
@ -177,16 +177,16 @@ pub struct UserSafeAlias2 {
|
|||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: Url,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<String>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ pub struct UserForm {
|
|||
pub admin: bool,
|
||||
pub banned: Option<bool>,
|
||||
pub email: Option<Option<String>>,
|
||||
pub avatar: Option<Option<String>>,
|
||||
pub avatar: Option<Option<DbUrl>>,
|
||||
pub published: Option<chrono::NaiveDateTime>,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub show_nsfw: bool,
|
||||
|
@ -210,13 +210,13 @@ pub struct UserForm {
|
|||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<Option<String>>,
|
||||
pub actor_id: Option<Url>,
|
||||
pub actor_id: Option<DbUrl>,
|
||||
pub bio: Option<Option<String>>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
|
||||
pub banner: Option<Option<String>>,
|
||||
pub inbox_url: Option<Url>,
|
||||
pub shared_inbox_url: Option<Option<Url>>,
|
||||
pub banner: Option<Option<DbUrl>>,
|
||||
pub inbox_url: Option<DbUrl>,
|
||||
pub shared_inbox_url: Option<Option<DbUrl>>,
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ lemmy_db_schema = { path = "../db_schema" }
|
|||
diesel = { version = "1.4.5", features = ["postgres","chrono","r2d2","serde_json"] }
|
||||
serde = { version = "1.0.123", features = ["derive"] }
|
||||
log = "0.4.14"
|
||||
url = "2.2.0"
|
||||
url = "2.2.1"
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.5.1"
|
|
@ -13,7 +13,7 @@ lemmy_db_queries = { path = "../db_queries" }
|
|||
lemmy_db_views = { path = "../db_views" }
|
||||
lemmy_db_views_actor = { path = "../db_views_actor" }
|
||||
lemmy_db_schema = { path = "../db_schema" }
|
||||
lemmy_structs = { path = "../structs" }
|
||||
lemmy_api_structs = { path = "../api_structs" }
|
||||
diesel = "1.4.5"
|
||||
actix = "0.10.0"
|
||||
actix-web = { version = "3.3.2", default-features = false, features = ["rustls"] }
|
||||
|
@ -25,6 +25,6 @@ chrono = { version = "0.4.19", features = ["serde"] }
|
|||
rss = "1.10.0"
|
||||
serde = { version = "1.0.123", features = ["derive"] }
|
||||
awc = { version = "2.0.3", default-features = false }
|
||||
url = { version = "2.2.0", features = ["serde"] }
|
||||
url = { version = "2.2.1", features = ["serde"] }
|
||||
strum = "0.20.0"
|
||||
lazy_static = "1.4.0"
|
||||
|
|
|
@ -2,6 +2,7 @@ use actix_web::{error::ErrorBadRequest, *};
|
|||
use anyhow::anyhow;
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use diesel::PgConnection;
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{
|
||||
source::{community::Community_, user::User},
|
||||
ListingType,
|
||||
|
@ -14,8 +15,12 @@ use lemmy_db_views::{
|
|||
site_view::SiteView,
|
||||
};
|
||||
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,
|
||||
|
@ -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)
|
||||
|
@ -391,9 +396,6 @@ fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
|
|||
p.community.name
|
||||
);
|
||||
|
||||
// TODO: for category we should just put the name of the category, but then we would have
|
||||
// to read each community from the db
|
||||
|
||||
// TODO add images
|
||||
let mut description = format!("submitted by <a href=\"{}\">{}</a> to <a href=\"{}\">{}</a><br>{} points | <a href=\"{}\">{} comments</a>",
|
||||
p.creator.actor_id,
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use actix_web::{body::Body, error::ErrorBadRequest, *};
|
||||
use anyhow::anyhow;
|
||||
use lemmy_api_structs::blocking;
|
||||
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;
|
||||
|
@ -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![]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use actix_web::{error::ErrorBadRequest, web::Query, *};
|
||||
use anyhow::anyhow;
|
||||
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_structs::{blocking, WebFingerLink, WebFingerResponse};
|
||||
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),
|
||||
|
|
|
@ -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"
|
||||
|
@ -23,7 +22,7 @@ thiserror = "1.0.23"
|
|||
comrak = { version = "0.9.0", default-features = false }
|
||||
lazy_static = "1.4.0"
|
||||
openssl = "0.10.32"
|
||||
url = { version = "2.2.0", features = ["serde"] }
|
||||
url = { version = "2.2.1", features = ["serde"] }
|
||||
actix-web = { version = "3.3.2", default-features = false, features = ["rustls"] }
|
||||
actix-rt = { version = "1.1.1", default-features = false }
|
||||
anyhow = "1.0.38"
|
||||
|
@ -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"
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
@ -24,7 +24,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,
|
||||
)
|
||||
}
|
||||
|
@ -39,7 +39,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()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>>();
|
||||
|
|
|
@ -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();
|
||||
.expect("compile webfinger regex");
|
||||
pub static ref WEBFINGER_USER_REGEX: Regex = Regex::new(&format!(
|
||||
"^acct:([a-z0-9_]{{3, 20}})@{}$",
|
||||
Settings::get().hostname
|
||||
Settings::get().hostname()
|
||||
))
|
||||
.unwrap();
|
||||
.expect("compile webfinger regex");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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};
|
||||
|
@ -6,6 +6,7 @@ use reqwest::Client;
|
|||
use serde::Deserialize;
|
||||
use std::future::Future;
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("Error sending request, {0}")]
|
||||
|
@ -43,22 +44,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
response.unwrap()
|
||||
response.expect("retry http request")
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub(crate) struct IframelyResponse {
|
||||
title: Option<String>,
|
||||
description: Option<String>,
|
||||
thumbnail_url: Option<String>,
|
||||
thumbnail_url: Option<Url>,
|
||||
html: Option<String>,
|
||||
}
|
||||
|
||||
pub(crate) async fn fetch_iframely(
|
||||
client: &Client,
|
||||
url: &str,
|
||||
url: &Url,
|
||||
) -> 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?;
|
||||
|
||||
|
@ -83,14 +84,14 @@ pub(crate) struct PictrsFile {
|
|||
|
||||
pub(crate) async fn fetch_pictrs(
|
||||
client: &Client,
|
||||
image_url: &str,
|
||||
image_url: &Url,
|
||||
) -> Result<PictrsResponse, LemmyError> {
|
||||
is_image_content_type(client, image_url).await?;
|
||||
|
||||
let fetch_url = format!(
|
||||
"{}/image/download?url={}",
|
||||
Settings::get().pictrs_url,
|
||||
utf8_percent_encode(image_url, NON_ALPHANUMERIC) // TODO this might not be needed
|
||||
Settings::get().pictrs_url(),
|
||||
utf8_percent_encode(image_url.as_str(), NON_ALPHANUMERIC) // TODO this might not be needed
|
||||
);
|
||||
|
||||
let response = retry(|| client.get(&fetch_url).send()).await?;
|
||||
|
@ -109,13 +110,8 @@ pub(crate) async fn fetch_pictrs(
|
|||
|
||||
pub async fn fetch_iframely_and_pictrs_data(
|
||||
client: &Client,
|
||||
url: Option<String>,
|
||||
) -> (
|
||||
Option<String>,
|
||||
Option<String>,
|
||||
Option<String>,
|
||||
Option<String>,
|
||||
) {
|
||||
url: Option<&Url>,
|
||||
) -> (Option<String>, Option<String>, Option<String>, Option<Url>) {
|
||||
match &url {
|
||||
Some(url) => {
|
||||
// Fetch iframely data
|
||||
|
@ -149,11 +145,19 @@ pub async fn fetch_iframely_and_pictrs_data(
|
|||
|
||||
// The full urls are necessary for federation
|
||||
let pictrs_thumbnail = if let Some(pictrs_hash) = pictrs_hash {
|
||||
Some(format!(
|
||||
let url = Url::parse(&format!(
|
||||
"{}/pictrs/image/{}",
|
||||
Settings::get().get_protocol_and_hostname(),
|
||||
pictrs_hash
|
||||
))
|
||||
));
|
||||
match url {
|
||||
Ok(parsed_url) => Some(parsed_url),
|
||||
Err(e) => {
|
||||
// This really shouldn't happen unless the settings or hash are malformed
|
||||
error!("Unexpected error constructing pictrs thumbnail URL: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -169,9 +173,8 @@ pub async fn fetch_iframely_and_pictrs_data(
|
|||
}
|
||||
}
|
||||
|
||||
async fn is_image_content_type(client: &Client, test: &str) -> Result<(), LemmyError> {
|
||||
let response = retry(|| client.get(test).send()).await?;
|
||||
|
||||
async fn is_image_content_type(client: &Client, test: &Url) -> Result<(), LemmyError> {
|
||||
let response = retry(|| client.get(test.to_owned()).send()).await?;
|
||||
if response
|
||||
.headers()
|
||||
.get("Content-Type")
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
69
crates/utils/src/settings/defaults.rs
Normal file
69
crates/utils/src/settings/defaults.rs
Normal file
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
172
crates/utils/src/settings/mod.rs
Normal file
172
crates/utils/src/settings/mod.rs
Normal file
|
@ -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().expect("read config").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, LemmyError> {
|
||||
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().expect("write config");
|
||||
*new_settings = match Settings::init() {
|
||||
Ok(c) => c,
|
||||
Err(e) => panic!("{}", e),
|
||||
};
|
||||
|
||||
Ok(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.expect("return bind address")
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
72
crates/utils/src/settings/structs.rs
Normal file
72
crates/utils/src/settings/structs.rs
Normal file
|
@ -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,
|
||||
}
|
|
@ -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;
|
||||
|
@ -6,15 +6,15 @@ use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
|||
use regex::{Regex, RegexBuilder};
|
||||
|
||||
lazy_static! {
|
||||
static ref EMAIL_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap();
|
||||
static ref SLUR_REGEX: Regex = RegexBuilder::new(r"(fag(g|got|tard)?\b|cock\s?sucker(s|ing)?|\bn(i|1)g(\b|g?(a|er)?(s|z)?)\b|mudslime?s?|kikes?|\bspi(c|k)s?\b|\bchinks?|gooks?|bitch(es|ing|y)?|whor(es?|ing)|\btr(a|@)nn?(y|ies?)|\b(b|re|r)tard(ed)?s?)").case_insensitive(true).build().unwrap();
|
||||
static ref USERNAME_MATCHES_REGEX: Regex = Regex::new(r"/u/[a-zA-Z][0-9a-zA-Z_]*").unwrap();
|
||||
static ref EMAIL_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").expect("compile regex");
|
||||
static ref SLUR_REGEX: Regex = RegexBuilder::new(r"(fag(g|got|tard)?\b|cock\s?sucker(s|ing)?|\bn(i|1)g(\b|g?(a|er)?(s|z)?)\b|mudslime?s?|kikes?|\bspi(c|k)s?\b|\bchinks?|gooks?|bitch(es|ing|y)?|whor(es?|ing)|\btr(a|@)nn?(y|ies?)|\b(b|re|r)tard(ed)?s?)").case_insensitive(true).build().expect("compile regex");
|
||||
static ref USERNAME_MATCHES_REGEX: Regex = Regex::new(r"/u/[a-zA-Z][0-9a-zA-Z_]*").expect("compile regex");
|
||||
// TODO keep this old one, it didn't work with port well tho
|
||||
// static ref MENTIONS_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)").unwrap();
|
||||
static ref MENTIONS_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._:-]+)").unwrap();
|
||||
static ref VALID_USERNAME_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9_]{3,20}$").unwrap();
|
||||
static ref VALID_COMMUNITY_NAME_REGEX: Regex = Regex::new(r"^[a-z0-9_]{3,20}$").unwrap();
|
||||
static ref VALID_POST_TITLE_REGEX: Regex = Regex::new(r".*\S.*").unwrap();
|
||||
// static ref MENTIONS_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)").expect("compile regex");
|
||||
static ref MENTIONS_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._:-]+)").expect("compile regex");
|
||||
static ref VALID_USERNAME_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9_]{3,20}$").expect("compile regex");
|
||||
static ref VALID_COMMUNITY_NAME_REGEX: Regex = Regex::new(r"^[a-z0-9_]{3,20}$").expect("compile regex");
|
||||
static ref VALID_POST_TITLE_REGEX: Regex = Regex::new(r".*\S.*").expect("compile regex");
|
||||
}
|
||||
|
||||
pub fn naive_from_unix(time: i64) -> NaiveDateTime {
|
||||
|
@ -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)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
[package]
|
||||
name = "lemmy_websocket"
|
||||
version = "0.1.0"
|
||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
|
@ -11,7 +10,7 @@ doctest = false
|
|||
|
||||
[dependencies]
|
||||
lemmy_utils = { path = "../utils" }
|
||||
lemmy_structs = { path = "../structs" }
|
||||
lemmy_api_structs = { path = "../api_structs" }
|
||||
lemmy_db_queries = { path = "../db_queries" }
|
||||
lemmy_db_schema = { path = "../db_schema" }
|
||||
reqwest = { version = "0.10.10", features = ["json"] }
|
||||
|
|
|
@ -6,7 +6,7 @@ use diesel::{
|
|||
r2d2::{ConnectionManager, Pool},
|
||||
PgConnection,
|
||||
};
|
||||
use lemmy_structs::{comment::*, post::*};
|
||||
use lemmy_api_structs::{comment::*, post::*};
|
||||
use lemmy_utils::{
|
||||
location_info,
|
||||
rate_limit::RateLimit,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::UserOperation;
|
||||
use actix::{prelude::*, Recipient};
|
||||
use lemmy_structs::{comment::CommentResponse, post::PostResponse};
|
||||
use lemmy_api_structs::{comment::CommentResponse, post::PostResponse};
|
||||
use lemmy_utils::{CommunityId, ConnectionId, IpAddr, PostId, UserId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue