mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-29 07:41:20 +00:00
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:
|
steps:
|
||||||
|
|
||||||
- name: chown repo
|
- name: chown repo
|
||||||
image: ekidd/rust-musl-builder:1.47.0
|
image: ekidd/rust-musl-builder:1.50.0
|
||||||
user: root
|
user: root
|
||||||
commands:
|
commands:
|
||||||
- chown 1000:1000 . -R
|
- chown 1000:1000 . -R
|
||||||
|
@ -20,12 +20,13 @@ steps:
|
||||||
- /root/.cargo/bin/cargo fmt -- --check
|
- /root/.cargo/bin/cargo fmt -- --check
|
||||||
|
|
||||||
- name: cargo clippy
|
- name: cargo clippy
|
||||||
image: ekidd/rust-musl-builder:1.47.0
|
image: ekidd/rust-musl-builder:1.50.0
|
||||||
commands:
|
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 --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
|
- name: cargo test
|
||||||
image: ekidd/rust-musl-builder:1.47.0
|
image: ekidd/rust-musl-builder:1.50.0
|
||||||
environment:
|
environment:
|
||||||
LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
|
LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
|
||||||
RUST_BACKTRACE: 1
|
RUST_BACKTRACE: 1
|
||||||
|
@ -35,7 +36,7 @@ steps:
|
||||||
- cargo test --workspace --no-fail-fast
|
- cargo test --workspace --no-fail-fast
|
||||||
|
|
||||||
- name: cargo build
|
- name: cargo build
|
||||||
image: ekidd/rust-musl-builder:1.47.0
|
image: ekidd/rust-musl-builder:1.50.0
|
||||||
commands:
|
commands:
|
||||||
- cargo build
|
- cargo build
|
||||||
- mv target/x86_64-unknown-linux-musl/debug/lemmy_server target/lemmy_server
|
- mv target/x86_64-unknown-linux-musl/debug/lemmy_server target/lemmy_server
|
||||||
|
@ -102,7 +103,7 @@ platform:
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: cargo test
|
- name: cargo test
|
||||||
image: rust:1.47-slim-buster
|
image: rust:1.50-slim-buster
|
||||||
environment:
|
environment:
|
||||||
LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
|
LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
|
||||||
RUST_BACKTRACE: 1
|
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.
|
# Using Debian here because there seems to be no official Alpine-based Rust docker image for ARM.
|
||||||
- name: cargo build
|
- name: cargo build
|
||||||
image: rust:1.47-slim-buster
|
image: rust:1.50-slim-buster
|
||||||
commands:
|
commands:
|
||||||
- apt-get update
|
- apt-get update
|
||||||
- apt-get -y install --no-install-recommends libssl-dev pkg-config libpq-dev
|
- 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 = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"mime",
|
"mime",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"url",
|
"url",
|
||||||
|
@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb8e19a0810cc25df3535061a08b7d8f8a734d309ea4411c57a9767e4a2ffa0e"
|
checksum = "bb8e19a0810cc25df3535061a08b7d8f8a734d309ea4411c57a9767e4a2ffa0e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitystreams",
|
"activitystreams",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ dependencies = [
|
||||||
"pin-project 1.0.4",
|
"pin-project 1.0.4",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"regex",
|
"regex",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sha-1 0.9.3",
|
"sha-1 0.9.3",
|
||||||
|
@ -158,7 +158,7 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -302,7 +302,7 @@ dependencies = [
|
||||||
"pin-project 1.0.4",
|
"pin-project 1.0.4",
|
||||||
"regex",
|
"regex",
|
||||||
"rustls",
|
"rustls",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
@ -391,12 +391,6 @@ version = "1.0.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
|
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arrayvec"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-mutex"
|
name = "async-mutex"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -466,7 +460,7 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rustls",
|
"rustls",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
]
|
]
|
||||||
|
@ -496,7 +490,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio 0.2.25",
|
"tokio 0.2.25",
|
||||||
|
@ -515,7 +509,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"log",
|
"log",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio 0.2.25",
|
"tokio 0.2.25",
|
||||||
|
@ -735,8 +729,8 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits 0.2.14",
|
"num-traits",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"time 0.1.44",
|
"time 0.1.44",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
@ -783,18 +777,6 @@ dependencies = [
|
||||||
"xdg",
|
"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]]
|
[[package]]
|
||||||
name = "const_fn"
|
name = "const_fn"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
|
@ -997,6 +979,15 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deser-hjson"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d995b60ff81bc6af01a98f0bf5db70a7418a1ac8bd74ada633968f388139da5e"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diesel"
|
name = "diesel"
|
||||||
version = "1.4.5"
|
version = "1.4.5"
|
||||||
|
@ -1112,6 +1103,15 @@ dependencies = [
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "envy"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "event-listener"
|
name = "event-listener"
|
||||||
version = "2.5.1"
|
version = "2.5.1"
|
||||||
|
@ -1592,7 +1592,7 @@ dependencies = [
|
||||||
"jpeg-decoder",
|
"jpeg-decoder",
|
||||||
"num-iter",
|
"num-iter",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
"num-traits 0.2.14",
|
"num-traits",
|
||||||
"png",
|
"png",
|
||||||
"scoped_threadpool",
|
"scoped_threadpool",
|
||||||
"tiff",
|
"tiff",
|
||||||
|
@ -1686,7 +1686,7 @@ dependencies = [
|
||||||
"base64 0.12.3",
|
"base64 0.12.3",
|
||||||
"pem",
|
"pem",
|
||||||
"ring",
|
"ring",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"simple_asn1",
|
"simple_asn1",
|
||||||
]
|
]
|
||||||
|
@ -1734,20 +1734,20 @@ dependencies = [
|
||||||
"http-signature-normalization-actix",
|
"http-signature-normalization-actix",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"lemmy_api_structs",
|
||||||
"lemmy_apub",
|
"lemmy_apub",
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"lemmy_db_views",
|
"lemmy_db_views",
|
||||||
"lemmy_db_views_actor",
|
"lemmy_db_views_actor",
|
||||||
"lemmy_db_views_moderator",
|
"lemmy_db_views_moderator",
|
||||||
"lemmy_structs",
|
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"lemmy_websocket",
|
"lemmy_websocket",
|
||||||
"log",
|
"log",
|
||||||
"openssl",
|
"openssl",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"strum",
|
"strum",
|
||||||
|
@ -1758,6 +1758,25 @@ dependencies = [
|
||||||
"uuid",
|
"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]]
|
[[package]]
|
||||||
name = "lemmy_apub"
|
name = "lemmy_apub"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1782,11 +1801,11 @@ dependencies = [
|
||||||
"http-signature-normalization-reqwest",
|
"http-signature-normalization-reqwest",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"lemmy_api_structs",
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"lemmy_db_views",
|
"lemmy_db_views",
|
||||||
"lemmy_db_views_actor",
|
"lemmy_db_views_actor",
|
||||||
"lemmy_structs",
|
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"lemmy_websocket",
|
"lemmy_websocket",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1794,7 +1813,7 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"strum",
|
"strum",
|
||||||
|
@ -1818,7 +1837,7 @@ dependencies = [
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
@ -1834,7 +1853,7 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"log",
|
"log",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
@ -1847,7 +1866,7 @@ dependencies = [
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"log",
|
"log",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
@ -1859,7 +1878,7 @@ dependencies = [
|
||||||
"diesel",
|
"diesel",
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1869,7 +1888,7 @@ dependencies = [
|
||||||
"diesel",
|
"diesel",
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1884,16 +1903,16 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"lemmy_api_structs",
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"lemmy_db_views",
|
"lemmy_db_views",
|
||||||
"lemmy_db_views_actor",
|
"lemmy_db_views_actor",
|
||||||
"lemmy_structs",
|
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"lemmy_websocket",
|
"lemmy_websocket",
|
||||||
"log",
|
"log",
|
||||||
"rss",
|
"rss",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"strum",
|
"strum",
|
||||||
"url",
|
"url",
|
||||||
|
@ -1916,6 +1935,7 @@ dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"http-signature-normalization-actix",
|
"http-signature-normalization-actix",
|
||||||
"lemmy_api",
|
"lemmy_api",
|
||||||
|
"lemmy_api_structs",
|
||||||
"lemmy_apub",
|
"lemmy_apub",
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
|
@ -1923,38 +1943,18 @@ dependencies = [
|
||||||
"lemmy_db_views_actor",
|
"lemmy_db_views_actor",
|
||||||
"lemmy_db_views_moderator",
|
"lemmy_db_views_moderator",
|
||||||
"lemmy_routes",
|
"lemmy_routes",
|
||||||
"lemmy_structs",
|
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"lemmy_websocket",
|
"lemmy_websocket",
|
||||||
"log",
|
"log",
|
||||||
"openssl",
|
"openssl",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
"tokio 0.3.7",
|
"tokio 0.3.7",
|
||||||
"url",
|
"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]]
|
[[package]]
|
||||||
name = "lemmy_utils"
|
name = "lemmy_utils"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1964,8 +1964,9 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"comrak",
|
"comrak",
|
||||||
"config",
|
"deser-hjson",
|
||||||
"diesel",
|
"diesel",
|
||||||
|
"envy",
|
||||||
"futures",
|
"futures",
|
||||||
"http",
|
"http",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
@ -1973,12 +1974,13 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lettre",
|
"lettre",
|
||||||
"log",
|
"log",
|
||||||
|
"merge",
|
||||||
"openssl",
|
"openssl",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
|
@ -1998,14 +2000,14 @@ dependencies = [
|
||||||
"background-jobs",
|
"background-jobs",
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
|
"lemmy_api_structs",
|
||||||
"lemmy_db_queries",
|
"lemmy_db_queries",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"lemmy_structs",
|
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
|
@ -2024,46 +2026,23 @@ dependencies = [
|
||||||
"idna",
|
"idna",
|
||||||
"mime",
|
"mime",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"nom 6.1.0",
|
"nom",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"quoted_printable",
|
"quoted_printable",
|
||||||
"r2d2",
|
"r2d2",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"regex",
|
"regex",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"uuid",
|
"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]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.84"
|
version = "0.2.84"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff"
|
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]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
version = "0.5.4"
|
version = "0.5.4"
|
||||||
|
@ -2106,7 +2085,7 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"linked-hash-map 0.5.4",
|
"linked-hash-map",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2148,6 +2127,28 @@ dependencies = [
|
||||||
"autocfg",
|
"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]]
|
[[package]]
|
||||||
name = "migrations_internals"
|
name = "migrations_internals"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
|
@ -2275,17 +2276,6 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"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]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "6.1.0"
|
version = "6.1.0"
|
||||||
|
@ -2305,7 +2295,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits 0.2.14",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2315,7 +2305,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-traits 0.2.14",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2326,7 +2316,7 @@ checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits 0.2.14",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2337,16 +2327,7 @@ checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits 0.2.14",
|
"num-traits",
|
||||||
]
|
|
||||||
|
|
||||||
[[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",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2601,6 +2582,30 @@ dependencies = [
|
||||||
"vcpkg",
|
"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]]
|
[[package]]
|
||||||
name = "proc-macro-hack"
|
name = "proc-macro-hack"
|
||||||
version = "0.5.19"
|
version = "0.5.19"
|
||||||
|
@ -2842,7 +2847,7 @@ dependencies = [
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite 0.2.4",
|
"pin-project-lite 0.2.4",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio 0.2.25",
|
"tokio 0.2.25",
|
||||||
|
@ -3012,12 +3017,6 @@ version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde"
|
|
||||||
version = "0.8.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.123"
|
version = "1.0.123"
|
||||||
|
@ -3027,19 +3026,6 @@ dependencies = [
|
||||||
"serde_derive",
|
"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]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.123"
|
version = "1.0.123"
|
||||||
|
@ -3060,16 +3046,7 @@ dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
]
|
|
||||||
|
|
||||||
[[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",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3081,7 +3058,7 @@ dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3173,7 +3150,7 @@ checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits 0.2.14",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3214,12 +3191,6 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "static_assertions"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stdweb"
|
name = "stdweb"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
|
@ -3242,7 +3213,7 @@ checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
@ -3256,7 +3227,7 @@ dependencies = [
|
||||||
"base-x",
|
"base-x",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha1",
|
"sha1",
|
||||||
|
@ -3684,15 +3655,15 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.2.0"
|
version = "2.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
|
checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna",
|
||||||
"matches",
|
"matches",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3702,7 +3673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.2",
|
"getrandom 0.2.2",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3746,7 +3717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be"
|
checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"serde 1.0.123",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
|
@ -19,7 +19,7 @@ members = [
|
||||||
"crates/db_views",
|
"crates/db_views",
|
||||||
"crates/db_views_actor",
|
"crates/db_views_actor",
|
||||||
"crates/db_views_actor",
|
"crates/db_views_actor",
|
||||||
"crates/structs",
|
"crates/api_structs",
|
||||||
"crates/websocket",
|
"crates/websocket",
|
||||||
"crates/routes"
|
"crates/routes"
|
||||||
]
|
]
|
||||||
|
@ -33,7 +33,7 @@ lemmy_db_queries = { path = "./crates/db_queries" }
|
||||||
lemmy_db_views = { path = "./crates/db_views" }
|
lemmy_db_views = { path = "./crates/db_views" }
|
||||||
lemmy_db_views_moderator = { path = "./crates/db_views_moderator" }
|
lemmy_db_views_moderator = { path = "./crates/db_views_moderator" }
|
||||||
lemmy_db_views_actor = { path = "./crates/db_views_actor" }
|
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_websocket = { path = "./crates/websocket" }
|
||||||
lemmy_routes = { path = "./crates/routes" }
|
lemmy_routes = { path = "./crates/routes" }
|
||||||
diesel = "1.4.5"
|
diesel = "1.4.5"
|
||||||
|
@ -45,7 +45,7 @@ actix-web = { version = "3.3.2", default-features = false, features = ["rustls"]
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
env_logger = "0.8.2"
|
env_logger = "0.8.2"
|
||||||
strum = "0.20.0"
|
strum = "0.20.0"
|
||||||
url = { version = "2.2.0", features = ["serde"] }
|
url = { version = "2.2.1", features = ["serde"] }
|
||||||
openssl = "0.10.32"
|
openssl = "0.10.32"
|
||||||
http-signature-normalization-actix = { version = "0.4.1", default-features = false, features = ["sha-2"] }
|
http-signature-normalization-actix = { version = "0.4.1", default-features = false, features = ["sha-2"] }
|
||||||
tokio = "0.3.6"
|
tokio = "0.3.6"
|
||||||
|
|
|
@ -29,8 +29,9 @@
|
||||||
# https://join.lemmy.ml/docs/en/federation/administration.html#instance-allowlist-and-blocklist
|
# https://join.lemmy.ml/docs/en/federation/administration.html#instance-allowlist-and-blocklist
|
||||||
#
|
#
|
||||||
# comma separated list of instances with which federation is allowed
|
# 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
|
# 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:
|
services:
|
||||||
lemmy:
|
lemmy:
|
||||||
|
@ -53,6 +53,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./iframely.config.local.js:/iframely/config.local.js:ro
|
- ./iframely.config.local.js:/iframely/config.local.js:ro
|
||||||
restart: always
|
restart: always
|
||||||
|
mem_limit: 200m
|
||||||
|
|
||||||
postfix:
|
postfix:
|
||||||
image: mwader/postfix-relay
|
image: mwader/postfix-relay
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
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 LEMMY_TEST_SEND_SYNC=1
|
||||||
export RUST_BACKTRACE=1
|
export RUST_BACKTRACE=1
|
||||||
|
|
||||||
|
@ -35,52 +28,40 @@ fi
|
||||||
|
|
||||||
killall lemmy_server || true
|
killall lemmy_server || true
|
||||||
|
|
||||||
|
echo "$PWD"
|
||||||
|
|
||||||
echo "start alpha"
|
echo "start alpha"
|
||||||
LEMMY_HOSTNAME=lemmy-alpha:8541 \
|
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_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_alpha" \
|
||||||
LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon \
|
LEMMY_HOSTNAME="lemmy-alpha:8541" \
|
||||||
LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha \
|
target/lemmy_server >/tmp/lemmy_alpha.out 2>&1 &
|
||||||
LEMMY_SETUP__SITE_NAME=lemmy-alpha \
|
|
||||||
target/lemmy_server >/dev/null 2>&1 &
|
|
||||||
|
|
||||||
echo "start beta"
|
echo "start beta"
|
||||||
LEMMY_HOSTNAME=lemmy-beta:8551 \
|
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_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_beta" \
|
||||||
LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon \
|
target/lemmy_server >/tmp/lemmy_beta.out 2>&1 &
|
||||||
LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta \
|
|
||||||
LEMMY_SETUP__SITE_NAME=lemmy-beta \
|
|
||||||
target/lemmy_server >/dev/null 2>&1 &
|
|
||||||
|
|
||||||
echo "start gamma"
|
echo "start gamma"
|
||||||
LEMMY_HOSTNAME=lemmy-gamma:8561 \
|
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_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_gamma" \
|
||||||
LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon \
|
target/lemmy_server >/tmp/lemmy_gamma.out 2>&1 &
|
||||||
LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma \
|
|
||||||
LEMMY_SETUP__SITE_NAME=lemmy-gamma \
|
|
||||||
target/lemmy_server >/dev/null 2>&1 &
|
|
||||||
|
|
||||||
echo "start delta"
|
echo "start delta"
|
||||||
# An instance with only an allowlist for beta
|
# An instance with only an allowlist for beta
|
||||||
LEMMY_HOSTNAME=lemmy-delta:8571 \
|
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_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_delta" \
|
||||||
LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta \
|
target/lemmy_server >/tmp/lemmy_delta.out 2>&1 &
|
||||||
LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta \
|
|
||||||
LEMMY_SETUP__SITE_NAME=lemmy-delta \
|
|
||||||
target/lemmy_server >/dev/null 2>&1 &
|
|
||||||
|
|
||||||
echo "start epsilon"
|
echo "start epsilon"
|
||||||
# An instance who has a blocklist, with lemmy-alpha blocked
|
# An instance who has a blocklist, with lemmy-alpha blocked
|
||||||
LEMMY_HOSTNAME=lemmy-epsilon:8581 \
|
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_DATABASE_URL="${LEMMY_DATABASE_URL}/lemmy_epsilon" \
|
||||||
LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha \
|
target/lemmy_server >/tmp/lemmy_epsilon.out 2>&1 &
|
||||||
LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon \
|
|
||||||
LEMMY_SETUP__SITE_NAME=lemmy-epsilon \
|
|
||||||
target/lemmy_server >/dev/null 2>&1 &
|
|
||||||
|
|
||||||
echo "wait for all instances to start"
|
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
|
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
|
export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432
|
||||||
|
|
||||||
pushd ..
|
pushd ..
|
||||||
cargo +1.47.0 build
|
cargo build
|
||||||
rm target/lemmy_server || true
|
rm target/lemmy_server || true
|
||||||
cp target/debug/lemmy_server target/lemmy_server
|
cp target/debug/lemmy_server target/lemmy_server
|
||||||
./api_tests/prepare-drone-federation-test.sh
|
./api_tests/prepare-drone-federation-test.sh
|
||||||
|
|
|
@ -66,9 +66,10 @@
|
||||||
# https://join.lemmy.ml/docs/en/federation/administration.html#instance-allowlist-and-blocklist
|
# https://join.lemmy.ml/docs/en/federation/administration.html#instance-allowlist-and-blocklist
|
||||||
#
|
#
|
||||||
# comma separated list of instances with which federation is allowed
|
# 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
|
# comma separated list of instances which are blocked from federating
|
||||||
blocked_instances: ""
|
# blocked_instances: []
|
||||||
}
|
}
|
||||||
captcha: {
|
captcha: {
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "lemmy_api"
|
name = "lemmy_api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -17,7 +16,7 @@ lemmy_db_schema = { path = "../db_schema" }
|
||||||
lemmy_db_views = { path = "../db_views" }
|
lemmy_db_views = { path = "../db_views" }
|
||||||
lemmy_db_views_moderator = { path = "../db_views_moderator" }
|
lemmy_db_views_moderator = { path = "../db_views_moderator" }
|
||||||
lemmy_db_views_actor = { path = "../db_views_actor" }
|
lemmy_db_views_actor = { path = "../db_views_actor" }
|
||||||
lemmy_structs = { path = "../structs" }
|
lemmy_api_structs = { path = "../api_structs" }
|
||||||
lemmy_websocket = { path = "../websocket" }
|
lemmy_websocket = { path = "../websocket" }
|
||||||
diesel = "1.4.5"
|
diesel = "1.4.5"
|
||||||
bcrypt = "0.9.0"
|
bcrypt = "0.9.0"
|
||||||
|
@ -33,7 +32,7 @@ rand = "0.8.3"
|
||||||
strum = "0.20.0"
|
strum = "0.20.0"
|
||||||
strum_macros = "0.20.1"
|
strum_macros = "0.20.1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
url = { version = "2.2.0", features = ["serde"] }
|
url = { version = "2.2.1", features = ["serde"] }
|
||||||
openssl = "0.10.32"
|
openssl = "0.10.32"
|
||||||
http = "0.2.3"
|
http = "0.2.3"
|
||||||
http-signature-normalization-actix = { version = "0.4.1", default-features = false, features = ["sha-2"] }
|
http-signature-normalization-actix = { version = "0.4.1", default-features = false, features = ["sha-2"] }
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
Perform,
|
Perform,
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
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_apub::{generate_apub_endpoint, ApubLikeableType, ApubObjectType, EndpointType};
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
source::comment::Comment_,
|
source::comment::Comment_,
|
||||||
|
@ -24,7 +25,6 @@ use lemmy_db_views::{
|
||||||
comment_report_view::{CommentReportQueryBuilder, CommentReportView},
|
comment_report_view::{CommentReportQueryBuilder, CommentReportView},
|
||||||
comment_view::{CommentQueryBuilder, CommentView},
|
comment_view::{CommentQueryBuilder, CommentView},
|
||||||
};
|
};
|
||||||
use lemmy_structs::{blocking, comment::*, send_local_notifs};
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
utils::{remove_slurs, scrape_text_for_mentions},
|
utils::{remove_slurs, scrape_text_for_mentions},
|
||||||
ApiError,
|
ApiError,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
check_community_ban,
|
check_community_ban,
|
||||||
check_optional_url,
|
|
||||||
get_user_from_jwt,
|
get_user_from_jwt,
|
||||||
get_user_from_jwt_opt,
|
get_user_from_jwt_opt,
|
||||||
is_admin,
|
is_admin,
|
||||||
|
@ -9,6 +8,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::{blocking, community::*};
|
||||||
use lemmy_apub::{
|
use lemmy_apub::{
|
||||||
generate_apub_endpoint,
|
generate_apub_endpoint,
|
||||||
generate_followers_url,
|
generate_followers_url,
|
||||||
|
@ -18,7 +18,7 @@ use lemmy_apub::{
|
||||||
EndpointType,
|
EndpointType,
|
||||||
};
|
};
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
diesel_option_overwrite,
|
diesel_option_overwrite_to_url,
|
||||||
source::{
|
source::{
|
||||||
comment::Comment_,
|
comment::Comment_,
|
||||||
community::{CommunityModerator_, Community_},
|
community::{CommunityModerator_, Community_},
|
||||||
|
@ -43,7 +43,6 @@ use lemmy_db_views_actor::{
|
||||||
community_view::{CommunityQueryBuilder, CommunityView},
|
community_view::{CommunityQueryBuilder, CommunityView},
|
||||||
user_view::UserViewSafe,
|
user_view::UserViewSafe,
|
||||||
};
|
};
|
||||||
use lemmy_structs::{blocking, community::*};
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
apub::generate_actor_keypair,
|
apub::generate_actor_keypair,
|
||||||
location_info,
|
location_info,
|
||||||
|
@ -155,11 +154,8 @@ impl Perform for CreateCommunity {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure the icon and banners are urls
|
// Check to make sure the icon and banners are urls
|
||||||
let icon = diesel_option_overwrite(&data.icon);
|
let icon = diesel_option_overwrite_to_url(&data.icon)?;
|
||||||
let banner = diesel_option_overwrite(&data.banner);
|
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||||
|
|
||||||
check_optional_url(&icon)?;
|
|
||||||
check_optional_url(&banner)?;
|
|
||||||
|
|
||||||
// When you create a community, make sure the user becomes a moderator and a follower
|
// When you create a community, make sure the user becomes a moderator and a follower
|
||||||
let keypair = generate_actor_keypair()?;
|
let keypair = generate_actor_keypair()?;
|
||||||
|
@ -260,11 +256,8 @@ impl Perform for EditCommunity {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let icon = diesel_option_overwrite(&data.icon);
|
let icon = diesel_option_overwrite_to_url(&data.icon)?;
|
||||||
let banner = diesel_option_overwrite(&data.banner);
|
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||||
|
|
||||||
check_optional_url(&icon)?;
|
|
||||||
check_optional_url(&banner)?;
|
|
||||||
|
|
||||||
let community_form = CommunityForm {
|
let community_form = CommunityForm {
|
||||||
name: read_community.name,
|
name: read_community.name,
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
use actix_web::{web, web::Data};
|
use actix_web::{web, web::Data};
|
||||||
|
use lemmy_api_structs::{
|
||||||
|
blocking,
|
||||||
|
comment::*,
|
||||||
|
community::*,
|
||||||
|
post::*,
|
||||||
|
site::*,
|
||||||
|
user::*,
|
||||||
|
websocket::*,
|
||||||
|
};
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
source::{
|
source::{
|
||||||
community::{CommunityModerator_, Community_},
|
community::{CommunityModerator_, Community_},
|
||||||
|
@ -18,8 +27,13 @@ use lemmy_db_views_actor::{
|
||||||
community_user_ban_view::CommunityUserBanView,
|
community_user_ban_view::CommunityUserBanView,
|
||||||
community_view::CommunityView,
|
community_view::CommunityView,
|
||||||
};
|
};
|
||||||
use lemmy_structs::{blocking, comment::*, community::*, post::*, site::*, user::*, websocket::*};
|
use lemmy_utils::{
|
||||||
use lemmy_utils::{claims::Claims, settings::Settings, ApiError, ConnectionId, LemmyError};
|
claims::Claims,
|
||||||
|
settings::structs::Settings,
|
||||||
|
ApiError,
|
||||||
|
ConnectionId,
|
||||||
|
LemmyError,
|
||||||
|
};
|
||||||
use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation};
|
use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{env, process::Command};
|
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(
|
pub(crate) async fn build_federated_instances(
|
||||||
pool: &DbPool,
|
pool: &DbPool,
|
||||||
) -> Result<Option<FederatedInstances>, LemmyError> {
|
) -> Result<Option<FederatedInstances>, LemmyError> {
|
||||||
if Settings::get().federation.enabled {
|
if Settings::get().federation().enabled {
|
||||||
let distinct_communities = blocking(pool, move |conn| {
|
let distinct_communities = blocking(pool, move |conn| {
|
||||||
Community::distinct_federated_communities(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()))
|
.map(|actor_id| Ok(Url::parse(actor_id)?.host_str().unwrap_or("").to_string()))
|
||||||
.collect::<Result<Vec<String>, LemmyError>>()?;
|
.collect::<Result<Vec<String>, LemmyError>>()?;
|
||||||
|
|
||||||
linked.extend_from_slice(&allowed);
|
if let Some(allowed) = allowed.as_ref() {
|
||||||
linked.retain(|a| !blocked.contains(a) && !a.eq("") && !a.eq(&Settings::get().hostname));
|
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
|
// Sort and remove dupes
|
||||||
linked.sort_unstable();
|
linked.sort_unstable();
|
||||||
|
@ -469,6 +479,15 @@ pub(crate) fn espeak_wav_base64(text: &str) -> Result<String, LemmyError> {
|
||||||
Ok(base64)
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{captcha_espeak_wav_base64, get_user_from_jwt};
|
use crate::{captcha_espeak_wav_base64, get_user_from_jwt};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
check_community_ban,
|
check_community_ban,
|
||||||
check_downvotes_enabled,
|
check_downvotes_enabled,
|
||||||
check_optional_url,
|
|
||||||
collect_moderated_communities,
|
collect_moderated_communities,
|
||||||
get_user_from_jwt,
|
get_user_from_jwt,
|
||||||
get_user_from_jwt_opt,
|
get_user_from_jwt_opt,
|
||||||
|
@ -9,6 +8,7 @@ use crate::{
|
||||||
Perform,
|
Perform,
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
|
use lemmy_api_structs::{blocking, post::*};
|
||||||
use lemmy_apub::{generate_apub_endpoint, ApubLikeableType, ApubObjectType, EndpointType};
|
use lemmy_apub::{generate_apub_endpoint, ApubLikeableType, ApubObjectType, EndpointType};
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
source::post::Post_,
|
source::post::Post_,
|
||||||
|
@ -36,7 +36,6 @@ use lemmy_db_views_actor::{
|
||||||
community_moderator_view::CommunityModeratorView,
|
community_moderator_view::CommunityModeratorView,
|
||||||
community_view::CommunityView,
|
community_view::CommunityView,
|
||||||
};
|
};
|
||||||
use lemmy_structs::{blocking, post::*};
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
request::fetch_iframely_and_pictrs_data,
|
request::fetch_iframely_and_pictrs_data,
|
||||||
utils::{check_slurs, check_slurs_opt, is_valid_post_title},
|
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_community_ban(user.id, data.community_id, context.pool()).await?;
|
||||||
|
|
||||||
check_optional_url(&Some(data.url.to_owned()))?;
|
|
||||||
|
|
||||||
// Fetch Iframely and pictrs cached image
|
// Fetch Iframely and pictrs cached image
|
||||||
|
let data_url = data.url.as_ref();
|
||||||
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
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 {
|
let post_form = PostForm {
|
||||||
name: data.name.trim().to_owned(),
|
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(),
|
body: data.body.to_owned(),
|
||||||
community_id: data.community_id,
|
community_id: data.community_id,
|
||||||
creator_id: user.id,
|
creator_id: user.id,
|
||||||
|
@ -93,7 +91,7 @@ impl Perform for CreatePost {
|
||||||
embed_title: iframely_title,
|
embed_title: iframely_title,
|
||||||
embed_description: iframely_description,
|
embed_description: iframely_description,
|
||||||
embed_html: iframely_html,
|
embed_html: iframely_html,
|
||||||
thumbnail_url: pictrs_thumbnail,
|
thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
|
||||||
ap_id: None,
|
ap_id: None,
|
||||||
local: true,
|
local: true,
|
||||||
published: None,
|
published: None,
|
||||||
|
@ -385,12 +383,13 @@ impl Perform for EditPost {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch Iframely and Pictrs cached image
|
// Fetch Iframely and Pictrs cached image
|
||||||
|
let data_url = data.url.as_ref();
|
||||||
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
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 {
|
let post_form = PostForm {
|
||||||
name: data.name.trim().to_owned(),
|
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(),
|
body: data.body.to_owned(),
|
||||||
nsfw: data.nsfw,
|
nsfw: data.nsfw,
|
||||||
creator_id: orig_post.creator_id.to_owned(),
|
creator_id: orig_post.creator_id.to_owned(),
|
||||||
|
@ -403,7 +402,7 @@ impl Perform for EditPost {
|
||||||
embed_title: iframely_title,
|
embed_title: iframely_title,
|
||||||
embed_description: iframely_description,
|
embed_description: iframely_description,
|
||||||
embed_html: iframely_html,
|
embed_html: iframely_html,
|
||||||
thumbnail_url: pictrs_thumbnail,
|
thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
|
||||||
ap_id: Some(orig_post.ap_id),
|
ap_id: Some(orig_post.ap_id),
|
||||||
local: orig_post.local,
|
local: orig_post.local,
|
||||||
published: None,
|
published: None,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::Perform;
|
use crate::Perform;
|
||||||
use actix_web::{error::ErrorBadRequest, *};
|
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_utils::rate_limit::RateLimit;
|
||||||
use lemmy_websocket::{routes::chat_route, LemmyContext};
|
use lemmy_websocket::{routes::chat_route, LemmyContext};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
|
@ -9,8 +9,15 @@ use crate::{
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::{blocking, site::*, user::Register};
|
||||||
use lemmy_apub::fetcher::search::search_by_apub_id;
|
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::{
|
use lemmy_db_schema::{
|
||||||
naive_now,
|
naive_now,
|
||||||
source::{
|
source::{
|
||||||
|
@ -38,10 +45,9 @@ use lemmy_db_views_moderator::{
|
||||||
mod_remove_post_view::ModRemovePostView,
|
mod_remove_post_view::ModRemovePostView,
|
||||||
mod_sticky_post_view::ModStickyPostView,
|
mod_sticky_post_view::ModStickyPostView,
|
||||||
};
|
};
|
||||||
use lemmy_structs::{blocking, site::*, user::Register};
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
settings::Settings,
|
settings::structs::Settings,
|
||||||
utils::{check_slurs, check_slurs_opt},
|
utils::{check_slurs, check_slurs_opt},
|
||||||
version,
|
version,
|
||||||
ApiError,
|
ApiError,
|
||||||
|
@ -157,8 +163,8 @@ impl Perform for CreateSite {
|
||||||
let site_form = SiteForm {
|
let site_form = SiteForm {
|
||||||
name: data.name.to_owned(),
|
name: data.name.to_owned(),
|
||||||
description: data.description.to_owned(),
|
description: data.description.to_owned(),
|
||||||
icon: Some(data.icon.to_owned()),
|
icon: Some(data.icon.to_owned().map(|url| url.into())),
|
||||||
banner: Some(data.banner.to_owned()),
|
banner: Some(data.banner.to_owned().map(|url| url.into())),
|
||||||
creator_id: user.id,
|
creator_id: user.id,
|
||||||
enable_downvotes: data.enable_downvotes,
|
enable_downvotes: data.enable_downvotes,
|
||||||
open_registration: data.open_registration,
|
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 found_site = blocking(context.pool(), move |conn| Site::read_simple(conn)).await??;
|
||||||
|
|
||||||
let icon = diesel_option_overwrite(&data.icon);
|
let icon = diesel_option_overwrite_to_url(&data.icon)?;
|
||||||
let banner = diesel_option_overwrite(&data.banner);
|
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||||
|
|
||||||
let site_form = SiteForm {
|
let site_form = SiteForm {
|
||||||
name: data.name.to_owned(),
|
name: data.name.to_owned(),
|
||||||
|
@ -245,7 +251,7 @@ impl Perform for GetSite {
|
||||||
Ok(site_view) => Some(site_view),
|
Ok(site_view) => Some(site_view),
|
||||||
// If the site isn't created yet, check the setup
|
// If the site isn't created yet, check the setup
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
if let Some(setup) = Settings::get().setup.as_ref() {
|
if let Some(setup) = Settings::get().setup().as_ref() {
|
||||||
let register = Register {
|
let register = Register {
|
||||||
username: setup.admin_username.to_owned(),
|
username: setup.admin_username.to_owned(),
|
||||||
email: setup.admin_email.to_owned(),
|
email: setup.admin_email.to_owned(),
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
captcha_espeak_wav_base64,
|
captcha_espeak_wav_base64,
|
||||||
check_optional_url,
|
|
||||||
collect_moderated_communities,
|
collect_moderated_communities,
|
||||||
get_user_from_jwt,
|
get_user_from_jwt,
|
||||||
get_user_from_jwt_opt,
|
get_user_from_jwt_opt,
|
||||||
is_admin,
|
is_admin,
|
||||||
|
password_length_check,
|
||||||
Perform,
|
Perform,
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
|
@ -12,6 +12,7 @@ use anyhow::Context;
|
||||||
use bcrypt::verify;
|
use bcrypt::verify;
|
||||||
use captcha::{gen, Difficulty};
|
use captcha::{gen, Difficulty};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
|
use lemmy_api_structs::{blocking, send_email_to_user, user::*};
|
||||||
use lemmy_apub::{
|
use lemmy_apub::{
|
||||||
generate_apub_endpoint,
|
generate_apub_endpoint,
|
||||||
generate_followers_url,
|
generate_followers_url,
|
||||||
|
@ -22,6 +23,7 @@ use lemmy_apub::{
|
||||||
};
|
};
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
diesel_option_overwrite,
|
diesel_option_overwrite,
|
||||||
|
diesel_option_overwrite_to_url,
|
||||||
source::{
|
source::{
|
||||||
comment::Comment_,
|
comment::Comment_,
|
||||||
community::Community_,
|
community::Community_,
|
||||||
|
@ -65,13 +67,12 @@ use lemmy_db_views_actor::{
|
||||||
user_mention_view::{UserMentionQueryBuilder, UserMentionView},
|
user_mention_view::{UserMentionQueryBuilder, UserMentionView},
|
||||||
user_view::UserViewSafe,
|
user_view::UserViewSafe,
|
||||||
};
|
};
|
||||||
use lemmy_structs::{blocking, send_email_to_user, user::*};
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
apub::generate_actor_keypair,
|
apub::generate_actor_keypair,
|
||||||
claims::Claims,
|
claims::Claims,
|
||||||
email::send_email,
|
email::send_email,
|
||||||
location_info,
|
location_info,
|
||||||
settings::Settings,
|
settings::structs::Settings,
|
||||||
utils::{
|
utils::{
|
||||||
check_slurs,
|
check_slurs,
|
||||||
generate_random_string,
|
generate_random_string,
|
||||||
|
@ -121,7 +122,7 @@ impl Perform for Login {
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(LoginResponse {
|
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
|
password_length_check(&data.password)?;
|
||||||
if data.password.len() > 60 {
|
|
||||||
return Err(ApiError::err("invalid_password").into());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure passwords match
|
// Make sure passwords match
|
||||||
if data.password != data.password_verify {
|
if data.password != data.password_verify {
|
||||||
|
@ -161,7 +159,7 @@ impl Perform for Register {
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// If its not the admin, check the captcha
|
// 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
|
let check = context
|
||||||
.chat_server()
|
.chat_server()
|
||||||
.send(CheckCaptcha {
|
.send(CheckCaptcha {
|
||||||
|
@ -302,7 +300,7 @@ impl Perform for Register {
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(LoginResponse {
|
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>,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_id: Option<ConnectionId>,
|
_websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<Self::Response, LemmyError> {
|
) -> Result<Self::Response, LemmyError> {
|
||||||
let captcha_settings = Settings::get().captcha;
|
let captcha_settings = Settings::get().captcha();
|
||||||
|
|
||||||
if !captcha_settings.enabled {
|
if !captcha_settings.enabled {
|
||||||
return Ok(GetCaptchaResponse { ok: None });
|
return Ok(GetCaptchaResponse { ok: None });
|
||||||
|
@ -366,17 +364,13 @@ impl Perform for SaveUserSettings {
|
||||||
let data: &SaveUserSettings = &self;
|
let data: &SaveUserSettings = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let avatar = diesel_option_overwrite(&data.avatar);
|
let avatar = diesel_option_overwrite_to_url(&data.avatar)?;
|
||||||
let banner = diesel_option_overwrite(&data.banner);
|
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||||
let email = diesel_option_overwrite(&data.email);
|
let email = diesel_option_overwrite(&data.email);
|
||||||
let bio = diesel_option_overwrite(&data.bio);
|
let bio = diesel_option_overwrite(&data.bio);
|
||||||
let preferred_username = diesel_option_overwrite(&data.preferred_username);
|
let preferred_username = diesel_option_overwrite(&data.preferred_username);
|
||||||
let matrix_user_id = diesel_option_overwrite(&data.matrix_user_id);
|
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 let Some(Some(bio)) = &bio {
|
||||||
if bio.chars().count() > 300 {
|
if bio.chars().count() > 300 {
|
||||||
return Err(ApiError::err("bio_length_overflow").into());
|
return Err(ApiError::err("bio_length_overflow").into());
|
||||||
|
@ -394,6 +388,8 @@ impl Perform for SaveUserSettings {
|
||||||
Some(new_password) => {
|
Some(new_password) => {
|
||||||
match &data.new_password_verify {
|
match &data.new_password_verify {
|
||||||
Some(new_password_verify) => {
|
Some(new_password_verify) => {
|
||||||
|
password_length_check(&new_password)?;
|
||||||
|
|
||||||
// Make sure passwords match
|
// Make sure passwords match
|
||||||
if new_password != new_password_verify {
|
if new_password != new_password_verify {
|
||||||
return Err(ApiError::err("passwords_dont_match").into());
|
return Err(ApiError::err("passwords_dont_match").into());
|
||||||
|
@ -475,7 +471,7 @@ impl Perform for SaveUserSettings {
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(LoginResponse {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
password_length_check(&data.password)?;
|
||||||
|
|
||||||
// Make sure passwords match
|
// Make sure passwords match
|
||||||
if data.password != data.password_verify {
|
if data.password != data.password_verify {
|
||||||
return Err(ApiError::err("passwords_dont_match").into());
|
return Err(ApiError::err("passwords_dont_match").into());
|
||||||
|
@ -1011,7 +1009,7 @@ impl Perform for PasswordChange {
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(LoginResponse {
|
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 crate::{get_user_from_jwt, Perform};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use lemmy_structs::websocket::*;
|
use lemmy_api_structs::websocket::*;
|
||||||
use lemmy_utils::{ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
messages::{JoinCommunityRoom, JoinModRoom, JoinPostRoom, JoinUserRoom},
|
messages::{JoinCommunityRoom, JoinModRoom, JoinPostRoom, JoinUserRoom},
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
[package]
|
[package]
|
||||||
name = "lemmy_structs"
|
name = "lemmy_api_structs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "lemmy_structs"
|
name = "lemmy_api_structs"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
|
@ -22,4 +21,4 @@ diesel = "1.4.5"
|
||||||
actix-web = "3.3.2"
|
actix-web = "3.3.2"
|
||||||
chrono = { version = "0.4.19", features = ["serde"] }
|
chrono = { version = "0.4.19", features = ["serde"] }
|
||||||
serde_json = { version = "1.0.61", features = ["preserve_order"] }
|
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 description: Option<String>,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<String>,
|
||||||
pub category_id: i32,
|
|
||||||
pub nsfw: bool,
|
pub nsfw: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
@ -88,7 +87,6 @@ pub struct EditCommunity {
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<String>,
|
||||||
pub category_id: i32,
|
|
||||||
pub nsfw: bool,
|
pub nsfw: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ use lemmy_db_schema::source::{
|
||||||
user::User_,
|
user::User_,
|
||||||
user_mention::{UserMention, UserMentionForm},
|
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 log::error;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use url::Url;
|
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!(
|
let subject = &format!(
|
||||||
"{} - {} {}",
|
"{} - {} {}",
|
||||||
subject_text,
|
subject_text,
|
||||||
Settings::get().hostname,
|
Settings::get().hostname(),
|
||||||
user.name,
|
user.name,
|
||||||
);
|
);
|
||||||
let html = &format!(
|
let html = &format!(
|
|
@ -8,11 +8,12 @@ use lemmy_db_views_actor::{
|
||||||
community_view::CommunityView,
|
community_view::CommunityView,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct CreatePost {
|
pub struct CreatePost {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub url: Option<String>,
|
pub url: Option<Url>,
|
||||||
pub body: Option<String>,
|
pub body: Option<String>,
|
||||||
pub nsfw: bool,
|
pub nsfw: bool,
|
||||||
pub community_id: i32,
|
pub community_id: i32,
|
||||||
|
@ -66,7 +67,7 @@ pub struct CreatePostLike {
|
||||||
pub struct EditPost {
|
pub struct EditPost {
|
||||||
pub post_id: i32,
|
pub post_id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub url: Option<String>,
|
pub url: Option<Url>,
|
||||||
pub body: Option<String>,
|
pub body: Option<String>,
|
||||||
pub nsfw: bool,
|
pub nsfw: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
|
@ -13,6 +13,7 @@ use lemmy_db_views_moderator::{
|
||||||
mod_sticky_post_view::ModStickyPostView,
|
mod_sticky_post_view::ModStickyPostView,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct Search {
|
pub struct Search {
|
||||||
|
@ -60,8 +61,8 @@ pub struct GetModlogResponse {
|
||||||
pub struct CreateSite {
|
pub struct CreateSite {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<Url>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<Url>,
|
||||||
pub enable_downvotes: bool,
|
pub enable_downvotes: bool,
|
||||||
pub open_registration: bool,
|
pub open_registration: bool,
|
||||||
pub enable_nsfw: bool,
|
pub enable_nsfw: bool,
|
||||||
|
@ -126,6 +127,6 @@ pub struct SaveSiteConfig {
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct FederatedInstances {
|
pub struct FederatedInstances {
|
||||||
pub linked: Vec<String>,
|
pub linked: Vec<String>,
|
||||||
pub allowed: Vec<String>,
|
pub allowed: Option<Vec<String>>,
|
||||||
pub blocked: Vec<String>,
|
pub blocked: Option<Vec<String>>,
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "lemmy_apub"
|
name = "lemmy_apub"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -15,7 +14,7 @@ lemmy_db_queries = { path = "../db_queries" }
|
||||||
lemmy_db_schema = { path = "../db_schema" }
|
lemmy_db_schema = { path = "../db_schema" }
|
||||||
lemmy_db_views = { path = "../db_views" }
|
lemmy_db_views = { path = "../db_views" }
|
||||||
lemmy_db_views_actor = { path = "../db_views_actor" }
|
lemmy_db_views_actor = { path = "../db_views_actor" }
|
||||||
lemmy_structs = { path = "../structs" }
|
lemmy_api_structs = { path = "../api_structs" }
|
||||||
lemmy_websocket = { path = "../websocket" }
|
lemmy_websocket = { path = "../websocket" }
|
||||||
diesel = "1.4.5"
|
diesel = "1.4.5"
|
||||||
activitystreams = "0.7.0-alpha.10"
|
activitystreams = "0.7.0-alpha.10"
|
||||||
|
@ -33,7 +32,7 @@ rand = "0.8.3"
|
||||||
strum = "0.20.0"
|
strum = "0.20.0"
|
||||||
strum_macros = "0.20.1"
|
strum_macros = "0.20.1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
url = { version = "2.2.0", features = ["serde"] }
|
url = { version = "2.2.1", features = ["serde"] }
|
||||||
percent-encoding = "2.1.0"
|
percent-encoding = "2.1.0"
|
||||||
openssl = "0.10.32"
|
openssl = "0.10.32"
|
||||||
http = "0.2.3"
|
http = "0.2.3"
|
||||||
|
|
|
@ -4,13 +4,13 @@ use activitystreams::{
|
||||||
base::ExtendsExt,
|
base::ExtendsExt,
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
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_queries::{source::comment::Comment_, Crud, Likeable};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
comment::{Comment, CommentLike, CommentLikeForm},
|
comment::{Comment, CommentLike, CommentLikeForm},
|
||||||
post::Post,
|
post::Post,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::comment_view::CommentView;
|
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_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::activities::receive::get_actor_as_user;
|
use crate::activities::receive::get_actor_as_user;
|
||||||
use activitystreams::activity::{Dislike, Like};
|
use activitystreams::activity::{Dislike, Like};
|
||||||
|
use lemmy_api_structs::{blocking, comment::CommentResponse};
|
||||||
use lemmy_db_queries::{source::comment::Comment_, Likeable};
|
use lemmy_db_queries::{source::comment::Comment_, Likeable};
|
||||||
use lemmy_db_schema::source::comment::{Comment, CommentLike};
|
use lemmy_db_schema::source::comment::{Comment, CommentLike};
|
||||||
use lemmy_db_views::comment_view::CommentView;
|
use lemmy_db_views::comment_view::CommentView;
|
||||||
use lemmy_structs::{blocking, comment::CommentResponse};
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ use activitystreams::{
|
||||||
base::{AnyBase, ExtendsExt},
|
base::{AnyBase, ExtendsExt},
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::{blocking, community::CommunityResponse};
|
||||||
use lemmy_db_queries::{source::community::Community_, ApubObject};
|
use lemmy_db_queries::{source::community::Community_, ApubObject};
|
||||||
use lemmy_db_schema::source::community::Community;
|
use lemmy_db_schema::source::community::Community;
|
||||||
use lemmy_db_views_actor::community_view::CommunityView;
|
use lemmy_db_views_actor::community_view::CommunityView;
|
||||||
use lemmy_structs::{blocking, community::CommunityResponse};
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
|
@ -4,10 +4,10 @@ use activitystreams::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::{blocking, post::PostResponse};
|
||||||
use lemmy_db_queries::{source::post::Post_, Likeable};
|
use lemmy_db_queries::{source::post::Post_, Likeable};
|
||||||
use lemmy_db_schema::source::post::{Post, PostLike, PostLikeForm};
|
use lemmy_db_schema::source::post::{Post, PostLike, PostLikeForm};
|
||||||
use lemmy_db_views::post_view::PostView;
|
use lemmy_db_views::post_view::PostView;
|
||||||
use lemmy_structs::{blocking, post::PostResponse};
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::activities::receive::get_actor_as_user;
|
use crate::activities::receive::get_actor_as_user;
|
||||||
use activitystreams::activity::{Dislike, Like};
|
use activitystreams::activity::{Dislike, Like};
|
||||||
|
use lemmy_api_structs::{blocking, post::PostResponse};
|
||||||
use lemmy_db_queries::{source::post::Post_, Likeable};
|
use lemmy_db_queries::{source::post::Post_, Likeable};
|
||||||
use lemmy_db_schema::source::post::{Post, PostLike};
|
use lemmy_db_schema::source::post::{Post, PostLike};
|
||||||
use lemmy_db_views::post_view::PostView;
|
use lemmy_db_views::post_view::PostView;
|
||||||
use lemmy_structs::{blocking, post::PostResponse};
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@ use activitystreams::{
|
||||||
public,
|
public,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
|
use lemmy_api_structs::{blocking, user::PrivateMessageResponse};
|
||||||
use lemmy_db_queries::source::private_message::PrivateMessage_;
|
use lemmy_db_queries::source::private_message::PrivateMessage_;
|
||||||
use lemmy_db_schema::source::private_message::PrivateMessage;
|
use lemmy_db_schema::source::private_message::PrivateMessage;
|
||||||
use lemmy_db_views::private_message_view::PrivateMessageView;
|
use lemmy_db_views::private_message_view::PrivateMessageView;
|
||||||
use lemmy_structs::{blocking, user::PrivateMessageResponse};
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
|
@ -26,12 +26,12 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use lemmy_api_structs::{blocking, WebFingerResponse};
|
||||||
use lemmy_db_queries::{Crud, DbPool};
|
use lemmy_db_queries::{Crud, DbPool};
|
||||||
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post, user::User_};
|
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post, user::User_};
|
||||||
use lemmy_structs::{blocking, WebFingerResponse};
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
request::{retry, RecvError},
|
request::{retry, RecvError},
|
||||||
settings::Settings,
|
settings::structs::Settings,
|
||||||
utils::{scrape_text_for_mentions, MentionData},
|
utils::{scrape_text_for_mentions, MentionData},
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,10 +23,10 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::DbPool;
|
use lemmy_db_queries::DbPool;
|
||||||
use lemmy_db_schema::source::community::Community;
|
use lemmy_db_schema::source::community::Community;
|
||||||
use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
|
use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use lemmy_utils::settings::Settings;
|
use lemmy_utils::settings::structs::Settings;
|
||||||
use url::{ParseError, Url};
|
use url::{ParseError, Url};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,9 @@ use activitystreams::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
public,
|
public,
|
||||||
};
|
};
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::Crud;
|
use lemmy_db_queries::Crud;
|
||||||
use lemmy_db_schema::source::{community::Community, post::Post, user::User_};
|
use lemmy_db_schema::source::{community::Community, post::Post, user::User_};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,9 @@ use activitystreams::{
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::Crud;
|
use lemmy_db_queries::Crud;
|
||||||
use lemmy_db_schema::source::{private_message::PrivateMessage, user::User_};
|
use lemmy_db_schema::source::{private_message::PrivateMessage, user::User_};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,12 @@ use activitystreams::{
|
||||||
base::{AnyBase, BaseExt, ExtendsExt},
|
base::{AnyBase, BaseExt, ExtendsExt},
|
||||||
object::ObjectExt,
|
object::ObjectExt,
|
||||||
};
|
};
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{ApubObject, DbPool, Followable};
|
use lemmy_db_queries::{ApubObject, DbPool, Followable};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||||
user::User_,
|
user::User_,
|
||||||
};
|
};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
|
@ -22,7 +22,7 @@ use background_jobs::{
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use lemmy_db_queries::DbPool;
|
use lemmy_db_queries::DbPool;
|
||||||
use lemmy_db_schema::source::{community::Community, user::User_};
|
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 lemmy_websocket::LemmyContext;
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
|
@ -88,7 +88,7 @@ where
|
||||||
.await?
|
.await?
|
||||||
.iter()
|
.iter()
|
||||||
.unique()
|
.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())
|
.filter(|inbox| check_is_apub_id_valid(inbox).is_ok())
|
||||||
.map(|inbox| inbox.to_owned())
|
.map(|inbox| inbox.to_owned())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -215,7 +215,7 @@ where
|
||||||
Kind: Serialize,
|
Kind: Serialize,
|
||||||
<T as Extends<Kind>>::Error: From<serde_json::Error> + Send + Sync + 'static,
|
<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(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ where
|
||||||
let hostname = Settings::get().get_hostname_without_port()?;
|
let hostname = Settings::get().get_hostname_without_port()?;
|
||||||
let inboxes: Vec<&Url> = inboxes
|
let inboxes: Vec<&Url> = inboxes
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|i| i.domain().unwrap() != hostname)
|
.filter(|i| i.domain().expect("valid inbox url") != hostname)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let activity = activity.into_any_base()?;
|
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!(
|
let context_ext = AnyBase::from_arbitrary_json(json!(
|
||||||
{
|
{
|
||||||
"sc": "http://schema.org#",
|
"sc": "http://schema.org#",
|
||||||
"category": "sc:category",
|
|
||||||
"sensitive": "as:sensitive",
|
"sensitive": "as:sensitive",
|
||||||
"stickied": "as:stickied",
|
"stickied": "as:stickied",
|
||||||
"comments_enabled": {
|
"comments_enabled": {
|
||||||
|
|
|
@ -16,9 +16,9 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{source::community::Community_, ApubObject, Joinable};
|
use lemmy_db_queries::{source::community::Community_, ApubObject, Joinable};
|
||||||
use lemmy_db_schema::source::community::{Community, CommunityModerator, CommunityModeratorForm};
|
use lemmy_db_schema::source::community::{Community, CommunityModerator, CommunityModeratorForm};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::{fetcher::fetch::fetch_remote_object, objects::FromApub, NoteExt, PageExt};
|
use crate::{fetcher::fetch::fetch_remote_object, objects::FromApub, NoteExt, PageExt};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{ApubObject, Crud};
|
use lemmy_db_queries::{ApubObject, Crud};
|
||||||
use lemmy_db_schema::source::{comment::Comment, post::Post};
|
use lemmy_db_schema::source::{comment::Comment, post::Post};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
|
@ -15,6 +15,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use activitystreams::base::BaseExt;
|
use activitystreams::base::BaseExt;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
|
use lemmy_api_structs::{blocking, site::SearchResponse};
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
source::{
|
source::{
|
||||||
comment::Comment_,
|
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::{comment_view::CommentView, post_view::PostView};
|
||||||
use lemmy_db_views_actor::{community_view::CommunityView, user_view::UserViewSafe};
|
use lemmy_db_views_actor::{community_view::CommunityView, user_view::UserViewSafe};
|
||||||
use lemmy_structs::{blocking, site::SearchResponse};
|
use lemmy_utils::{settings::structs::Settings, LemmyError};
|
||||||
use lemmy_utils::{settings::Settings, LemmyError};
|
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
|
@ -5,9 +5,9 @@ use crate::{
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{source::user::User, ApubObject};
|
use lemmy_db_queries::{source::user::User, ApubObject};
|
||||||
use lemmy_db_schema::source::user::User_;
|
use lemmy_db_schema::source::user::User_;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
|
@ -4,9 +4,9 @@ use crate::{
|
||||||
};
|
};
|
||||||
use actix_web::{body::Body, web, web::Path, HttpResponse};
|
use actix_web::{body::Body, web, web::Path, HttpResponse};
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::Crud;
|
use lemmy_db_queries::Crud;
|
||||||
use lemmy_db_schema::source::comment::Comment;
|
use lemmy_db_schema::source::comment::Comment;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
|
@ -9,10 +9,10 @@ use activitystreams::{
|
||||||
collection::{CollectionExt, OrderedCollection, UnorderedCollection},
|
collection::{CollectionExt, OrderedCollection, UnorderedCollection},
|
||||||
};
|
};
|
||||||
use actix_web::{body::Body, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::source::{activity::Activity_, community::Community_};
|
use lemmy_db_queries::source::{activity::Activity_, community::Community_};
|
||||||
use lemmy_db_schema::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_db_views_actor::community_follower_view::CommunityFollowerView;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
use crate::APUB_JSON_CONTENT_TYPE;
|
use crate::APUB_JSON_CONTENT_TYPE;
|
||||||
use actix_web::{body::Body, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::source::activity::Activity_;
|
use lemmy_db_queries::source::activity::Activity_;
|
||||||
use lemmy_db_schema::source::activity::Activity;
|
use lemmy_db_schema::source::activity::Activity;
|
||||||
use lemmy_structs::blocking;
|
use lemmy_utils::{settings::structs::Settings, LemmyError};
|
||||||
use lemmy_utils::{settings::Settings, LemmyError};
|
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
pub mod comment;
|
pub mod comment;
|
||||||
pub mod community;
|
pub mod community;
|
||||||
|
@ -46,12 +47,13 @@ pub async fn get_activity(
|
||||||
context: web::Data<LemmyContext>,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse<Body>, LemmyError> {
|
) -> Result<HttpResponse<Body>, LemmyError> {
|
||||||
let settings = Settings::get();
|
let settings = Settings::get();
|
||||||
let activity_id = format!(
|
let activity_id = Url::parse(&format!(
|
||||||
"{}/activities/{}/{}",
|
"{}/activities/{}/{}",
|
||||||
settings.get_protocol_and_hostname(),
|
settings.get_protocol_and_hostname(),
|
||||||
info.type_,
|
info.type_,
|
||||||
info.id
|
info.id
|
||||||
);
|
))?
|
||||||
|
.into();
|
||||||
let activity = blocking(context.pool(), move |conn| {
|
let activity = blocking(context.pool(), move |conn| {
|
||||||
Activity::read_from_apub_id(&conn, &activity_id)
|
Activity::read_from_apub_id(&conn, &activity_id)
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,9 +4,9 @@ use crate::{
|
||||||
};
|
};
|
||||||
use actix_web::{body::Body, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::Crud;
|
use lemmy_db_queries::Crud;
|
||||||
use lemmy_db_schema::source::post::Post;
|
use lemmy_db_schema::source::post::Post;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
|
@ -9,9 +9,9 @@ use activitystreams::{
|
||||||
collection::{CollectionExt, OrderedCollection},
|
collection::{CollectionExt, OrderedCollection},
|
||||||
};
|
};
|
||||||
use actix_web::{body::Body, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::source::user::User;
|
use lemmy_db_queries::source::user::User;
|
||||||
use lemmy_db_schema::source::user::User_;
|
use lemmy_db_schema::source::user::User_;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
|
@ -26,13 +26,13 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{source::community::Community_, ApubObject, DbPool, Followable};
|
use lemmy_db_queries::{source::community::Community_, ApubObject, DbPool, Followable};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||||
user::User_,
|
user::User_,
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::community_user_ban_view::CommunityUserBanView;
|
use lemmy_db_views_actor::community_user_ban_view::CommunityUserBanView;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
|
@ -12,14 +12,14 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use actix_web::HttpRequest;
|
use actix_web::HttpRequest;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
source::{activity::Activity_, community::Community_},
|
source::{activity::Activity_, community::Community_},
|
||||||
ApubObject,
|
ApubObject,
|
||||||
DbPool,
|
DbPool,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::source::{activity::Activity, community::Community, user::User_};
|
use lemmy_db_schema::source::{activity::Activity, community::Community, user::User_};
|
||||||
use lemmy_structs::blocking;
|
use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
|
||||||
use lemmy_utils::{location_info, settings::Settings, LemmyError};
|
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -45,7 +45,7 @@ pub(crate) async fn is_activity_already_known(
|
||||||
pool: &DbPool,
|
pool: &DbPool,
|
||||||
activity_id: &Url,
|
activity_id: &Url,
|
||||||
) -> Result<bool, LemmyError> {
|
) -> Result<bool, LemmyError> {
|
||||||
let activity_id = activity_id.to_string();
|
let activity_id = activity_id.to_owned().into();
|
||||||
let existing = blocking(pool, move |conn| {
|
let existing = blocking(pool, move |conn| {
|
||||||
Activity::read_from_apub_id(&conn, &activity_id)
|
Activity::read_from_apub_id(&conn, &activity_id)
|
||||||
})
|
})
|
||||||
|
@ -167,7 +167,7 @@ where
|
||||||
let id = activity.id_unchecked().context(location_info!())?;
|
let id = activity.id_unchecked().context(location_info!())?;
|
||||||
let activity_domain = id.domain().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(
|
return Err(
|
||||||
anyhow!(
|
anyhow!(
|
||||||
"Error: received activity which was sent by local instance: {:?}",
|
"Error: received activity which was sent by local instance: {:?}",
|
||||||
|
|
|
@ -43,9 +43,9 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::Crud;
|
use lemmy_db_queries::Crud;
|
||||||
use lemmy_db_schema::source::site::Site;
|
use lemmy_db_schema::source::site::Site;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use strum_macros::EnumString;
|
use strum_macros::EnumString;
|
||||||
|
@ -120,9 +120,9 @@ pub(in crate::inbox) async fn receive_like_for_community(
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
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) => {
|
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!())?;
|
.context(location_info!())?;
|
||||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||||
PostOrComment::Post(post) => {
|
PostOrComment::Post(post) => {
|
||||||
receive_dislike_post(dislike, post, context, request_counter).await
|
receive_dislike_post(dislike, *post, context, request_counter).await
|
||||||
}
|
}
|
||||||
PostOrComment::Comment(comment) => {
|
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!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
match find_post_or_comment_by_id(context, object).await {
|
match find_post_or_comment_by_id(context, object).await {
|
||||||
Ok(PostOrComment::Post(p)) => receive_delete_post(context, p).await,
|
Ok(PostOrComment::Post(p)) => receive_delete_post(context, *p).await,
|
||||||
Ok(PostOrComment::Comment(c)) => receive_delete_comment(context, c).await,
|
Ok(PostOrComment::Comment(c)) => receive_delete_comment(context, *c).await,
|
||||||
// if we dont have the object, no need to do anything
|
// if we dont have the object, no need to do anything
|
||||||
Err(_) => Ok(()),
|
Err(_) => Ok(()),
|
||||||
}
|
}
|
||||||
|
@ -215,8 +215,8 @@ pub(in crate::inbox) async fn receive_remove_for_community(
|
||||||
remove.id(community_id.domain().context(location_info!())?)?;
|
remove.id(community_id.domain().context(location_info!())?)?;
|
||||||
|
|
||||||
match find_post_or_comment_by_id(context, object).await {
|
match find_post_or_comment_by_id(context, object).await {
|
||||||
Ok(PostOrComment::Post(p)) => receive_remove_post(context, remove, p).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::Comment(c)) => receive_remove_comment(context, remove, *c).await,
|
||||||
// if we dont have the object, no need to do anything
|
// if we dont have the object, no need to do anything
|
||||||
Err(_) => Ok(()),
|
Err(_) => Ok(()),
|
||||||
}
|
}
|
||||||
|
@ -276,8 +276,8 @@ pub(in crate::inbox) async fn receive_undo_delete_for_community(
|
||||||
.single_xsd_any_uri()
|
.single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
match find_post_or_comment_by_id(context, object).await {
|
match find_post_or_comment_by_id(context, object).await {
|
||||||
Ok(PostOrComment::Post(p)) => receive_undo_delete_post(context, p).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::Comment(c)) => receive_undo_delete_comment(context, *c).await,
|
||||||
// if we dont have the object, no need to do anything
|
// if we dont have the object, no need to do anything
|
||||||
Err(_) => Ok(()),
|
Err(_) => Ok(()),
|
||||||
}
|
}
|
||||||
|
@ -300,8 +300,8 @@ pub(in crate::inbox) async fn receive_undo_remove_for_community(
|
||||||
.single_xsd_any_uri()
|
.single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
match find_post_or_comment_by_id(context, object).await {
|
match find_post_or_comment_by_id(context, object).await {
|
||||||
Ok(PostOrComment::Post(p)) => receive_undo_remove_post(context, p).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::Comment(c)) => receive_undo_remove_comment(context, *c).await,
|
||||||
// if we dont have the object, no need to do anything
|
// if we dont have the object, no need to do anything
|
||||||
Err(_) => Ok(()),
|
Err(_) => Ok(()),
|
||||||
}
|
}
|
||||||
|
@ -325,10 +325,10 @@ pub(in crate::inbox) async fn receive_undo_like_for_community(
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||||
PostOrComment::Post(post) => {
|
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) => {
|
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!())?;
|
.context(location_info!())?;
|
||||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||||
PostOrComment::Post(post) => {
|
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) => {
|
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,
|
request_counter: &mut i32,
|
||||||
) -> Result<PostOrComment, LemmyError> {
|
) -> Result<PostOrComment, LemmyError> {
|
||||||
if let Ok(post) = get_or_fetch_and_insert_post(apub_id, context, request_counter).await {
|
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 {
|
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())
|
Err(NotFound.into())
|
||||||
|
|
|
@ -15,9 +15,9 @@ use crate::{
|
||||||
use activitystreams::{activity::ActorAndObject, prelude::*};
|
use activitystreams::{activity::ActorAndObject, prelude::*};
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{ApubObject, DbPool};
|
use lemmy_db_queries::{ApubObject, DbPool};
|
||||||
use lemmy_db_schema::source::community::Community;
|
use lemmy_db_schema::source::community::Community;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
@ -48,13 +48,13 @@ use activitystreams::{
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use diesel::NotFound;
|
use diesel::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{source::user::User, ApubObject, Followable};
|
use lemmy_db_queries::{source::user::User, ApubObject, Followable};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
community::{Community, CommunityFollower},
|
community::{Community, CommunityFollower},
|
||||||
private_message::PrivateMessage,
|
private_message::PrivateMessage,
|
||||||
user::User_,
|
user::User_,
|
||||||
};
|
};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
@ -143,7 +143,14 @@ pub(crate) async fn user_receive_message(
|
||||||
let actor_url = actor.actor_id();
|
let actor_url = actor.actor_id();
|
||||||
match kind {
|
match kind {
|
||||||
UserValidTypes::Accept => {
|
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 => {
|
UserValidTypes::Announce => {
|
||||||
receive_announce(&context, any_base, actor, request_counter).await?
|
receive_announce(&context, any_base, actor, request_counter).await?
|
||||||
|
|
|
@ -24,17 +24,20 @@ use activitystreams::{
|
||||||
use activitystreams_ext::{Ext1, Ext2};
|
use activitystreams_ext::{Ext1, Ext2};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use diesel::NotFound;
|
use diesel::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{source::activity::Activity_, ApubObject, DbPool};
|
use lemmy_db_queries::{source::activity::Activity_, ApubObject, DbPool};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::{
|
||||||
|
source::{
|
||||||
activity::Activity,
|
activity::Activity,
|
||||||
comment::Comment,
|
comment::Comment,
|
||||||
community::Community,
|
community::Community,
|
||||||
post::Post,
|
post::Post,
|
||||||
private_message::PrivateMessage,
|
private_message::PrivateMessage,
|
||||||
user::User_,
|
user::User_,
|
||||||
|
},
|
||||||
|
DbUrl,
|
||||||
};
|
};
|
||||||
use lemmy_structs::blocking;
|
use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
|
||||||
use lemmy_utils::{location_info, settings::Settings, LemmyError};
|
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::net::IpAddr;
|
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 domain = apub_id.domain().context(location_info!())?.to_string();
|
||||||
let local_instance = settings.get_hostname_without_port()?;
|
let local_instance = settings.get_hostname_without_port()?;
|
||||||
|
|
||||||
if !settings.federation.enabled {
|
if !settings.federation().enabled {
|
||||||
return if domain == local_instance {
|
return if domain == local_instance {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} 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());
|
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();
|
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(())
|
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
|
// 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.
|
// 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(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("{} not in federation allowlist", domain).into())
|
Err(anyhow!("{} not in federation allowlist", domain).into())
|
||||||
}
|
}
|
||||||
} else if !blocked_instances.is_empty() {
|
} else if let Some(blocked) = blocked_instances {
|
||||||
if blocked_instances.contains(&domain) {
|
if blocked.contains(&domain) {
|
||||||
Err(anyhow!("{} is in federation blocklist", domain).into())
|
Err(anyhow!("{} is in federation blocklist", domain).into())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -215,7 +219,7 @@ pub enum EndpointType {
|
||||||
pub fn generate_apub_endpoint(
|
pub fn generate_apub_endpoint(
|
||||||
endpoint_type: EndpointType,
|
endpoint_type: EndpointType,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Result<lemmy_db_schema::Url, ParseError> {
|
) -> Result<DbUrl, ParseError> {
|
||||||
let point = match endpoint_type {
|
let point = match endpoint_type {
|
||||||
EndpointType::Community => "c",
|
EndpointType::Community => "c",
|
||||||
EndpointType::User => "u",
|
EndpointType::User => "u",
|
||||||
|
@ -235,21 +239,15 @@ pub fn generate_apub_endpoint(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_followers_url(
|
pub fn generate_followers_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
|
||||||
actor_id: &lemmy_db_schema::Url,
|
|
||||||
) -> Result<lemmy_db_schema::Url, ParseError> {
|
|
||||||
Ok(Url::parse(&format!("{}/followers", actor_id))?.into())
|
Ok(Url::parse(&format!("{}/followers", actor_id))?.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_inbox_url(
|
pub fn generate_inbox_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
|
||||||
actor_id: &lemmy_db_schema::Url,
|
|
||||||
) -> Result<lemmy_db_schema::Url, ParseError> {
|
|
||||||
Ok(Url::parse(&format!("{}/inbox", actor_id))?.into())
|
Ok(Url::parse(&format!("{}/inbox", actor_id))?.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_shared_inbox_url(
|
pub fn generate_shared_inbox_url(actor_id: &DbUrl) -> Result<DbUrl, LemmyError> {
|
||||||
actor_id: &lemmy_db_schema::Url,
|
|
||||||
) -> Result<lemmy_db_schema::Url, LemmyError> {
|
|
||||||
let actor_id = actor_id.clone().into_inner();
|
let actor_id = actor_id.clone().into_inner();
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}://{}{}/inbox",
|
"{}://{}{}/inbox",
|
||||||
|
@ -276,7 +274,7 @@ pub(crate) async fn insert_activity<T>(
|
||||||
where
|
where
|
||||||
T: Serialize + std::fmt::Debug + Send + 'static,
|
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| {
|
blocking(pool, move |conn| {
|
||||||
Activity::insert(conn, ap_id, &activity, local, sensitive)
|
Activity::insert(conn, ap_id, &activity, local, sensitive)
|
||||||
})
|
})
|
||||||
|
@ -285,8 +283,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum PostOrComment {
|
pub(crate) enum PostOrComment {
|
||||||
Comment(Comment),
|
Comment(Box<Comment>),
|
||||||
Post(Post),
|
Post(Box<Post>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to find a post or comment in the local database, without any network requests.
|
/// 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?;
|
.await?;
|
||||||
if let Ok(p) = post {
|
if let Ok(p) = post {
|
||||||
return Ok(PostOrComment::Post(p));
|
return Ok(PostOrComment::Post(Box::new(p)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ap_id = apub_id.clone();
|
let ap_id = apub_id.clone();
|
||||||
|
@ -311,7 +309,7 @@ pub(crate) async fn find_post_or_comment_by_id(
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
if let Ok(c) = comment {
|
if let Ok(c) = comment {
|
||||||
return Ok(PostOrComment::Comment(c));
|
return Ok(PostOrComment::Comment(Box::new(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(NotFound.into())
|
Err(NotFound.into())
|
||||||
|
@ -332,8 +330,8 @@ pub(crate) async fn find_object_by_id(
|
||||||
let ap_id = apub_id.clone();
|
let ap_id = apub_id.clone();
|
||||||
if let Ok(pc) = find_post_or_comment_by_id(context, ap_id.to_owned()).await {
|
if let Ok(pc) = find_post_or_comment_by_id(context, ap_id.to_owned()).await {
|
||||||
return Ok(match pc {
|
return Ok(match pc {
|
||||||
PostOrComment::Post(p) => Object::Post(p),
|
PostOrComment::Post(p) => Object::Post(*p),
|
||||||
PostOrComment::Comment(c) => Object::Comment(c),
|
PostOrComment::Comment(c) => Object::Comment(*c),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,13 @@ use activitystreams::{
|
||||||
public,
|
public,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{Crud, DbPool};
|
use lemmy_db_queries::{Crud, DbPool};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
post::Post,
|
post::Post,
|
||||||
user::User_,
|
user::User_,
|
||||||
};
|
};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
utils::{convert_datetime, remove_slurs},
|
utils::{convert_datetime, remove_slurs},
|
||||||
|
|
|
@ -22,13 +22,13 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use activitystreams_ext::Ext2;
|
use activitystreams_ext::Ext2;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::DbPool;
|
use lemmy_db_queries::DbPool;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
naive_now,
|
naive_now,
|
||||||
source::community::{Community, CommunityForm},
|
source::community::{Community, CommunityForm},
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
|
use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
utils::{check_slurs, check_slurs_opt, convert_datetime},
|
utils::{check_slurs, check_slurs_opt, convert_datetime},
|
||||||
|
@ -73,13 +73,13 @@ impl ToApub for Community {
|
||||||
|
|
||||||
if let Some(icon_url) = &self.icon {
|
if let Some(icon_url) = &self.icon {
|
||||||
let mut image = Image::new();
|
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()?);
|
group.set_icon(image.into_any_base()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(banner_url) = &self.banner {
|
if let Some(banner_url) = &self.banner {
|
||||||
let mut image = Image::new();
|
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()?);
|
group.set_image(image.into_any_base()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ impl FromApubToForm<GroupExt> for CommunityForm {
|
||||||
.url()
|
.url()
|
||||||
.context(location_info!())?
|
.context(location_info!())?
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.map(|u| u.to_string()),
|
.map(|u| u.to_owned().into()),
|
||||||
),
|
),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
@ -185,7 +185,7 @@ impl FromApubToForm<GroupExt> for CommunityForm {
|
||||||
.url()
|
.url()
|
||||||
.context(location_info!())?
|
.context(location_info!())?
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.map(|u| u.to_string()),
|
.map(|u| u.to_owned().into()),
|
||||||
),
|
),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,12 +12,12 @@ use activitystreams::{
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{ApubObject, Crud, DbPool};
|
use lemmy_db_queries::{ApubObject, Crud, DbPool};
|
||||||
use lemmy_db_schema::source::community::Community;
|
use lemmy_db_schema::{source::community::Community, DbUrl};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
settings::Settings,
|
settings::structs::Settings,
|
||||||
utils::{convert_datetime, markdown_to_html},
|
utils::{convert_datetime, markdown_to_html},
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -96,7 +96,7 @@ where
|
||||||
pub(in crate::objects) fn check_object_domain<T, Kind>(
|
pub(in crate::objects) fn check_object_domain<T, Kind>(
|
||||||
apub: &T,
|
apub: &T,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
) -> Result<lemmy_db_schema::Url, LemmyError>
|
) -> Result<DbUrl, LemmyError>
|
||||||
where
|
where
|
||||||
T: Base + AsBase<Kind>,
|
T: Base + AsBase<Kind>,
|
||||||
{
|
{
|
||||||
|
@ -187,7 +187,7 @@ where
|
||||||
let domain = object_id.domain().context(location_info!())?;
|
let domain = object_id.domain().context(location_info!())?;
|
||||||
|
|
||||||
// if its a local object, return it directly from the database
|
// 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| {
|
let object = blocking(context.pool(), move |conn| {
|
||||||
To::read_from_apub_id(conn, &object_id.into())
|
To::read_from_apub_id(conn, &object_id.into())
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,13 +22,16 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use activitystreams_ext::Ext1;
|
use activitystreams_ext::Ext1;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{Crud, DbPool};
|
use lemmy_db_queries::{Crud, DbPool};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::{
|
||||||
|
self,
|
||||||
|
source::{
|
||||||
community::Community,
|
community::Community,
|
||||||
post::{Post, PostForm},
|
post::{Post, PostForm},
|
||||||
user::User_,
|
user::User_,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
request::fetch_iframely_and_pictrs_data,
|
request::fetch_iframely_and_pictrs_data,
|
||||||
|
@ -70,16 +73,13 @@ impl ToApub for Post {
|
||||||
set_content_and_source(&mut page, &body)?;
|
set_content_and_source(&mut page, &body)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: hacky code because we get self.url == Some("")
|
if let Some(url) = &self.url {
|
||||||
// https://github.com/LemmyNet/lemmy/issues/602
|
page.set_url::<Url>(url.to_owned().into());
|
||||||
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(thumbnail_url) = &self.thumbnail_url {
|
if let Some(thumbnail_url) = &self.thumbnail_url {
|
||||||
let mut image = Image::new();
|
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()?);
|
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 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(
|
Some(any_image) => Image::from_any_base(
|
||||||
any_image
|
any_image
|
||||||
.to_owned()
|
.to_owned()
|
||||||
|
@ -158,7 +158,7 @@ impl FromApubToForm<PageExt> for PostForm {
|
||||||
.url()
|
.url()
|
||||||
.context(location_info!())?
|
.context(location_info!())?
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.map(|u| u.to_string()),
|
.map(|url| url.to_owned()),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
let url = page
|
let url = page
|
||||||
|
@ -166,11 +166,11 @@ impl FromApubToForm<PageExt> for PostForm {
|
||||||
.url()
|
.url()
|
||||||
.map(|u| u.as_single_xsd_any_uri())
|
.map(|u| u.as_single_xsd_any_uri())
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|s| s.to_string());
|
.map(|u| u.to_owned());
|
||||||
|
|
||||||
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
||||||
if let Some(url) = &url {
|
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 {
|
} else {
|
||||||
(None, None, None, thumbnail_url)
|
(None, None, None, thumbnail_url)
|
||||||
};
|
};
|
||||||
|
@ -192,7 +192,7 @@ impl FromApubToForm<PageExt> for PostForm {
|
||||||
let body_slurs_removed = body.map(|b| remove_slurs(&b));
|
let body_slurs_removed = body.map(|b| remove_slurs(&b));
|
||||||
Ok(PostForm {
|
Ok(PostForm {
|
||||||
name,
|
name,
|
||||||
url,
|
url: url.map(|u| u.into()),
|
||||||
body: body_slurs_removed,
|
body: body_slurs_removed,
|
||||||
creator_id: creator.id,
|
creator_id: creator.id,
|
||||||
community_id: community.id,
|
community_id: community.id,
|
||||||
|
@ -214,7 +214,7 @@ impl FromApubToForm<PageExt> for PostForm {
|
||||||
embed_title: iframely_title,
|
embed_title: iframely_title,
|
||||||
embed_description: iframely_description,
|
embed_description: iframely_description,
|
||||||
embed_html: iframely_html,
|
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)?),
|
ap_id: Some(check_object_domain(page, expected_domain)?),
|
||||||
local: false,
|
local: false,
|
||||||
})
|
})
|
||||||
|
|
|
@ -19,12 +19,12 @@ use activitystreams::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{Crud, DbPool};
|
use lemmy_db_queries::{Crud, DbPool};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
private_message::{PrivateMessage, PrivateMessageForm},
|
private_message::{PrivateMessage, PrivateMessageForm},
|
||||||
user::User_,
|
user::User_,
|
||||||
};
|
};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{location_info, utils::convert_datetime, LemmyError};
|
use lemmy_utils::{location_info, utils::convert_datetime, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
|
@ -18,15 +18,15 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use activitystreams_ext::Ext1;
|
use activitystreams_ext::Ext1;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{ApubObject, DbPool};
|
use lemmy_db_queries::{ApubObject, DbPool};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
naive_now,
|
naive_now,
|
||||||
source::user::{UserForm, User_},
|
source::user::{UserForm, User_},
|
||||||
};
|
};
|
||||||
use lemmy_structs::blocking;
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
settings::Settings,
|
settings::structs::Settings,
|
||||||
utils::{check_slurs, check_slurs_opt, convert_datetime},
|
utils::{check_slurs, check_slurs_opt, convert_datetime},
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -50,13 +50,13 @@ impl ToApub for User_ {
|
||||||
|
|
||||||
if let Some(avatar_url) = &self.avatar {
|
if let Some(avatar_url) = &self.avatar {
|
||||||
let mut image = Image::new();
|
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()?);
|
person.set_icon(image.into_any_base()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(banner_url) = &self.banner {
|
if let Some(banner_url) = &self.banner {
|
||||||
let mut image = Image::new();
|
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()?);
|
person.set_image(image.into_any_base()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ impl FromApub for User_ {
|
||||||
) -> Result<User_, LemmyError> {
|
) -> Result<User_, LemmyError> {
|
||||||
let user_id = person.id_unchecked().context(location_info!())?.to_owned();
|
let user_id = person.id_unchecked().context(location_info!())?.to_owned();
|
||||||
let domain = user_id.domain().context(location_info!())?;
|
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| {
|
let user = blocking(context.pool(), move |conn| {
|
||||||
User_::read_from_apub_id(conn, &user_id.into())
|
User_::read_from_apub_id(conn, &user_id.into())
|
||||||
})
|
})
|
||||||
|
@ -126,7 +126,7 @@ impl FromApubToForm<PersonExt> for UserForm {
|
||||||
.url()
|
.url()
|
||||||
.context(location_info!())?
|
.context(location_info!())?
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.map(|u| u.to_string()),
|
.map(|url| url.to_owned()),
|
||||||
),
|
),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
@ -139,7 +139,7 @@ impl FromApubToForm<PersonExt> for UserForm {
|
||||||
.url()
|
.url()
|
||||||
.context(location_info!())?
|
.context(location_info!())?
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.map(|u| u.to_string()),
|
.map(|url| url.to_owned()),
|
||||||
),
|
),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
@ -174,8 +174,8 @@ impl FromApubToForm<PersonExt> for UserForm {
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: None,
|
banned: None,
|
||||||
email: None,
|
email: None,
|
||||||
avatar,
|
avatar: avatar.map(|o| o.map(|i| i.into())),
|
||||||
banner,
|
banner: banner.map(|o| o.map(|i| i.into())),
|
||||||
published: person.inner.published().map(|u| u.to_owned().naive_local()),
|
published: person.inner.published().map(|u| u.to_owned().naive_local()),
|
||||||
updated: person.updated().map(|u| u.to_owned().naive_local()),
|
updated: person.updated().map(|u| u.to_owned().naive_local()),
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -16,15 +16,15 @@ use crate::{
|
||||||
};
|
};
|
||||||
use actix_web::*;
|
use actix_web::*;
|
||||||
use http_signature_normalization_actix::digest::middleware::VerifyDigest;
|
use http_signature_normalization_actix::digest::middleware::VerifyDigest;
|
||||||
use lemmy_utils::settings::Settings;
|
use lemmy_utils::settings::structs::Settings;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
static APUB_JSON_CONTENT_TYPE_LONG: &str =
|
static APUB_JSON_CONTENT_TYPE_LONG: &str =
|
||||||
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
|
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
|
||||||
|
|
||||||
pub fn config(cfg: &mut web::ServiceConfig) {
|
pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
if Settings::get().federation.enabled {
|
if Settings::get().federation().enabled {
|
||||||
println!("federation enabled, host is {}", Settings::get().hostname);
|
println!("federation enabled, host is {}", Settings::get().hostname());
|
||||||
let digest_verifier = VerifyDigest::new(Sha256::new());
|
let digest_verifier = VerifyDigest::new(Sha256::new());
|
||||||
|
|
||||||
let header_guard_accept = guard::Any(guard::Header("Accept", APUB_JSON_CONTENT_TYPE))
|
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"
|
strum_macros = "0.20.1"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
sha2 = "0.9.3"
|
sha2 = "0.9.3"
|
||||||
url = { version = "2.2.0", features = ["serde"] }
|
url = { version = "2.2.1", features = ["serde"] }
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
regex = "1.4.3"
|
regex = "1.4.3"
|
||||||
bcrypt = "0.9.0"
|
bcrypt = "0.9.0"
|
||||||
|
|
|
@ -13,10 +13,12 @@ extern crate diesel_migrations;
|
||||||
extern crate serial_test;
|
extern crate serial_test;
|
||||||
|
|
||||||
use diesel::{result::Error, *};
|
use diesel::{result::Error, *};
|
||||||
use lemmy_db_schema::Url;
|
use lemmy_db_schema::DbUrl;
|
||||||
|
use lemmy_utils::ApiError;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{env, env::VarError};
|
use std::{env, env::VarError};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
pub mod aggregates;
|
pub mod aggregates;
|
||||||
pub mod source;
|
pub mod source;
|
||||||
|
@ -112,7 +114,7 @@ pub trait Reportable<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ApubObject<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
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
fn upsert(conn: &PgConnection, user_form: &T) -> Result<Self, Error>
|
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!();
|
embed_migrations!();
|
||||||
|
|
||||||
pub fn establish_unpooled_connection() -> PgConnection {
|
pub fn establish_unpooled_connection() -> PgConnection {
|
||||||
|
@ -231,7 +247,7 @@ pub fn establish_unpooled_connection() -> PgConnection {
|
||||||
};
|
};
|
||||||
let conn =
|
let conn =
|
||||||
PgConnection::establish(&db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
|
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
|
conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +280,8 @@ pub fn establish_pooled_connection(
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref EMAIL_REGEX: Regex =
|
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 {
|
pub mod functions {
|
||||||
|
@ -277,7 +294,7 @@ pub mod functions {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::fuzzy_search;
|
use super::{fuzzy_search, *};
|
||||||
use crate::is_email_regex;
|
use crate::is_email_regex;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -291,4 +308,32 @@ mod tests {
|
||||||
assert!(is_email_regex("gush@gmail.com"));
|
assert!(is_email_regex("gush@gmail.com"));
|
||||||
assert!(!is_email_regex("nada_neutho"));
|
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 crate::Crud;
|
||||||
use diesel::{dsl::*, result::Error, sql_types::Text, *};
|
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 log::debug;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
@ -41,7 +41,7 @@ impl Crud<ActivityForm> for Activity {
|
||||||
pub trait Activity_ {
|
pub trait Activity_ {
|
||||||
fn insert<T>(
|
fn insert<T>(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
ap_id: String,
|
ap_id: DbUrl,
|
||||||
data: &T,
|
data: &T,
|
||||||
local: bool,
|
local: bool,
|
||||||
sensitive: bool,
|
sensitive: bool,
|
||||||
|
@ -49,20 +49,20 @@ pub trait Activity_ {
|
||||||
where
|
where
|
||||||
T: Serialize + Debug;
|
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>;
|
fn delete_olds(conn: &PgConnection) -> Result<usize, Error>;
|
||||||
|
|
||||||
/// Returns up to 20 activities of type `Announce/Create/Page` from the community
|
/// Returns up to 20 activities of type `Announce/Create/Page` from the community
|
||||||
fn read_community_outbox(
|
fn read_community_outbox(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
community_actor_id: &Url,
|
community_actor_id: &DbUrl,
|
||||||
) -> Result<Vec<Value>, Error>;
|
) -> Result<Vec<Value>, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Activity_ for Activity {
|
impl Activity_ for Activity {
|
||||||
fn insert<T>(
|
fn insert<T>(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
ap_id: String,
|
ap_id: DbUrl,
|
||||||
data: &T,
|
data: &T,
|
||||||
local: bool,
|
local: bool,
|
||||||
sensitive: 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::*;
|
use lemmy_db_schema::schema::activity::dsl::*;
|
||||||
activity.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
activity.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ impl Activity_ for Activity {
|
||||||
|
|
||||||
fn read_community_outbox(
|
fn read_community_outbox(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
community_actor_id: &Url,
|
community_actor_id: &DbUrl,
|
||||||
) -> Result<Vec<Value>, Error> {
|
) -> Result<Vec<Value>, Error> {
|
||||||
use lemmy_db_schema::schema::activity::dsl::*;
|
use lemmy_db_schema::schema::activity::dsl::*;
|
||||||
let res: Vec<Value> = activity
|
let res: Vec<Value> = activity
|
||||||
|
@ -121,6 +121,7 @@ impl Activity_ for Activity {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
establish_unpooled_connection,
|
establish_unpooled_connection,
|
||||||
source::activity::Activity_,
|
source::activity::Activity_,
|
||||||
|
@ -134,6 +135,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
|
@ -171,8 +173,11 @@ mod tests {
|
||||||
|
|
||||||
let inserted_creator = User_::create(&conn, &creator_form).unwrap();
|
let inserted_creator = User_::create(&conn, &creator_form).unwrap();
|
||||||
|
|
||||||
let ap_id =
|
let ap_id: DbUrl = Url::parse(
|
||||||
"https://enterprise.lemmy.ml/activities/delete/f1b5d57c-80f8-4e03-a615-688d552e946c";
|
"https://enterprise.lemmy.ml/activities/delete/f1b5d57c-80f8-4e03-a615-688d552e946c",
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.into();
|
||||||
let test_json: Value = serde_json::from_str(
|
let test_json: Value = serde_json::from_str(
|
||||||
r#"{
|
r#"{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
@ -188,7 +193,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let activity_form = ActivityForm {
|
let activity_form = ActivityForm {
|
||||||
ap_id: ap_id.to_string(),
|
ap_id: ap_id.clone(),
|
||||||
data: test_json.to_owned(),
|
data: test_json.to_owned(),
|
||||||
local: true,
|
local: true,
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
|
@ -198,7 +203,7 @@ mod tests {
|
||||||
let inserted_activity = Activity::create(&conn, &activity_form).unwrap();
|
let inserted_activity = Activity::create(&conn, &activity_form).unwrap();
|
||||||
|
|
||||||
let expected_activity = Activity {
|
let expected_activity = Activity {
|
||||||
ap_id: Some(ap_id.to_string()),
|
ap_id: Some(ap_id.clone()),
|
||||||
id: inserted_activity.id,
|
id: inserted_activity.id,
|
||||||
data: test_json,
|
data: test_json,
|
||||||
local: true,
|
local: true,
|
||||||
|
@ -208,7 +213,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
let read_activity = Activity::read(&conn, inserted_activity.id).unwrap();
|
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();
|
User_::delete(&conn, inserted_creator.id).unwrap();
|
||||||
Activity::delete(&conn, inserted_activity.id).unwrap();
|
Activity::delete(&conn, inserted_activity.id).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,11 @@ use lemmy_db_schema::{
|
||||||
CommentSaved,
|
CommentSaved,
|
||||||
CommentSavedForm,
|
CommentSavedForm,
|
||||||
},
|
},
|
||||||
Url,
|
DbUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Comment_ {
|
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(
|
fn permadelete_for_creator(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
for_creator_id: i32,
|
for_creator_id: i32,
|
||||||
|
@ -43,7 +43,7 @@ pub trait Comment_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Comment_ for 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::*;
|
use lemmy_db_schema::schema::comment::dsl::*;
|
||||||
|
|
||||||
diesel::update(comment.find(comment_id))
|
diesel::update(comment.find(comment_id))
|
||||||
|
@ -145,7 +145,7 @@ impl Crud<CommentForm> for Comment {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApubObject<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::*;
|
use lemmy_db_schema::schema::comment::dsl::*;
|
||||||
comment.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
comment.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use lemmy_db_schema::{
|
||||||
CommunityUserBan,
|
CommunityUserBan,
|
||||||
CommunityUserBanForm,
|
CommunityUserBanForm,
|
||||||
},
|
},
|
||||||
Url,
|
DbUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod safe_type {
|
mod safe_type {
|
||||||
|
@ -90,7 +90,7 @@ impl Crud<CommunityForm> for Community {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApubObject<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::*;
|
use lemmy_db_schema::schema::community::dsl::*;
|
||||||
community
|
community
|
||||||
.filter(actor_id.eq(for_actor_id))
|
.filter(actor_id.eq(for_actor_id))
|
||||||
|
@ -131,7 +131,10 @@ pub trait Community_ {
|
||||||
new_creator_id: i32,
|
new_creator_id: i32,
|
||||||
) -> Result<Community, Error>;
|
) -> Result<Community, Error>;
|
||||||
fn distinct_federated_communities(conn: &PgConnection) -> Result<Vec<String>, 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 {
|
impl Community_ for Community {
|
||||||
|
@ -194,7 +197,7 @@ impl Community_ for Community {
|
||||||
|
|
||||||
fn read_from_followers_url(
|
fn read_from_followers_url(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
followers_url_: &Url,
|
followers_url_: &DbUrl,
|
||||||
) -> Result<Community, Error> {
|
) -> Result<Community, Error> {
|
||||||
use lemmy_db_schema::schema::community::dsl::*;
|
use lemmy_db_schema::schema::community::dsl::*;
|
||||||
community
|
community
|
||||||
|
|
|
@ -12,7 +12,7 @@ use lemmy_db_schema::{
|
||||||
PostSaved,
|
PostSaved,
|
||||||
PostSavedForm,
|
PostSavedForm,
|
||||||
},
|
},
|
||||||
Url,
|
DbUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Crud<PostForm> for Post {
|
impl Crud<PostForm> for Post {
|
||||||
|
@ -42,7 +42,7 @@ impl Crud<PostForm> for Post {
|
||||||
pub trait Post_ {
|
pub trait Post_ {
|
||||||
//fn read(conn: &PgConnection, post_id: i32) -> Result<Post, Error>;
|
//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 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 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_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>;
|
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)
|
.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::*;
|
use lemmy_db_schema::schema::post::dsl::*;
|
||||||
|
|
||||||
diesel::update(post.find(post_id))
|
diesel::update(post.find(post_id))
|
||||||
|
@ -147,7 +147,7 @@ impl Post_ for Post {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApubObject<PostForm> 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::*;
|
use lemmy_db_schema::schema::post::dsl::*;
|
||||||
post.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
post.filter(ap_id.eq(object_id)).first::<Self>(conn)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{ApubObject, Crud};
|
use crate::{ApubObject, Crud};
|
||||||
use diesel::{dsl::*, result::Error, *};
|
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 {
|
impl Crud<PrivateMessageForm> for PrivateMessage {
|
||||||
fn read(conn: &PgConnection, private_message_id: i32) -> Result<Self, Error> {
|
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 {
|
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
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,7 @@ pub trait PrivateMessage_ {
|
||||||
fn update_ap_id(
|
fn update_ap_id(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
private_message_id: i32,
|
private_message_id: i32,
|
||||||
apub_id: Url,
|
apub_id: DbUrl,
|
||||||
) -> Result<PrivateMessage, Error>;
|
) -> Result<PrivateMessage, Error>;
|
||||||
fn update_content(
|
fn update_content(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
|
@ -80,7 +80,7 @@ impl PrivateMessage_ for PrivateMessage {
|
||||||
fn update_ap_id(
|
fn update_ap_id(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
private_message_id: i32,
|
private_message_id: i32,
|
||||||
apub_id: Url,
|
apub_id: DbUrl,
|
||||||
) -> Result<PrivateMessage, Error> {
|
) -> Result<PrivateMessage, Error> {
|
||||||
use lemmy_db_schema::schema::private_message::dsl::*;
|
use lemmy_db_schema::schema::private_message::dsl::*;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ use lemmy_db_schema::{
|
||||||
naive_now,
|
naive_now,
|
||||||
schema::user_::dsl::*,
|
schema::user_::dsl::*,
|
||||||
source::user::{UserForm, UserSafeSettings, User_},
|
source::user::{UserForm, UserSafeSettings, User_},
|
||||||
Url,
|
DbUrl,
|
||||||
};
|
};
|
||||||
use lemmy_utils::settings::Settings;
|
use lemmy_utils::settings::structs::Settings;
|
||||||
|
|
||||||
mod safe_type {
|
mod safe_type {
|
||||||
use crate::ToSafe;
|
use crate::ToSafe;
|
||||||
|
@ -244,7 +244,7 @@ impl Crud<UserForm> for User_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApubObject<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::*;
|
use lemmy_db_schema::schema::user_::dsl::*;
|
||||||
user_
|
user_
|
||||||
.filter(deleted.eq(false))
|
.filter(deleted.eq(false))
|
||||||
|
|
|
@ -12,4 +12,4 @@ chrono = { version = "0.4.19", features = ["serde"] }
|
||||||
serde = { version = "1.0.123", features = ["derive"] }
|
serde = { version = "1.0.123", features = ["derive"] }
|
||||||
serde_json = { version = "1.0.61", features = ["preserve_order"] }
|
serde_json = { version = "1.0.61", features = ["preserve_order"] }
|
||||||
log = "0.4.14"
|
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},
|
serialize::{Output, ToSql},
|
||||||
sql_types::Text,
|
sql_types::Text,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
io::Write,
|
io::Write,
|
||||||
};
|
};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
pub mod source;
|
pub mod source;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Clone, PartialEq, Serialize, Debug, AsExpression, FromSqlRow)]
|
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, FromSqlRow)]
|
||||||
#[sql_type = "Text"]
|
#[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
|
where
|
||||||
String: ToSql<Text, DB>,
|
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
|
where
|
||||||
String: FromSql<Text, DB>,
|
String: FromSql<Text, DB>,
|
||||||
{
|
{
|
||||||
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
|
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
|
||||||
let str = String::from_sql(bytes)?;
|
let str = String::from_sql(bytes)?;
|
||||||
Ok(Url(url::Url::parse(&str)?))
|
Ok(DbUrl(Url::parse(&str)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Url {
|
impl DbUrl {
|
||||||
pub fn into_inner(self) -> url::Url {
|
pub fn into_inner(self) -> Url {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Url {
|
impl Display for DbUrl {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
self.to_owned().into_inner().fmt(f)
|
self.to_owned().into_inner().fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Url> for url::Url {
|
impl From<DbUrl> for Url {
|
||||||
fn from(url: Url) -> Self {
|
fn from(url: DbUrl) -> Self {
|
||||||
url.0
|
url.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<url::Url> for Url {
|
impl From<Url> for DbUrl {
|
||||||
fn from(url: url::Url) -> Self {
|
fn from(url: Url) -> Self {
|
||||||
Url(url)
|
DbUrl(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::schema::activity;
|
use crate::{schema::activity, DbUrl};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ pub struct Activity {
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub ap_id: Option<String>,
|
pub ap_id: Option<DbUrl>,
|
||||||
pub sensitive: Option<bool>,
|
pub sensitive: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,6 @@ pub struct ActivityForm {
|
||||||
pub data: Value,
|
pub data: Value,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub ap_id: String,
|
pub ap_id: DbUrl,
|
||||||
pub sensitive: bool,
|
pub sensitive: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
schema::{comment, comment_alias_1, comment_like, comment_saved},
|
schema::{comment, comment_alias_1, comment_like, comment_saved},
|
||||||
source::post::Post,
|
source::post::Post,
|
||||||
Url,
|
DbUrl,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ pub struct Comment {
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub ap_id: Url,
|
pub ap_id: DbUrl,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ pub struct CommentAlias1 {
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub ap_id: Url,
|
pub ap_id: DbUrl,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ pub struct CommentForm {
|
||||||
pub published: Option<chrono::NaiveDateTime>,
|
pub published: Option<chrono::NaiveDateTime>,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub deleted: Option<bool>,
|
pub deleted: Option<bool>,
|
||||||
pub ap_id: Option<Url>,
|
pub ap_id: Option<DbUrl>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
schema::{community, community_follower, community_moderator, community_user_ban},
|
schema::{community, community_follower, community_moderator, community_user_ban},
|
||||||
Url,
|
DbUrl,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -17,16 +17,16 @@ pub struct Community {
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub nsfw: bool,
|
pub nsfw: bool,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub private_key: Option<String>,
|
pub private_key: Option<String>,
|
||||||
pub public_key: Option<String>,
|
pub public_key: Option<String>,
|
||||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<DbUrl>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
pub followers_url: Url,
|
pub followers_url: DbUrl,
|
||||||
pub inbox_url: Url,
|
pub inbox_url: DbUrl,
|
||||||
pub shared_inbox_url: Option<Url>,
|
pub shared_inbox_url: Option<DbUrl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A safe representation of community, without the sensitive info
|
/// A safe representation of community, without the sensitive info
|
||||||
|
@ -43,10 +43,10 @@ pub struct CommunitySafe {
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub nsfw: bool,
|
pub nsfw: bool,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<DbUrl>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Insertable, AsChangeset, Debug)]
|
#[derive(Insertable, AsChangeset, Debug)]
|
||||||
|
@ -61,16 +61,16 @@ pub struct CommunityForm {
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub deleted: Option<bool>,
|
pub deleted: Option<bool>,
|
||||||
pub nsfw: bool,
|
pub nsfw: bool,
|
||||||
pub actor_id: Option<Url>,
|
pub actor_id: Option<DbUrl>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub private_key: Option<String>,
|
pub private_key: Option<String>,
|
||||||
pub public_key: Option<String>,
|
pub public_key: Option<String>,
|
||||||
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
|
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
|
||||||
pub icon: Option<Option<String>>,
|
pub icon: Option<Option<DbUrl>>,
|
||||||
pub banner: Option<Option<String>>,
|
pub banner: Option<Option<DbUrl>>,
|
||||||
pub followers_url: Option<Url>,
|
pub followers_url: Option<DbUrl>,
|
||||||
pub inbox_url: Option<Url>,
|
pub inbox_url: Option<DbUrl>,
|
||||||
pub shared_inbox_url: Option<Option<Url>>,
|
pub shared_inbox_url: Option<Option<DbUrl>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
|
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
schema::{post, post_like, post_read, post_saved},
|
schema::{post, post_like, post_read, post_saved},
|
||||||
Url,
|
DbUrl,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use serde::Serialize;
|
||||||
pub struct Post {
|
pub struct Post {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub url: Option<String>,
|
pub url: Option<DbUrl>,
|
||||||
pub body: Option<String>,
|
pub body: Option<String>,
|
||||||
pub creator_id: i32,
|
pub creator_id: i32,
|
||||||
pub community_id: i32,
|
pub community_id: i32,
|
||||||
|
@ -23,8 +23,8 @@ pub struct Post {
|
||||||
pub embed_title: Option<String>,
|
pub embed_title: Option<String>,
|
||||||
pub embed_description: Option<String>,
|
pub embed_description: Option<String>,
|
||||||
pub embed_html: Option<String>,
|
pub embed_html: Option<String>,
|
||||||
pub thumbnail_url: Option<String>,
|
pub thumbnail_url: Option<DbUrl>,
|
||||||
pub ap_id: Url,
|
pub ap_id: DbUrl,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ pub struct Post {
|
||||||
#[table_name = "post"]
|
#[table_name = "post"]
|
||||||
pub struct PostForm {
|
pub struct PostForm {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub url: Option<String>,
|
pub url: Option<DbUrl>,
|
||||||
pub body: Option<String>,
|
pub body: Option<String>,
|
||||||
pub creator_id: i32,
|
pub creator_id: i32,
|
||||||
pub community_id: i32,
|
pub community_id: i32,
|
||||||
|
@ -46,8 +46,8 @@ pub struct PostForm {
|
||||||
pub embed_title: Option<String>,
|
pub embed_title: Option<String>,
|
||||||
pub embed_description: Option<String>,
|
pub embed_description: Option<String>,
|
||||||
pub embed_html: Option<String>,
|
pub embed_html: Option<String>,
|
||||||
pub thumbnail_url: Option<String>,
|
pub thumbnail_url: Option<DbUrl>,
|
||||||
pub ap_id: Option<Url>,
|
pub ap_id: Option<DbUrl>,
|
||||||
pub local: bool,
|
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};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -11,7 +11,7 @@ pub struct PostReport {
|
||||||
pub creator_id: i32,
|
pub creator_id: i32,
|
||||||
pub post_id: i32,
|
pub post_id: i32,
|
||||||
pub original_post_name: String,
|
pub original_post_name: String,
|
||||||
pub original_post_url: Option<String>,
|
pub original_post_url: Option<DbUrl>,
|
||||||
pub original_post_body: Option<String>,
|
pub original_post_body: Option<String>,
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
pub resolved: bool,
|
pub resolved: bool,
|
||||||
|
@ -26,7 +26,7 @@ pub struct PostReportForm {
|
||||||
pub creator_id: i32,
|
pub creator_id: i32,
|
||||||
pub post_id: i32,
|
pub post_id: i32,
|
||||||
pub original_post_name: String,
|
pub original_post_name: String,
|
||||||
pub original_post_url: Option<String>,
|
pub original_post_url: Option<DbUrl>,
|
||||||
pub original_post_body: Option<String>,
|
pub original_post_body: Option<String>,
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{schema::private_message, Url};
|
use crate::{schema::private_message, DbUrl};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)]
|
#[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)]
|
||||||
|
@ -12,7 +12,7 @@ pub struct PrivateMessage {
|
||||||
pub read: bool,
|
pub read: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub ap_id: Url,
|
pub ap_id: DbUrl,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,6 @@ pub struct PrivateMessageForm {
|
||||||
pub read: Option<bool>,
|
pub read: Option<bool>,
|
||||||
pub published: Option<chrono::NaiveDateTime>,
|
pub published: Option<chrono::NaiveDateTime>,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub ap_id: Option<Url>,
|
pub ap_id: Option<DbUrl>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::schema::site;
|
use crate::{schema::site, DbUrl};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Queryable, Identifiable, PartialEq, Debug, Clone, Serialize)]
|
#[derive(Queryable, Identifiable, PartialEq, Debug, Clone, Serialize)]
|
||||||
|
@ -13,8 +13,8 @@ pub struct Site {
|
||||||
pub enable_downvotes: bool,
|
pub enable_downvotes: bool,
|
||||||
pub open_registration: bool,
|
pub open_registration: bool,
|
||||||
pub enable_nsfw: bool,
|
pub enable_nsfw: bool,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<DbUrl>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Insertable, AsChangeset)]
|
#[derive(Insertable, AsChangeset)]
|
||||||
|
@ -28,6 +28,6 @@ pub struct SiteForm {
|
||||||
pub open_registration: bool,
|
pub open_registration: bool,
|
||||||
pub enable_nsfw: 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.
|
// 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 icon: Option<Option<DbUrl>>,
|
||||||
pub banner: Option<Option<String>>,
|
pub banner: Option<Option<DbUrl>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
schema::{user_, user_alias_1, user_alias_2},
|
schema::{user_, user_alias_1, user_alias_2},
|
||||||
Url,
|
DbUrl,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ pub struct User_ {
|
||||||
pub preferred_username: Option<String>,
|
pub preferred_username: Option<String>,
|
||||||
pub password_encrypted: String,
|
pub password_encrypted: String,
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<DbUrl>,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
|
@ -25,16 +25,16 @@ pub struct User_ {
|
||||||
pub show_avatars: bool,
|
pub show_avatars: bool,
|
||||||
pub send_notifications_to_email: bool,
|
pub send_notifications_to_email: bool,
|
||||||
pub matrix_user_id: Option<String>,
|
pub matrix_user_id: Option<String>,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub bio: Option<String>,
|
pub bio: Option<String>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub private_key: Option<String>,
|
pub private_key: Option<String>,
|
||||||
pub public_key: Option<String>,
|
pub public_key: Option<String>,
|
||||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub inbox_url: Url,
|
pub inbox_url: DbUrl,
|
||||||
pub shared_inbox_url: Option<Url>,
|
pub shared_inbox_url: Option<DbUrl>,
|
||||||
pub validator_time: chrono::NaiveDateTime,
|
pub validator_time: chrono::NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,19 +45,19 @@ pub struct UserSafe {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub preferred_username: Option<String>,
|
pub preferred_username: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<DbUrl>,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub matrix_user_id: Option<String>,
|
pub matrix_user_id: Option<String>,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub bio: Option<String>,
|
pub bio: Option<String>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub inbox_url: Url,
|
pub inbox_url: DbUrl,
|
||||||
pub shared_inbox_url: Option<Url>,
|
pub shared_inbox_url: Option<DbUrl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A safe user view with only settings
|
/// A safe user view with only settings
|
||||||
|
@ -68,7 +68,7 @@ pub struct UserSafeSettings {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub preferred_username: Option<String>,
|
pub preferred_username: Option<String>,
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<DbUrl>,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
|
@ -81,11 +81,11 @@ pub struct UserSafeSettings {
|
||||||
pub show_avatars: bool,
|
pub show_avatars: bool,
|
||||||
pub send_notifications_to_email: bool,
|
pub send_notifications_to_email: bool,
|
||||||
pub matrix_user_id: Option<String>,
|
pub matrix_user_id: Option<String>,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub bio: Option<String>,
|
pub bio: Option<String>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub validator_time: chrono::NaiveDateTime,
|
pub validator_time: chrono::NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ pub struct UserAlias1 {
|
||||||
pub preferred_username: Option<String>,
|
pub preferred_username: Option<String>,
|
||||||
pub password_encrypted: String,
|
pub password_encrypted: String,
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<DbUrl>,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
|
@ -111,13 +111,13 @@ pub struct UserAlias1 {
|
||||||
pub show_avatars: bool,
|
pub show_avatars: bool,
|
||||||
pub send_notifications_to_email: bool,
|
pub send_notifications_to_email: bool,
|
||||||
pub matrix_user_id: Option<String>,
|
pub matrix_user_id: Option<String>,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub bio: Option<String>,
|
pub bio: Option<String>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub private_key: Option<String>,
|
pub private_key: Option<String>,
|
||||||
pub public_key: Option<String>,
|
pub public_key: Option<String>,
|
||||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,16 +127,16 @@ pub struct UserSafeAlias1 {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub preferred_username: Option<String>,
|
pub preferred_username: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<DbUrl>,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub matrix_user_id: Option<String>,
|
pub matrix_user_id: Option<String>,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub bio: Option<String>,
|
pub bio: Option<String>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ pub struct UserAlias2 {
|
||||||
pub preferred_username: Option<String>,
|
pub preferred_username: Option<String>,
|
||||||
pub password_encrypted: String,
|
pub password_encrypted: String,
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<DbUrl>,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
|
@ -161,13 +161,13 @@ pub struct UserAlias2 {
|
||||||
pub show_avatars: bool,
|
pub show_avatars: bool,
|
||||||
pub send_notifications_to_email: bool,
|
pub send_notifications_to_email: bool,
|
||||||
pub matrix_user_id: Option<String>,
|
pub matrix_user_id: Option<String>,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub bio: Option<String>,
|
pub bio: Option<String>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub private_key: Option<String>,
|
pub private_key: Option<String>,
|
||||||
pub public_key: Option<String>,
|
pub public_key: Option<String>,
|
||||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,16 +177,16 @@ pub struct UserSafeAlias2 {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub preferred_username: Option<String>,
|
pub preferred_username: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<DbUrl>,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub matrix_user_id: Option<String>,
|
pub matrix_user_id: Option<String>,
|
||||||
pub actor_id: Url,
|
pub actor_id: DbUrl,
|
||||||
pub bio: Option<String>,
|
pub bio: Option<String>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<DbUrl>,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ pub struct UserForm {
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub banned: Option<bool>,
|
pub banned: Option<bool>,
|
||||||
pub email: Option<Option<String>>,
|
pub email: Option<Option<String>>,
|
||||||
pub avatar: Option<Option<String>>,
|
pub avatar: Option<Option<DbUrl>>,
|
||||||
pub published: Option<chrono::NaiveDateTime>,
|
pub published: Option<chrono::NaiveDateTime>,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
pub show_nsfw: bool,
|
pub show_nsfw: bool,
|
||||||
|
@ -210,13 +210,13 @@ pub struct UserForm {
|
||||||
pub show_avatars: bool,
|
pub show_avatars: bool,
|
||||||
pub send_notifications_to_email: bool,
|
pub send_notifications_to_email: bool,
|
||||||
pub matrix_user_id: Option<Option<String>>,
|
pub matrix_user_id: Option<Option<String>>,
|
||||||
pub actor_id: Option<Url>,
|
pub actor_id: Option<DbUrl>,
|
||||||
pub bio: Option<Option<String>>,
|
pub bio: Option<Option<String>>,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub private_key: Option<String>,
|
pub private_key: Option<String>,
|
||||||
pub public_key: Option<String>,
|
pub public_key: Option<String>,
|
||||||
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
|
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
|
||||||
pub banner: Option<Option<String>>,
|
pub banner: Option<Option<DbUrl>>,
|
||||||
pub inbox_url: Option<Url>,
|
pub inbox_url: Option<DbUrl>,
|
||||||
pub shared_inbox_url: Option<Option<Url>>,
|
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"] }
|
diesel = { version = "1.4.5", features = ["postgres","chrono","r2d2","serde_json"] }
|
||||||
serde = { version = "1.0.123", features = ["derive"] }
|
serde = { version = "1.0.123", features = ["derive"] }
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
url = "2.2.0"
|
url = "2.2.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = "0.5.1"
|
serial_test = "0.5.1"
|
|
@ -13,7 +13,7 @@ lemmy_db_queries = { path = "../db_queries" }
|
||||||
lemmy_db_views = { path = "../db_views" }
|
lemmy_db_views = { path = "../db_views" }
|
||||||
lemmy_db_views_actor = { path = "../db_views_actor" }
|
lemmy_db_views_actor = { path = "../db_views_actor" }
|
||||||
lemmy_db_schema = { path = "../db_schema" }
|
lemmy_db_schema = { path = "../db_schema" }
|
||||||
lemmy_structs = { path = "../structs" }
|
lemmy_api_structs = { path = "../api_structs" }
|
||||||
diesel = "1.4.5"
|
diesel = "1.4.5"
|
||||||
actix = "0.10.0"
|
actix = "0.10.0"
|
||||||
actix-web = { version = "3.3.2", default-features = false, features = ["rustls"] }
|
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"
|
rss = "1.10.0"
|
||||||
serde = { version = "1.0.123", features = ["derive"] }
|
serde = { version = "1.0.123", features = ["derive"] }
|
||||||
awc = { version = "2.0.3", default-features = false }
|
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"
|
strum = "0.20.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
|
@ -2,6 +2,7 @@ use actix_web::{error::ErrorBadRequest, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
source::{community::Community_, user::User},
|
source::{community::Community_, user::User},
|
||||||
ListingType,
|
ListingType,
|
||||||
|
@ -14,8 +15,12 @@ use lemmy_db_views::{
|
||||||
site_view::SiteView,
|
site_view::SiteView,
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::user_mention_view::{UserMentionQueryBuilder, UserMentionView};
|
use lemmy_db_views_actor::user_mention_view::{UserMentionQueryBuilder, UserMentionView};
|
||||||
use lemmy_structs::blocking;
|
use lemmy_utils::{
|
||||||
use lemmy_utils::{claims::Claims, settings::Settings, utils::markdown_to_html, LemmyError};
|
claims::Claims,
|
||||||
|
settings::structs::Settings,
|
||||||
|
utils::markdown_to_html,
|
||||||
|
LemmyError,
|
||||||
|
};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use rss::{
|
use rss::{
|
||||||
extension::dublincore::DublinCoreExtensionBuilder,
|
extension::dublincore::DublinCoreExtensionBuilder,
|
||||||
|
@ -163,7 +168,7 @@ fn get_feed_user(
|
||||||
) -> Result<ChannelBuilder, LemmyError> {
|
) -> Result<ChannelBuilder, LemmyError> {
|
||||||
let site_view = SiteView::read(&conn)?;
|
let site_view = SiteView::read(&conn)?;
|
||||||
let user = User_::find_by_username(&conn, &user_name)?;
|
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)
|
let posts = PostQueryBuilder::create(&conn)
|
||||||
.listing_type(&ListingType::All)
|
.listing_type(&ListingType::All)
|
||||||
|
@ -391,9 +396,6 @@ fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
|
||||||
p.community.name
|
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
|
// TODO add images
|
||||||
let mut description = format!("submitted by <a href=\"{}\">{}</a> to <a href=\"{}\">{}</a><br>{} points | <a href=\"{}\">{} comments</a>",
|
let mut description = format!("submitted by <a href=\"{}\">{}</a> to <a href=\"{}\">{}</a><br>{} points | <a href=\"{}\">{} comments</a>",
|
||||||
p.creator.actor_id,
|
p.creator.actor_id,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use actix::clock::Duration;
|
use actix::clock::Duration;
|
||||||
use actix_web::{body::BodyStream, http::StatusCode, *};
|
use actix_web::{body::BodyStream, http::StatusCode, *};
|
||||||
use awc::Client;
|
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};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
|
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
|
||||||
|
@ -54,8 +54,10 @@ async fn upload(
|
||||||
return Ok(HttpResponse::Unauthorized().finish());
|
return Ok(HttpResponse::Unauthorized().finish());
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut client_req =
|
let mut client_req = client.request_from(
|
||||||
client.request_from(format!("{}/image", Settings::get().pictrs_url), req.head());
|
format!("{}/image", Settings::get().pictrs_url()),
|
||||||
|
req.head(),
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(addr) = req.head().peer_addr {
|
if let Some(addr) = req.head().peer_addr {
|
||||||
client_req = client_req.header("X-Forwarded-For", addr.to_string())
|
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
|
// If there are no query params, the URL is original
|
||||||
let url = if params.format.is_none() && params.thumbnail.is_none() {
|
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 {
|
} else {
|
||||||
// Use jpg as a default when none is given
|
// Use jpg as a default when none is given
|
||||||
let format = params.format.unwrap_or_else(|| "jpg".to_string());
|
let format = params.format.unwrap_or_else(|| "jpg".to_string());
|
||||||
|
|
||||||
let mut url = format!(
|
let mut url = format!(
|
||||||
"{}/image/process.{}?src={}",
|
"{}/image/process.{}?src={}",
|
||||||
Settings::get().pictrs_url,
|
Settings::get().pictrs_url(),
|
||||||
format,
|
format,
|
||||||
name,
|
name,
|
||||||
);
|
);
|
||||||
|
@ -134,7 +136,7 @@ async fn delete(
|
||||||
|
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}/image/delete/{}/{}",
|
"{}/image/delete/{}/{}",
|
||||||
Settings::get().pictrs_url,
|
Settings::get().pictrs_url(),
|
||||||
&token,
|
&token,
|
||||||
&file
|
&file
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use actix_web::{body::Body, error::ErrorBadRequest, *};
|
use actix_web::{body::Body, error::ErrorBadRequest, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use lemmy_api_structs::blocking;
|
||||||
use lemmy_db_views::site_view::SiteView;
|
use lemmy_db_views::site_view::SiteView;
|
||||||
use lemmy_structs::blocking;
|
use lemmy_utils::{settings::structs::Settings, version, LemmyError};
|
||||||
use lemmy_utils::{settings::Settings, version, LemmyError};
|
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -31,7 +31,7 @@ async fn node_info(context: web::Data<LemmyContext>) -> Result<HttpResponse, Err
|
||||||
.await?
|
.await?
|
||||||
.map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?;
|
.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()]
|
vec!["activitypub".to_string()]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use actix_web::{error::ErrorBadRequest, web::Query, *};
|
use actix_web::{error::ErrorBadRequest, web::Query, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use lemmy_api_structs::{blocking, WebFingerLink, WebFingerResponse};
|
||||||
use lemmy_db_queries::source::{community::Community_, user::User};
|
use lemmy_db_queries::source::{community::Community_, user::User};
|
||||||
use lemmy_db_schema::source::{community::Community, user::User_};
|
use lemmy_db_schema::source::{community::Community, user::User_};
|
||||||
use lemmy_structs::{blocking, WebFingerLink, WebFingerResponse};
|
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
settings::Settings,
|
settings::structs::Settings,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
WEBFINGER_COMMUNITY_REGEX,
|
WEBFINGER_COMMUNITY_REGEX,
|
||||||
WEBFINGER_USER_REGEX,
|
WEBFINGER_USER_REGEX,
|
||||||
|
@ -18,7 +18,7 @@ struct Params {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn config(cfg: &mut web::ServiceConfig) {
|
pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
if Settings::get().federation.enabled {
|
if Settings::get().federation().enabled {
|
||||||
cfg.route(
|
cfg.route(
|
||||||
".well-known/webfinger",
|
".well-known/webfinger",
|
||||||
web::get().to(get_webfinger_response),
|
web::get().to(get_webfinger_response),
|
||||||
|
|
|
@ -10,7 +10,6 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1.4.3"
|
regex = "1.4.3"
|
||||||
config = { version = "0.10.1", default-features = false, features = ["hjson"] }
|
|
||||||
chrono = { version = "0.4.19", features = ["serde"] }
|
chrono = { version = "0.4.19", features = ["serde"] }
|
||||||
lettre = "0.10.0-alpha.5"
|
lettre = "0.10.0-alpha.5"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
|
@ -23,7 +22,7 @@ thiserror = "1.0.23"
|
||||||
comrak = { version = "0.9.0", default-features = false }
|
comrak = { version = "0.9.0", default-features = false }
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
openssl = "0.10.32"
|
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-web = { version = "3.3.2", default-features = false, features = ["rustls"] }
|
||||||
actix-rt = { version = "1.1.1", default-features = false }
|
actix-rt = { version = "1.1.1", default-features = false }
|
||||||
anyhow = "1.0.38"
|
anyhow = "1.0.38"
|
||||||
|
@ -35,3 +34,6 @@ futures = "0.3.12"
|
||||||
diesel = "1.4.5"
|
diesel = "1.4.5"
|
||||||
http = "0.2.3"
|
http = "0.2.3"
|
||||||
jsonwebtoken = "7.2.0"
|
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 jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ impl Claims {
|
||||||
};
|
};
|
||||||
decode::<Claims>(
|
decode::<Claims>(
|
||||||
&jwt,
|
&jwt,
|
||||||
&DecodingKey::from_secret(Settings::get().jwt_secret.as_ref()),
|
&DecodingKey::from_secret(Settings::get().jwt_secret().as_ref()),
|
||||||
&v,
|
&v,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ impl Claims {
|
||||||
encode(
|
encode(
|
||||||
&Header::default(),
|
&Header::default(),
|
||||||
&my_claims,
|
&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::{
|
use lettre::{
|
||||||
message::{header, Mailbox, MultiPart, SinglePart},
|
message::{header, Mailbox, MultiPart, SinglePart},
|
||||||
transport::smtp::{
|
transport::smtp::{
|
||||||
|
@ -19,8 +19,8 @@ pub fn send_email(
|
||||||
to_username: &str,
|
to_username: &str,
|
||||||
html: &str,
|
html: &str,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let email_config = Settings::get().email.ok_or("no_email_setup")?;
|
let email_config = Settings::get().email().ok_or("no_email_setup")?;
|
||||||
let domain = Settings::get().hostname;
|
let domain = Settings::get().hostname();
|
||||||
|
|
||||||
let (smtp_server, smtp_port) = {
|
let (smtp_server, smtp_port) = {
|
||||||
let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>();
|
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 rate_limit;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod version;
|
pub mod version;
|
||||||
|
|
||||||
use crate::settings::Settings;
|
use crate::settings::structs::Settings;
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
@ -83,12 +84,12 @@ impl actix_web::error::ResponseError for LemmyError {
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref WEBFINGER_COMMUNITY_REGEX: Regex = Regex::new(&format!(
|
pub static ref WEBFINGER_COMMUNITY_REGEX: Regex = Regex::new(&format!(
|
||||||
"^group:([a-z0-9_]{{3, 20}})@{}$",
|
"^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!(
|
pub static ref WEBFINGER_USER_REGEX: Regex = Regex::new(&format!(
|
||||||
"^acct:([a-z0-9_]{{3, 20}})@{}$",
|
"^acct:([a-z0-9_]{{3, 20}})@{}$",
|
||||||
Settings::get().hostname
|
Settings::get().hostname()
|
||||||
))
|
))
|
||||||
.unwrap();
|
.expect("compile webfinger regex");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
settings::{RateLimitConfig, Settings},
|
settings::structs::{RateLimitConfig, Settings},
|
||||||
utils::get_ip,
|
utils::get_ip,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -70,7 +70,7 @@ impl RateLimited {
|
||||||
{
|
{
|
||||||
// Does not need to be blocking because the RwLock in settings never held across await points,
|
// 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
|
// 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
|
// before
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{settings::Settings, LemmyError};
|
use crate::{settings::structs::Settings, LemmyError};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use log::error;
|
use log::error;
|
||||||
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
|
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
|
||||||
|
@ -6,6 +6,7 @@ use reqwest::Client;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Error)]
|
#[derive(Clone, Debug, Error)]
|
||||||
#[error("Error sending request, {0}")]
|
#[error("Error sending request, {0}")]
|
||||||
|
@ -43,22 +44,22 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response.unwrap()
|
response.expect("retry http request")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub(crate) struct IframelyResponse {
|
pub(crate) struct IframelyResponse {
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
thumbnail_url: Option<String>,
|
thumbnail_url: Option<Url>,
|
||||||
html: Option<String>,
|
html: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn fetch_iframely(
|
pub(crate) async fn fetch_iframely(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
url: &str,
|
url: &Url,
|
||||||
) -> Result<IframelyResponse, LemmyError> {
|
) -> 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?;
|
let response = retry(|| client.get(&fetch_url).send()).await?;
|
||||||
|
|
||||||
|
@ -83,14 +84,14 @@ pub(crate) struct PictrsFile {
|
||||||
|
|
||||||
pub(crate) async fn fetch_pictrs(
|
pub(crate) async fn fetch_pictrs(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
image_url: &str,
|
image_url: &Url,
|
||||||
) -> Result<PictrsResponse, LemmyError> {
|
) -> Result<PictrsResponse, LemmyError> {
|
||||||
is_image_content_type(client, image_url).await?;
|
is_image_content_type(client, image_url).await?;
|
||||||
|
|
||||||
let fetch_url = format!(
|
let fetch_url = format!(
|
||||||
"{}/image/download?url={}",
|
"{}/image/download?url={}",
|
||||||
Settings::get().pictrs_url,
|
Settings::get().pictrs_url(),
|
||||||
utf8_percent_encode(image_url, NON_ALPHANUMERIC) // TODO this might not be needed
|
utf8_percent_encode(image_url.as_str(), NON_ALPHANUMERIC) // TODO this might not be needed
|
||||||
);
|
);
|
||||||
|
|
||||||
let response = retry(|| client.get(&fetch_url).send()).await?;
|
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(
|
pub async fn fetch_iframely_and_pictrs_data(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
url: Option<String>,
|
url: Option<&Url>,
|
||||||
) -> (
|
) -> (Option<String>, Option<String>, Option<String>, Option<Url>) {
|
||||||
Option<String>,
|
|
||||||
Option<String>,
|
|
||||||
Option<String>,
|
|
||||||
Option<String>,
|
|
||||||
) {
|
|
||||||
match &url {
|
match &url {
|
||||||
Some(url) => {
|
Some(url) => {
|
||||||
// Fetch iframely data
|
// Fetch iframely data
|
||||||
|
@ -149,11 +145,19 @@ pub async fn fetch_iframely_and_pictrs_data(
|
||||||
|
|
||||||
// The full urls are necessary for federation
|
// The full urls are necessary for federation
|
||||||
let pictrs_thumbnail = if let Some(pictrs_hash) = pictrs_hash {
|
let pictrs_thumbnail = if let Some(pictrs_hash) = pictrs_hash {
|
||||||
Some(format!(
|
let url = Url::parse(&format!(
|
||||||
"{}/pictrs/image/{}",
|
"{}/pictrs/image/{}",
|
||||||
Settings::get().get_protocol_and_hostname(),
|
Settings::get().get_protocol_and_hostname(),
|
||||||
pictrs_hash
|
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 {
|
} else {
|
||||||
None
|
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> {
|
async fn is_image_content_type(client: &Client, test: &Url) -> Result<(), LemmyError> {
|
||||||
let response = retry(|| client.get(test).send()).await?;
|
let response = retry(|| client.get(test.to_owned()).send()).await?;
|
||||||
|
|
||||||
if response
|
if response
|
||||||
.headers()
|
.headers()
|
||||||
.get("Content-Type")
|
.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 actix_web::dev::ConnectionInfo;
|
||||||
use chrono::{DateTime, FixedOffset, NaiveDateTime};
|
use chrono::{DateTime, FixedOffset, NaiveDateTime};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
@ -6,15 +6,15 @@ use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||||
use regex::{Regex, RegexBuilder};
|
use regex::{Regex, RegexBuilder};
|
||||||
|
|
||||||
lazy_static! {
|
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 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().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().expect("compile regex");
|
||||||
static ref USERNAME_MATCHES_REGEX: Regex = Regex::new(r"/u/[a-zA-Z][0-9a-zA-Z_]*").unwrap();
|
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
|
// 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._-]+\.[a-zA-Z0-9_-]+)").expect("compile regex");
|
||||||
static ref MENTIONS_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._:-]+)").unwrap();
|
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}$").unwrap();
|
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}$").unwrap();
|
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.*").unwrap();
|
static ref VALID_POST_TITLE_REGEX: Regex = Regex::new(r".*\S.*").expect("compile regex");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn naive_from_unix(time: i64) -> NaiveDateTime {
|
pub fn naive_from_unix(time: i64) -> NaiveDateTime {
|
||||||
|
@ -85,7 +85,7 @@ pub struct MentionData {
|
||||||
|
|
||||||
impl MentionData {
|
impl MentionData {
|
||||||
pub fn is_local(&self) -> bool {
|
pub fn is_local(&self) -> bool {
|
||||||
Settings::get().hostname.eq(&self.domain)
|
Settings::get().hostname().eq(&self.domain)
|
||||||
}
|
}
|
||||||
pub fn full_name(&self) -> String {
|
pub fn full_name(&self) -> String {
|
||||||
format!("@{}@{}", &self.name, &self.domain)
|
format!("@{}@{}", &self.name, &self.domain)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "lemmy_websocket"
|
name = "lemmy_websocket"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -11,7 +10,7 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lemmy_utils = { path = "../utils" }
|
lemmy_utils = { path = "../utils" }
|
||||||
lemmy_structs = { path = "../structs" }
|
lemmy_api_structs = { path = "../api_structs" }
|
||||||
lemmy_db_queries = { path = "../db_queries" }
|
lemmy_db_queries = { path = "../db_queries" }
|
||||||
lemmy_db_schema = { path = "../db_schema" }
|
lemmy_db_schema = { path = "../db_schema" }
|
||||||
reqwest = { version = "0.10.10", features = ["json"] }
|
reqwest = { version = "0.10.10", features = ["json"] }
|
||||||
|
|
|
@ -6,7 +6,7 @@ use diesel::{
|
||||||
r2d2::{ConnectionManager, Pool},
|
r2d2::{ConnectionManager, Pool},
|
||||||
PgConnection,
|
PgConnection,
|
||||||
};
|
};
|
||||||
use lemmy_structs::{comment::*, post::*};
|
use lemmy_api_structs::{comment::*, post::*};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
rate_limit::RateLimit,
|
rate_limit::RateLimit,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::UserOperation;
|
use crate::UserOperation;
|
||||||
use actix::{prelude::*, Recipient};
|
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 lemmy_utils::{CommunityId, ConnectionId, IpAddr, PostId, UserId};
|
||||||
use serde::{Deserialize, Serialize};
|
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