Compare commits

...

38 commits

Author SHA1 Message Date
renovate[bot]
f81ac07c51
Merge e7af9c2387 into d8311a5ff6 2025-04-12 03:22:21 +02:00
June Clementine Strawberry
d8311a5ff6
bump crossbeam-channel bc yanked crate with potential double free
Some checks failed
CI and Artifacts / Test (push) Has been cancelled
CI and Artifacts / Build (push) Has been cancelled
CI and Artifacts / variables (push) Has been cancelled
Documentation and GitHub Pages / Documentation and GitHub Pages (push) Has been cancelled
CI and Artifacts / Docker publish (push) Has been cancelled
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-08 23:38:54 -04:00
June Clementine Strawberry
47f8345457
bump tokio because of RUSTSEC-2025-0023
Some checks are pending
CI and Artifacts / Test (push) Waiting to run
CI and Artifacts / Build (push) Waiting to run
CI and Artifacts / variables (push) Waiting to run
CI and Artifacts / Docker publish (push) Blocked by required conditions
Documentation and GitHub Pages / Documentation and GitHub Pages (push) Waiting to run
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-08 09:05:49 -04:00
June Clementine Strawberry
99868b1661
update new complement flakes
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-06 16:11:35 -04:00
June Clementine Strawberry
d5ad973464
change forbidden_server_names and etc to allow regex patterns for wildcards
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-06 15:25:19 -04:00
June Clementine Strawberry
ff276a42a3
drop unnecessary info log to debug
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-06 13:19:09 -04:00
June Clementine Strawberry
5f8c68ab84
add trace logging for room summaries, use server_in_room instead of exists
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-06 13:17:13 -04:00
June Clementine Strawberry
6578b83bce
parallelise IO of user searching, improve perf, raise max limit to 500
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-05 20:09:22 -04:00
June Clementine Strawberry
3cc92b32ec
bump rust toolchain to 1.86.0
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-05 18:37:13 -04:00
June Clementine Strawberry
9678948daf
use patch of resolv-conf crate to allow no-aaaa resolv.conf option
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-05 18:33:43 -04:00
Jason Volk
500faa8d7f simplify space join rules related
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-05 22:12:33 +00:00
Jason Volk
d6cc447add simplify acl brick-check conditions
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-05 22:12:33 +00:00
June Clementine Strawberry
e28ae8fb4d
downgrade deranged crate
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-05 14:26:00 -04:00
June Clementine Strawberry
c7246662f4
try partially reverting 94b107b42b
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-05 14:07:37 -04:00
June Clementine Strawberry
a212bf7cfc
update default room version to v11
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-05 14:00:40 -04:00
Jason Volk
58b8c7516a extend extract_variant to multiple variants
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-05 02:44:46 +00:00
Jason Volk
bb8320a691 abstract and encapsulate the awkward OptionFuture into Stream pattern
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-05 02:44:46 +00:00
Jason Volk
532dfd004d move core::pdu and core::state_res into core::matrix::
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-05 02:44:46 +00:00
June Clementine Strawberry
4e5b87d0cd
add missing condition for signatures upload failures
Some checks failed
CI and Artifacts / Test (push) Has been cancelled
CI and Artifacts / Build (push) Has been cancelled
CI and Artifacts / variables (push) Has been cancelled
Documentation and GitHub Pages / Documentation and GitHub Pages (push) Has been cancelled
CI and Artifacts / Docker publish (push) Has been cancelled
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-04 11:34:31 -04:00
Jason Volk
00f7745ec4 remove the db pool queue full warning
Some checks are pending
CI and Artifacts / Test (push) Waiting to run
CI and Artifacts / Build (push) Waiting to run
CI and Artifacts / variables (push) Waiting to run
CI and Artifacts / Docker publish (push) Blocked by required conditions
Documentation and GitHub Pages / Documentation and GitHub Pages (push) Waiting to run
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-04 02:59:54 +00:00
Jason Volk
d036394ec7 refactor incoming prev events loop; mitigate large future
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 22:40:40 +00:00
Jason Volk
6a073b4fa4 remove additional unnecessary Arc
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 22:40:40 +00:00
Jason Volk
b7109131e2 further simplify get_missing_events; various log calls
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 22:40:40 +00:00
June Clementine Strawberry
94b107b42b add some debug logging and misc cleanup to keys/signatures/upload
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-03 16:08:18 -04:00
Jason Volk
29d55b8036 move systemd stopping notification point
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 19:38:51 +00:00
Jason Volk
45fd3875c8 move runtime shutdown out of main; gather final stats
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 19:38:51 +00:00
Jason Volk
f9529937ce patch hyper-util due to conflicts with federation resolver hooks
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 19:38:51 +00:00
Jason Volk
0b56204f89 bump additional dependencies
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 19:38:51 +00:00
Jason Volk
58adb6fead upgrade hickory and hyper-util dependencies
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 19:38:51 +00:00
Jason Volk
5d1404e9df fix well-known using the hooked resolver
Signed-off-by: Jason Volk <jason@zemos.net>
2025-04-03 19:38:51 +00:00
June Clementine Strawberry
f14756fb76 leave room locally if room is banned, rescind knocks on deactivation too
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-03 12:21:16 -04:00
June Clementine Strawberry
24be579477 add appservice MSC4190 support
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-03 12:21:16 -04:00
June Clementine Strawberry
0e0b8cc403
fixup+update msc3266, add fed support, parallelise IO
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-03 00:56:37 -04:00
June Clementine Strawberry
1036f8dfa8
default shared history vis on unknown visibilities, drop needless error log
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-02 22:46:01 -04:00
June Clementine Strawberry
74012c5289
significantly improve get_missing_events fed code
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-02 22:44:44 -04:00
June Clementine Strawberry
ea246d91d9
remove pointless and buggy *_visibility in-memory caches
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-02 22:38:47 -04:00
June Clementine Strawberry
1b71b99c51
fix weird issue with acl c2s check
Signed-off-by: June Clementine Strawberry <june@3.dog>
2025-04-02 10:49:38 -04:00
renovate[bot]
e7af9c2387
Update Rust crate cargo_toml to 0.22 2025-03-31 16:29:11 +00:00
132 changed files with 1812 additions and 1255 deletions

495
Cargo.lock generated
View file

@ -142,6 +142,17 @@ dependencies = [
"zstd-safe",
]
[[package]]
name = "async-recursion"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "async-stream"
version = "0.3.6"
@ -221,9 +232,9 @@ dependencies = [
[[package]]
name = "aws-lc-rs"
version = "1.12.6"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01"
checksum = "19b756939cb2f8dc900aa6dcd505e6e2428e9cae7ff7b028c49e3946efa70878"
dependencies = [
"aws-lc-sys",
"zeroize",
@ -231,9 +242,9 @@ dependencies = [
[[package]]
name = "aws-lc-sys"
version = "0.27.1"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f"
checksum = "b9f7720b74ed28ca77f90769a71fd8c637a0137f6fae4ae947e1050229cff57f"
dependencies = [
"bindgen 0.69.5",
"cc",
@ -571,9 +582,9 @@ dependencies = [
[[package]]
name = "cargo_toml"
version = "0.21.0"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fbd1fe9db3ebf71b89060adaf7b0504c2d6a425cf061313099547e382c2e472"
checksum = "02260d489095346e5cafd04dea8e8cb54d1d74fcd759022a9b72986ebe9a1257"
dependencies = [
"serde",
"toml",
@ -652,9 +663,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.34"
version = "4.5.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff"
checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944"
dependencies = [
"clap_builder",
"clap_derive",
@ -662,9 +673,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.34"
version = "4.5.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489"
checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9"
dependencies = [
"anstyle",
"clap_lex",
@ -731,8 +742,8 @@ dependencies = [
"opentelemetry-jaeger",
"opentelemetry_sdk",
"sentry",
"sentry-tower 0.35.0",
"sentry-tracing 0.35.0",
"sentry-tower",
"sentry-tracing",
"tokio",
"tokio-metrics",
"tracing",
@ -905,8 +916,8 @@ dependencies = [
"rustls",
"sd-notify",
"sentry",
"sentry-tower 0.35.0",
"sentry-tracing 0.35.0",
"sentry-tower",
"sentry-tracing",
"serde_json",
"tokio",
"tower 0.5.2",
@ -927,7 +938,7 @@ dependencies = [
"const-str",
"either",
"futures",
"hickory-resolver",
"hickory-resolver 0.25.1",
"http",
"image",
"ipaddress",
@ -1061,6 +1072,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "critical-section"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "crokey"
version = "1.1.1"
@ -1102,9 +1119,9 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
version = "0.5.14"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471"
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
dependencies = [
"crossbeam-utils",
]
@ -1262,9 +1279,9 @@ dependencies = [
[[package]]
name = "deranged"
version = "0.4.1"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058"
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
dependencies = [
"powerfmt",
]
@ -1437,9 +1454,9 @@ dependencies = [
[[package]]
name = "flate2"
version = "1.1.0"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc"
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
dependencies = [
"crc32fast",
"miniz_oxide",
@ -1584,6 +1601,19 @@ dependencies = [
"slab",
]
[[package]]
name = "generator"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd"
dependencies = [
"cfg-if",
"libc",
"log",
"rustversion",
"windows 0.58.0",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@ -1769,6 +1799,34 @@ dependencies = [
"url",
]
[[package]]
name = "hickory-proto"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d844af74f7b799e41c78221be863bade11c430d46042c3b49ca8ae0c6d27287"
dependencies = [
"async-recursion",
"async-trait",
"cfg-if",
"critical-section",
"data-encoding",
"enum-as-inner",
"futures-channel",
"futures-io",
"futures-util",
"idna",
"ipnet",
"once_cell",
"rand 0.9.0",
"ring",
"serde",
"thiserror 2.0.12",
"tinyvec",
"tokio",
"tracing",
"url",
]
[[package]]
name = "hickory-resolver"
version = "0.24.4"
@ -1777,7 +1835,7 @@ checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e"
dependencies = [
"cfg-if",
"futures-util",
"hickory-proto",
"hickory-proto 0.24.4",
"ipconfig",
"lru-cache",
"once_cell",
@ -1790,6 +1848,28 @@ dependencies = [
"tracing",
]
[[package]]
name = "hickory-resolver"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a128410b38d6f931fcc6ca5c107a3b02cabd6c05967841269a4ad65d23c44331"
dependencies = [
"cfg-if",
"futures-util",
"hickory-proto 0.25.1",
"ipconfig",
"moka",
"once_cell",
"parking_lot",
"rand 0.9.0",
"resolv-conf",
"serde",
"smallvec",
"thiserror 2.0.12",
"tokio",
"tracing",
]
[[package]]
name = "hmac"
version = "0.12.1"
@ -1816,7 +1896,7 @@ checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba"
dependencies = [
"cfg-if",
"libc",
"windows",
"windows 0.52.0",
]
[[package]]
@ -1936,9 +2016,9 @@ dependencies = [
[[package]]
name = "hyper-timeout"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793"
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
dependencies = [
"hyper",
"hyper-util",
@ -1949,9 +2029,8 @@ dependencies = [
[[package]]
name = "hyper-util"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba"
version = "0.1.11"
source = "git+https://github.com/girlbossceo/hyper-util?rev=e4ae7628fe4fcdacef9788c4c8415317a4489941#e4ae7628fe4fcdacef9788c4c8415317a4489941"
dependencies = [
"bytes",
"futures-channel",
@ -1959,10 +2038,10 @@ dependencies = [
"http",
"http-body",
"hyper",
"libc",
"pin-project-lite",
"socket2",
"tokio",
"tower 0.4.13",
"tower-service",
"tracing",
]
@ -2256,10 +2335,11 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jobserver"
version = "0.1.32"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
dependencies = [
"getrandom 0.3.2",
"libc",
]
@ -2439,6 +2519,19 @@ dependencies = [
"futures-sink",
]
[[package]]
name = "loom"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "loop9"
version = "0.1.5"
@ -2609,6 +2702,25 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "moka"
version = "0.12.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926"
dependencies = [
"crossbeam-channel",
"crossbeam-epoch",
"crossbeam-utils",
"loom",
"parking_lot",
"portable-atomic",
"rustc_version",
"smallvec",
"tagptr",
"thiserror 1.0.69",
"uuid",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
@ -2773,6 +2885,10 @@ name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
dependencies = [
"critical-section",
"portable-atomic",
]
[[package]]
name = "openssl-probe"
@ -3052,6 +3168,12 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "powerfmt"
version = "0.2.0"
@ -3452,9 +3574,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.12.9"
version = "0.12.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f"
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
dependencies = [
"async-compression",
"base64 0.22.1",
@ -3463,7 +3585,7 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"hickory-resolver",
"hickory-resolver 0.24.4",
"http",
"http-body",
"http-body-util",
@ -3490,6 +3612,7 @@ dependencies = [
"tokio-rustls",
"tokio-socks",
"tokio-util",
"tower 0.5.2",
"tower-service",
"url",
"wasm-bindgen",
@ -3502,8 +3625,7 @@ dependencies = [
[[package]]
name = "resolv-conf"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4"
source = "git+https://github.com/girlbossceo/resolv-conf?rev=200e958941d522a70c5877e3d846f55b5586c68d#200e958941d522a70c5877e3d846f55b5586c68d"
dependencies = [
"hostname",
]
@ -3531,7 +3653,7 @@ dependencies = [
[[package]]
name = "ruma"
version = "0.10.1"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"assign",
"js_int",
@ -3551,7 +3673,7 @@ dependencies = [
[[package]]
name = "ruma-appservice-api"
version = "0.10.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"js_int",
"ruma-common",
@ -3563,7 +3685,7 @@ dependencies = [
[[package]]
name = "ruma-client-api"
version = "0.18.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"as_variant",
"assign",
@ -3586,7 +3708,7 @@ dependencies = [
[[package]]
name = "ruma-common"
version = "0.13.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"as_variant",
"base64 0.22.1",
@ -3618,7 +3740,7 @@ dependencies = [
[[package]]
name = "ruma-events"
version = "0.28.1"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"as_variant",
"indexmap 2.8.0",
@ -3643,7 +3765,7 @@ dependencies = [
[[package]]
name = "ruma-federation-api"
version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"bytes",
"headers",
@ -3665,7 +3787,7 @@ dependencies = [
[[package]]
name = "ruma-identifiers-validation"
version = "0.9.5"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"js_int",
"thiserror 2.0.12",
@ -3674,7 +3796,7 @@ dependencies = [
[[package]]
name = "ruma-identity-service-api"
version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"js_int",
"ruma-common",
@ -3684,7 +3806,7 @@ dependencies = [
[[package]]
name = "ruma-macros"
version = "0.13.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"cfg-if",
"proc-macro-crate",
@ -3699,7 +3821,7 @@ dependencies = [
[[package]]
name = "ruma-push-gateway-api"
version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"js_int",
"ruma-common",
@ -3711,7 +3833,7 @@ dependencies = [
[[package]]
name = "ruma-signatures"
version = "0.15.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=d197318a2507d38ffe6ee524d0d52728ca72538a#d197318a2507d38ffe6ee524d0d52728ca72538a"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4"
dependencies = [
"base64 0.22.1",
"ed25519-dalek",
@ -3893,6 +4015,12 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -3939,21 +4067,21 @@ checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
[[package]]
name = "sentry"
version = "0.36.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a7332159e544e34db06b251b1eda5e546bd90285c3f58d9c8ff8450b484e0da"
checksum = "255914a8e53822abd946e2ce8baa41d4cded6b8e938913b7f7b9da5b7ab44335"
dependencies = [
"httpdate",
"reqwest",
"rustls",
"sentry-backtrace",
"sentry-contexts",
"sentry-core 0.36.0",
"sentry-core",
"sentry-debug-images",
"sentry-log",
"sentry-panic",
"sentry-tower 0.36.0",
"sentry-tracing 0.36.0",
"sentry-tower",
"sentry-tracing",
"tokio",
"ureq",
"webpki-roots",
@ -3961,107 +4089,83 @@ dependencies = [
[[package]]
name = "sentry-backtrace"
version = "0.36.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "565ec31ad37bab8e6d9f289f34913ed8768347b133706192f10606dabd5c6bc4"
checksum = "00293cd332a859961f24fd69258f7e92af736feaeb91020cff84dac4188a4302"
dependencies = [
"backtrace",
"once_cell",
"regex",
"sentry-core 0.36.0",
"sentry-core",
]
[[package]]
name = "sentry-contexts"
version = "0.36.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e860275f25f27e8c0c7726ce116c7d5c928c5bba2ee73306e52b20a752298ea6"
checksum = "961990f9caa76476c481de130ada05614cd7f5aa70fb57c2142f0e09ad3fb2aa"
dependencies = [
"hostname",
"libc",
"os_info",
"rustc_version",
"sentry-core 0.36.0",
"sentry-core",
"uname",
]
[[package]]
name = "sentry-core"
version = "0.35.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9f8b6dcd4fbae1e3e22b447f32670360b27e31b62ab040f7fb04e0f80c04d92"
checksum = "1a6409d845707d82415c800290a5d63be5e3df3c2e417b0997c60531dfbd35ef"
dependencies = [
"once_cell",
"rand 0.8.5",
"sentry-types 0.35.0",
"serde",
"serde_json",
]
[[package]]
name = "sentry-core"
version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "653942e6141f16651273159f4b8b1eaeedf37a7554c00cd798953e64b8a9bf72"
dependencies = [
"once_cell",
"rand 0.8.5",
"sentry-types 0.36.0",
"sentry-types",
"serde",
"serde_json",
]
[[package]]
name = "sentry-debug-images"
version = "0.36.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60bc2154e6df59beed0ac13d58f8dfaf5ad20a88548a53e29e4d92e8e835c2"
checksum = "71ab5df4f3b64760508edfe0ba4290feab5acbbda7566a79d72673065888e5cc"
dependencies = [
"findshlibs",
"once_cell",
"sentry-core 0.36.0",
"sentry-core",
]
[[package]]
name = "sentry-log"
version = "0.36.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c96d796cba1b3a0793e7f53edc420c61f9419fba8fb34ad5519f5c7d01af6b2"
checksum = "693841da8dfb693af29105edfbea1d91348a13d23dd0a5d03761eedb9e450c46"
dependencies = [
"log",
"sentry-core 0.36.0",
"sentry-core",
]
[[package]]
name = "sentry-panic"
version = "0.36.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "105e3a956c8aa9dab1e4087b1657b03271bfc49d838c6ae9bfc7c58c802fd0ef"
checksum = "609b1a12340495ce17baeec9e08ff8ed423c337c1a84dffae36a178c783623f3"
dependencies = [
"sentry-backtrace",
"sentry-core 0.36.0",
"sentry-core",
]
[[package]]
name = "sentry-tower"
version = "0.35.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcdaf9b1939589476bd57751d12a9653bbfe356610fc476d03d7683189183ab7"
dependencies = [
"sentry-core 0.35.0",
"tower-layer",
"tower-service",
]
[[package]]
name = "sentry-tower"
version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "082f781dfc504d984e16d99f8dbf94d6ee4762dd0fc28de25713d0f900a8164d"
checksum = "4b98005537e38ee3bc10e7d36e7febe9b8e573d03f2ddd85fcdf05d21f9abd6d"
dependencies = [
"http",
"pin-project",
"sentry-core 0.36.0",
"sentry-core",
"tower-layer",
"tower-service",
"url",
@ -4069,49 +4173,21 @@ dependencies = [
[[package]]
name = "sentry-tracing"
version = "0.35.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "263f73c757ed7915d3e1e34625eae18cad498a95b4261603d4ce3f87b159a6f0"
dependencies = [
"sentry-core 0.35.0",
"tracing-core",
"tracing-subscriber",
]
[[package]]
name = "sentry-tracing"
version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e75c831b4d8b34a5aec1f65f67c5d46a26c7c5d3c7abd8b5ef430796900cf8"
checksum = "49f4e86402d5c50239dc7d8fd3f6d5e048221d5fcb4e026d8d50ab57fe4644cb"
dependencies = [
"sentry-backtrace",
"sentry-core 0.36.0",
"sentry-core",
"tracing-core",
"tracing-subscriber",
]
[[package]]
name = "sentry-types"
version = "0.35.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a71ed3a389948a6a6d92b98e997a2723ca22f09660c5a7b7388ecd509a70a527"
dependencies = [
"debugid",
"hex",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror 1.0.69",
"time",
"url",
"uuid",
]
[[package]]
name = "sentry-types"
version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d4203359e60724aa05cf2385aaf5d4f147e837185d7dd2b9ccf1ee77f4420c8"
checksum = "3d3f117b8755dbede8260952de2aeb029e20f432e72634e8969af34324591631"
dependencies = [
"debugid",
"hex",
@ -4464,6 +4540,12 @@ dependencies = [
"version-compare",
]
[[package]]
name = "tagptr"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
[[package]]
name = "target-lexicon"
version = "0.12.16"
@ -4676,9 +4758,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.44.1"
version = "1.44.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
dependencies = [
"backtrace",
"bytes",
@ -5367,7 +5449,17 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [
"windows-core",
"windows-core 0.52.0",
"windows-targets 0.52.6",
]
[[package]]
name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
dependencies = [
"windows-core 0.58.0",
"windows-targets 0.52.6",
]
@ -5381,16 +5473,57 @@ dependencies = [
]
[[package]]
name = "windows-registry"
version = "0.2.0"
name = "windows-core"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
dependencies = [
"windows-result",
"windows-strings",
"windows-implement",
"windows-interface",
"windows-result 0.2.0",
"windows-strings 0.1.0",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-implement"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-registry"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
dependencies = [
"windows-result 0.3.2",
"windows-strings 0.3.1",
"windows-targets 0.53.0",
]
[[package]]
name = "windows-result"
version = "0.2.0"
@ -5400,16 +5533,34 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-result"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result",
"windows-result 0.2.0",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-strings"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
@ -5461,13 +5612,29 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
dependencies = [
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
"windows_i686_gnullvm 0.53.0",
"windows_i686_msvc 0.53.0",
"windows_x86_64_gnu 0.53.0",
"windows_x86_64_gnullvm 0.53.0",
"windows_x86_64_msvc 0.53.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
@ -5480,6 +5647,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
@ -5492,6 +5665,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
@ -5504,12 +5683,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
@ -5522,6 +5713,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
@ -5534,6 +5731,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
@ -5546,6 +5749,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
@ -5558,6 +5767,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.7.4"

View file

@ -20,7 +20,7 @@ license = "Apache-2.0"
# See also `rust-toolchain.toml`
readme = "README.md"
repository = "https://github.com/girlbossceo/conduwuit"
rust-version = "1.85.0"
rust-version = "1.86.0"
version = "0.5.0"
[workspace.metadata.crane]
@ -51,7 +51,7 @@ version = "0.6.2"
version = "0.2.9"
[workspace.dependencies.cargo_toml]
version = "0.21"
version = "0.22"
default-features = false
features = ["features"]
@ -141,12 +141,12 @@ features = [
]
[workspace.dependencies.rustls]
version = "0.23.19"
version = "0.23.25"
default-features = false
features = ["aws_lc_rs"]
[workspace.dependencies.reqwest]
version = "0.12.9"
version = "0.12.15"
default-features = false
features = [
"rustls-tls-native-roots",
@ -204,7 +204,7 @@ features = [
# logging
[workspace.dependencies.log]
version = "0.4.22"
version = "0.4.27"
default-features = false
[workspace.dependencies.tracing]
version = "0.1.41"
@ -224,7 +224,7 @@ default-features = false
# used for conduwuit's CLI and admin room command parsing
[workspace.dependencies.clap]
version = "4.5.23"
version = "4.5.35"
default-features = false
features = [
"derive",
@ -242,7 +242,7 @@ default-features = false
features = ["std", "async-await"]
[workspace.dependencies.tokio]
version = "1.44.1"
version = "1.44.2"
default-features = false
features = [
"fs",
@ -284,8 +284,7 @@ features = [
]
[workspace.dependencies.hyper-util]
# hyper-util >=0.1.9 seems to have DNS issues
version = "=0.1.8"
version = "0.1.11"
default-features = false
features = [
"server-auto",
@ -306,8 +305,13 @@ default-features = false
features = ["env", "toml"]
[workspace.dependencies.hickory-resolver]
version = "0.24.2"
version = "0.25.1"
default-features = false
features = [
"serde",
"system-config",
"tokio",
]
# Used for conduwuit::Error type
[workspace.dependencies.thiserror]
@ -316,7 +320,7 @@ default-features = false
# Used when hashing the state
[workspace.dependencies.ring]
version = "0.17.8"
version = "0.17.14"
default-features = false
# Used to make working with iterators easier, was already a transitive depdendency
@ -346,7 +350,7 @@ version = "0.1.2"
[workspace.dependencies.ruma]
git = "https://github.com/girlbossceo/ruwuma"
#branch = "conduwuit-changes"
rev = "d197318a2507d38ffe6ee524d0d52728ca72538a"
rev = "920148dca1076454ca0ca5d43b5ce1aa708381d4"
features = [
"compat",
"rand",
@ -423,7 +427,7 @@ features = ["rt-tokio"]
# optional sentry metrics for crash/panic reporting
[workspace.dependencies.sentry]
version = "0.36.0"
version = "0.37.0"
default-features = false
features = [
"backtrace",
@ -439,9 +443,9 @@ features = [
]
[workspace.dependencies.sentry-tracing]
version = "0.35.0"
version = "0.37.0"
[workspace.dependencies.sentry-tower]
version = "0.35.0"
version = "0.37.0"
# jemalloc usage
[workspace.dependencies.tikv-jemalloc-sys]
@ -475,7 +479,7 @@ default-features = false
features = ["resource"]
[workspace.dependencies.sd-notify]
version = "0.4.3"
version = "0.4.5"
default-features = false
[workspace.dependencies.hardened_malloc-rs]
@ -492,7 +496,7 @@ version = "0.4.3"
default-features = false
[workspace.dependencies.termimad]
version = "0.31.1"
version = "0.31.2"
default-features = false
[workspace.dependencies.checked_ops]
@ -566,10 +570,23 @@ rev = "fe4aebeeaae435af60087ddd56b573a2e0be671d"
git = "https://github.com/girlbossceo/async-channel"
rev = "92e5e74063bf2a3b10414bcc8a0d68b235644280"
# adds affinity masks for selecting more than one core at a time
[patch.crates-io.core_affinity]
git = "https://github.com/girlbossceo/core_affinity_rs"
rev = "9c8e51510c35077df888ee72a36b4b05637147da"
# reverts hyperium#148 conflicting with our delicate federation resolver hooks
[patch.crates-io.hyper-util]
git = "https://github.com/girlbossceo/hyper-util"
rev = "e4ae7628fe4fcdacef9788c4c8415317a4489941"
# allows no-aaaa option in resolv.conf
# bumps rust edition and toolchain to 1.86.0 and 2024
# use sat_add on line number errors
[patch.crates-io.resolv-conf]
git = "https://github.com/girlbossceo/resolv-conf"
rev = "200e958941d522a70c5877e3d846f55b5586c68d"
#
# Our crates
#

View file

@ -195,14 +195,6 @@
#
#servernameevent_data_cache_capacity = varies by system
# This item is undocumented. Please contribute documentation for it.
#
#server_visibility_cache_capacity = varies by system
# This item is undocumented. Please contribute documentation for it.
#
#user_visibility_cache_capacity = varies by system
# This item is undocumented. Please contribute documentation for it.
#
#stateinfo_cache_capacity = varies by system
@ -535,9 +527,9 @@
# Default room version conduwuit will create rooms with.
#
# Per spec, room version 10 is the default.
# Per spec, room version 11 is the default.
#
#default_room_version = 10
#default_room_version = 11
# This item is undocumented. Please contribute documentation for it.
#
@ -602,7 +594,7 @@
# Currently, conduwuit doesn't support inbound batched key requests, so
# this list should only contain other Synapse servers.
#
# example: ["matrix.org", "envs.net", "tchncs.de"]
# example: ["matrix.org", "tchncs.de"]
#
#trusted_servers = ["matrix.org"]
@ -1194,13 +1186,16 @@
#
#prune_missing_media = false
# Vector list of servers that conduwuit will refuse to download remote
# media from.
# Vector list of regex patterns of server names that conduwuit will refuse
# to download remote media from.
#
# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
#
#prevent_media_downloads_from = []
# List of forbidden server names that we will block incoming AND outgoing
# federation with, and block client room joins / remote user invites.
# List of forbidden server names via regex patterns that we will block
# incoming AND outgoing federation with, and block client room joins /
# remote user invites.
#
# This check is applied on the room ID, room alias, sender server name,
# sender user's server name, inbound federation X-Matrix origin, and
@ -1208,11 +1203,15 @@
#
# Basically "global" ACLs.
#
# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
#
#forbidden_remote_server_names = []
# List of forbidden server names that we will block all outgoing federated
# room directory requests for. Useful for preventing our users from
# wandering into bad servers or spaces.
# List of forbidden server names via regex patterns that we will block all
# outgoing federated room directory requests for. Useful for preventing
# our users from wandering into bad servers or spaces.
#
# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
#
#forbidden_remote_room_directory_server_names = []
@ -1323,7 +1322,7 @@
# used, and startup as warnings if any room aliases in your database have
# a forbidden room alias/ID.
#
# example: ["19dollarfortnitecards", "b[4a]droom"]
# example: ["19dollarfortnitecards", "b[4a]droom", "badphrase"]
#
#forbidden_alias_names = []
@ -1336,7 +1335,7 @@
# startup as warnings if any local users in your database have a forbidden
# username.
#
# example: ["administrator", "b[a4]dusernam[3e]"]
# example: ["administrator", "b[a4]dusernam[3e]", "badphrase"]
#
#forbidden_usernames = []

View file

@ -26,7 +26,7 @@
file = ./rust-toolchain.toml;
# See also `rust-toolchain.toml`
sha256 = "sha256-AJ6LX/Q/Er9kS15bn9iflkUwcgYqRQxiOIL2ToVAXaU=";
sha256 = "sha256-X/4ZBHO3iW0fOenQ3foEvscgAPJYl2abspaBThDOukI=";
};
mkScope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: {

View file

@ -9,7 +9,7 @@
# If you're having trouble making the relevant changes, bug a maintainer.
[toolchain]
channel = "1.85.0"
channel = "1.86.0"
profile = "minimal"
components = [
# For rust-analyzer

View file

@ -6,7 +6,9 @@ use std::{
};
use conduwuit::{
Error, PduEvent, PduId, RawPduId, Result, debug_error, err, info, trace, utils,
Error, Result, debug_error, err, info,
matrix::pdu::{PduEvent, PduId, RawPduId},
trace, utils,
utils::{
stream::{IterStream, ReadyExt},
string::EMPTY,

View file

@ -2,7 +2,8 @@ use std::{collections::BTreeMap, fmt::Write as _};
use api::client::{full_user_deactivate, join_room_by_id_helper, leave_room};
use conduwuit::{
PduBuilder, Result, debug, debug_warn, error, info, is_equal_to,
Result, debug, debug_warn, error, info, is_equal_to,
matrix::pdu::PduBuilder,
utils::{self, ReadyExt},
warn,
};

View file

@ -3,10 +3,13 @@ use std::fmt::Write;
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{
Err, Error, PduBuilder, Result, debug_info, err, error, info, is_equal_to, utils,
Err, Error, Result, debug_info, err, error, info, is_equal_to,
matrix::pdu::PduBuilder,
utils,
utils::{ReadyExt, stream::BroadbandExt},
warn,
};
use conduwuit_service::Services;
use futures::{FutureExt, StreamExt};
use register::RegistrationKind;
use ruma::{
@ -30,7 +33,6 @@ use ruma::{
},
push,
};
use service::Services;
use super::{DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH, join_room_by_id_helper};
use crate::Ruma;
@ -318,14 +320,14 @@ pub(crate) async fn register_route(
// Success!
},
| _ => match body.json_body {
| Some(json) => {
| Some(ref json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services.uiaa.create(
&UserId::parse_with_server_name("", services.globals.server_name())
.unwrap(),
"".into(),
&uiaainfo,
&json,
json,
);
return Err(Error::Uiaa(uiaainfo));
},
@ -373,8 +375,12 @@ pub(crate) async fn register_route(
)
.await?;
// Inhibit login does not work for guests
if !is_guest && body.inhibit_login {
if (!is_guest && body.inhibit_login)
|| body
.appservice_info
.as_ref()
.is_some_and(|appservice| appservice.registration.device_management)
{
return Ok(register::v3::Response {
access_token: None,
user_id,

View file

@ -1,5 +1,6 @@
use axum::extract::State;
use conduwuit::{Err, err};
use conduwuit::{Err, Result, err};
use conduwuit_service::Services;
use ruma::{
RoomId, UserId,
api::client::config::{
@ -15,7 +16,7 @@ use ruma::{
use serde::Deserialize;
use serde_json::{json, value::RawValue as RawJsonValue};
use crate::{Result, Ruma, service::Services};
use crate::Ruma;
/// # `PUT /_matrix/client/r0/user/{userId}/account_data/{type}`
///

View file

@ -1,12 +1,12 @@
use axum::extract::State;
use conduwuit::{Err, Result, debug};
use conduwuit_service::Services;
use futures::StreamExt;
use rand::seq::SliceRandom;
use ruma::{
OwnedServerName, RoomAliasId, RoomId,
api::client::alias::{create_alias, delete_alias, get_alias},
};
use service::Services;
use crate::Ruma;

View file

@ -22,7 +22,13 @@ pub(crate) async fn appservice_ping(
)));
}
if appservice_info.registration.url.is_none() {
if appservice_info.registration.url.is_none()
|| appservice_info
.registration
.url
.as_ref()
.is_some_and(|url| url.is_empty() || url == "null")
{
return Err!(Request(UrlNotSet(
"Appservice does not have a URL set, there is nothing to ping."
)));

View file

@ -1,7 +1,7 @@
use std::cmp::Ordering;
use axum::extract::State;
use conduwuit::{Err, err};
use conduwuit::{Err, Result, err};
use ruma::{
UInt,
api::client::backup::{
@ -13,7 +13,7 @@ use ruma::{
},
};
use crate::{Result, Ruma};
use crate::Ruma;
/// # `POST /_matrix/client/r0/room_keys/version`
///

View file

@ -1,18 +1,20 @@
use axum::extract::State;
use conduwuit::{
Err, PduEvent, Result, at, debug_warn, err, ref_at,
Err, Result, at, debug_warn, err,
matrix::pdu::PduEvent,
ref_at,
utils::{
IterStream,
future::TryExtExt,
stream::{BroadbandExt, ReadyExt, TryIgnore, WidebandExt},
},
};
use conduwuit_service::rooms::{lazy_loading, lazy_loading::Options, short::ShortStateKey};
use futures::{
FutureExt, StreamExt, TryFutureExt, TryStreamExt,
future::{OptionFuture, join, join3, try_join3},
};
use ruma::{OwnedEventId, UserId, api::client::context::get_context, events::StateEventType};
use service::rooms::{lazy_loading, lazy_loading::Options, short::ShortStateKey};
use crate::{
Ruma,

View file

@ -1,9 +1,9 @@
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{Err, err};
use conduwuit::{Err, Error, Result, debug, err, utils};
use futures::StreamExt;
use ruma::{
MilliSecondsSinceUnixEpoch,
MilliSecondsSinceUnixEpoch, OwnedDeviceId,
api::client::{
device::{self, delete_device, delete_devices, get_device, get_devices, update_device},
error::ErrorKind,
@ -12,7 +12,7 @@ use ruma::{
};
use super::SESSION_ID_LENGTH;
use crate::{Error, Result, Ruma, utils};
use crate::{Ruma, client::DEVICE_ID_LENGTH};
/// # `GET /_matrix/client/r0/devices`
///
@ -59,26 +59,58 @@ pub(crate) async fn update_device_route(
InsecureClientIp(client): InsecureClientIp,
body: Ruma<update_device::v3::Request>,
) -> Result<update_device::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let sender_user = body.sender_user();
let appservice = body.appservice_info.as_ref();
let mut device = services
match services
.users
.get_device_metadata(sender_user, &body.device_id)
.await
.map_err(|_| err!(Request(NotFound("Device not found."))))?;
{
| Ok(mut device) => {
device.display_name.clone_from(&body.display_name);
device.last_seen_ip.clone_from(&Some(client.to_string()));
device
.last_seen_ts
.clone_from(&Some(MilliSecondsSinceUnixEpoch::now()));
device.display_name.clone_from(&body.display_name);
device.last_seen_ip.clone_from(&Some(client.to_string()));
device
.last_seen_ts
.clone_from(&Some(MilliSecondsSinceUnixEpoch::now()));
services
.users
.update_device_metadata(sender_user, &body.device_id, &device)
.await?;
services
.users
.update_device_metadata(sender_user, &body.device_id, &device)
.await?;
Ok(update_device::v3::Response {})
},
| Err(_) => {
let Some(appservice) = appservice else {
return Err!(Request(NotFound("Device not found.")));
};
if !appservice.registration.device_management {
return Err!(Request(NotFound("Device not found.")));
}
Ok(update_device::v3::Response {})
debug!(
"Creating new device for {sender_user} from appservice {} as MSC4190 is enabled \
and device ID does not exist",
appservice.registration.id
);
let device_id = OwnedDeviceId::from(utils::random_string(DEVICE_ID_LENGTH));
services
.users
.create_device(
sender_user,
&device_id,
&appservice.registration.as_token,
None,
Some(client.to_string()),
)
.await?;
return Ok(update_device::v3::Response {});
},
}
}
/// # `DELETE /_matrix/client/r0/devices/{deviceId}`
@ -95,8 +127,21 @@ pub(crate) async fn delete_device_route(
State(services): State<crate::State>,
body: Ruma<delete_device::v3::Request>,
) -> Result<delete_device::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let sender_device = body.sender_device.as_ref().expect("user is authenticated");
let (sender_user, sender_device) = body.sender();
let appservice = body.appservice_info.as_ref();
if appservice.is_some_and(|appservice| appservice.registration.device_management) {
debug!(
"Skipping UIAA for {sender_user} as this is from an appservice and MSC4190 is \
enabled"
);
services
.users
.remove_device(sender_user, &body.device_id)
.await;
return Ok(delete_device::v3::Response {});
}
// UIAA
let mut uiaainfo = UiaaInfo {
@ -120,11 +165,11 @@ pub(crate) async fn delete_device_route(
// Success!
},
| _ => match body.json_body {
| Some(json) => {
| Some(ref json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
.create(sender_user, sender_device, &uiaainfo, json);
return Err!(Uiaa(uiaainfo));
},
@ -142,11 +187,12 @@ pub(crate) async fn delete_device_route(
Ok(delete_device::v3::Response {})
}
/// # `PUT /_matrix/client/r0/devices/{deviceId}`
/// # `POST /_matrix/client/v3/delete_devices`
///
/// Deletes the given device.
/// Deletes the given list of devices.
///
/// - Requires UIAA to verify user password
/// - Requires UIAA to verify user password unless from an appservice with
/// MSC4190 enabled.
///
/// For each device:
/// - Invalidates access token
@ -158,8 +204,20 @@ pub(crate) async fn delete_devices_route(
State(services): State<crate::State>,
body: Ruma<delete_devices::v3::Request>,
) -> Result<delete_devices::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let sender_device = body.sender_device.as_ref().expect("user is authenticated");
let (sender_user, sender_device) = body.sender();
let appservice = body.appservice_info.as_ref();
if appservice.is_some_and(|appservice| appservice.registration.device_management) {
debug!(
"Skipping UIAA for {sender_user} as this is from an appservice and MSC4190 is \
enabled"
);
for device_id in &body.devices {
services.users.remove_device(sender_user, device_id).await;
}
return Ok(delete_devices::v3::Response {});
}
// UIAA
let mut uiaainfo = UiaaInfo {
@ -183,11 +241,11 @@ pub(crate) async fn delete_devices_route(
// Success!
},
| _ => match body.json_body {
| Some(json) => {
| Some(ref json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
.create(sender_user, sender_device, &uiaainfo, json);
return Err(Error::Uiaa(uiaainfo));
},

View file

@ -9,6 +9,7 @@ use conduwuit::{
stream::{ReadyExt, WidebandExt},
},
};
use conduwuit_service::Services;
use futures::{
FutureExt, StreamExt, TryFutureExt,
future::{join, join4, join5},
@ -35,7 +36,6 @@ use ruma::{
},
uint,
};
use service::Services;
use crate::Ruma;
@ -52,10 +52,13 @@ pub(crate) async fn get_public_rooms_filtered_route(
) -> Result<get_public_rooms_filtered::v3::Response> {
if let Some(server) = &body.server {
if services
.server
.config
.forbidden_remote_room_directory_server_names
.contains(server)
.is_match(server.host())
|| services
.config
.forbidden_remote_server_names
.is_match(server.host())
{
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
}
@ -90,10 +93,13 @@ pub(crate) async fn get_public_rooms_route(
) -> Result<get_public_rooms::v3::Response> {
if let Some(server) = &body.server {
if services
.server
.config
.forbidden_remote_room_directory_server_names
.contains(server)
.is_match(server.host())
|| services
.config
.forbidden_remote_server_names
.is_match(server.host())
{
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
}

View file

@ -1,8 +1,8 @@
use axum::extract::State;
use conduwuit::err;
use conduwuit::{Result, err};
use ruma::api::client::filter::{create_filter, get_filter};
use crate::{Result, Ruma};
use crate::Ruma;
/// # `GET /_matrix/client/r0/user/{userId}/filter/{filterId}`
///

View file

@ -1,7 +1,8 @@
use std::collections::{BTreeMap, HashMap, HashSet};
use axum::extract::State;
use conduwuit::{Err, Error, Result, debug, debug_warn, err, info, result::NotFound, utils};
use conduwuit::{Err, Error, Result, debug, debug_warn, err, result::NotFound, utils};
use conduwuit_service::{Services, users::parse_master_key};
use futures::{StreamExt, stream::FuturesUnordered};
use ruma::{
OneTimeKeyAlgorithm, OwnedDeviceId, OwnedUserId, UserId,
@ -9,7 +10,8 @@ use ruma::{
client::{
error::ErrorKind,
keys::{
claim_keys, get_key_changes, get_keys, upload_keys, upload_signatures,
claim_keys, get_key_changes, get_keys, upload_keys,
upload_signatures::{self},
upload_signing_keys,
},
uiaa::{AuthFlow, AuthType, UiaaInfo},
@ -22,10 +24,7 @@ use ruma::{
use serde_json::json;
use super::SESSION_ID_LENGTH;
use crate::{
Ruma,
service::{Services, users::parse_master_key},
};
use crate::Ruma;
/// # `POST /_matrix/client/r0/keys/upload`
///
@ -178,7 +177,7 @@ pub(crate) async fn upload_signing_keys_route(
body.master_key.as_ref(),
)
.await
.inspect_err(|e| info!(?e))
.inspect_err(|e| debug!(?e))
{
| Ok(exists) => {
if let Some(result) = exists {
@ -308,53 +307,60 @@ async fn check_for_new_keys(
/// # `POST /_matrix/client/r0/keys/signatures/upload`
///
/// Uploads end-to-end key signatures from the sender user.
///
/// TODO: clean this timo-code up more and integrate failures. tried to improve
/// it a bit to stop exploding the entire request on bad sigs, but needs way
/// more work.
pub(crate) async fn upload_signatures_route(
State(services): State<crate::State>,
body: Ruma<upload_signatures::v3::Request>,
) -> Result<upload_signatures::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
if body.signed_keys.is_empty() {
debug!("Empty signed_keys sent in key signature upload");
return Ok(upload_signatures::v3::Response::new());
}
let sender_user = body.sender_user();
for (user_id, keys) in &body.signed_keys {
for (key_id, key) in keys {
let key = serde_json::to_value(key)
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid key JSON"))?;
let Ok(key) = serde_json::to_value(key)
.inspect_err(|e| debug_warn!(?key_id, "Invalid \"key\" JSON: {e}"))
else {
continue;
};
for signature in key
.get("signatures")
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Missing signatures field."))?
.get(sender_user.to_string())
.ok_or(Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid user in signatures field.",
))?
.as_object()
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Invalid signature."))?
.clone()
{
// Signature validation?
let signature = (
signature.0,
signature
.1
.as_str()
.ok_or(Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid signature value.",
))?
.to_owned(),
);
let Some(signatures) = key.get("signatures") else {
continue;
};
services
let Some(sender_user_val) = signatures.get(sender_user.to_string()) else {
continue;
};
let Some(sender_user_object) = sender_user_val.as_object() else {
continue;
};
for (signature, val) in sender_user_object.clone() {
let Some(val) = val.as_str().map(ToOwned::to_owned) else {
continue;
};
let signature = (signature, val);
if let Err(_e) = services
.users
.sign_key(user_id, key_id, signature, sender_user)
.await?;
.await
.inspect_err(|e| debug_warn!("{e}"))
{
continue;
}
}
}
}
Ok(upload_signatures::v3::Response {
failures: BTreeMap::new(), // TODO: integrate
})
Ok(upload_signatures::v3::Response { failures: BTreeMap::new() })
}
/// # `POST /_matrix/client/r0/keys/changes`

View file

@ -9,13 +9,25 @@ use std::{
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{
Err, PduEvent, Result, StateKey, at, debug, debug_info, debug_warn, err, error, info,
pdu::{PduBuilder, gen_event_id_canonical_json},
Err, Result, at, debug, debug_info, debug_warn, err, error, info,
matrix::{
StateKey,
pdu::{PduBuilder, PduEvent, gen_event_id, gen_event_id_canonical_json},
state_res,
},
result::{FlatOk, NotFound},
state_res, trace,
trace,
utils::{self, IterStream, ReadyExt, shuffle},
warn,
};
use conduwuit_service::{
Services,
appservice::RegistrationInfo,
rooms::{
state::RoomMutexGuard,
state_compressor::{CompressedState, HashSetCompressStateEvent},
},
};
use futures::{FutureExt, StreamExt, TryFutureExt, future::join4, join};
use ruma::{
CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, OwnedRoomId, OwnedServerName,
@ -44,15 +56,6 @@ use ruma::{
},
},
};
use service::{
Services,
appservice::RegistrationInfo,
pdu::gen_event_id,
rooms::{
state::RoomMutexGuard,
state_compressor::{CompressedState, HashSetCompressStateEvent},
},
};
use crate::{Ruma, client::full_user_deactivate};
@ -76,10 +79,9 @@ async fn banned_room_check(
if let Some(room_id) = room_id {
if services.rooms.metadata.is_banned(room_id).await
|| services
.server
.config
.forbidden_remote_server_names
.contains(&room_id.server_name().unwrap().to_owned())
.is_match(room_id.server_name().unwrap().host())
{
warn!(
"User {user_id} who is not an admin attempted to send an invite for or \
@ -117,10 +119,9 @@ async fn banned_room_check(
}
} else if let Some(server_name) = server_name {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server_name.to_owned())
.is_match(server_name.host())
{
warn!(
"User {user_id} who is not an admin tried joining a room which has the server \
@ -475,9 +476,9 @@ pub(crate) async fn leave_room_route(
State(services): State<crate::State>,
body: Ruma<leave_room::v3::Request>,
) -> Result<leave_room::v3::Response> {
leave_room(&services, body.sender_user(), &body.room_id, body.reason.clone()).await?;
Ok(leave_room::v3::Response::new())
leave_room(&services, body.sender_user(), &body.room_id, body.reason.clone())
.await
.map(|()| leave_room::v3::Response::new())
}
/// # `POST /_matrix/client/r0/rooms/{roomId}/invite`
@ -1763,8 +1764,8 @@ pub(crate) async fn invite_helper(
Ok(())
}
// Make a user leave all their joined rooms, forgets all rooms, and ignores
// errors
// Make a user leave all their joined rooms, rescinds knocks, forgets all rooms,
// and ignores errors
pub async fn leave_all_rooms(services: &Services, user_id: &UserId) {
let rooms_joined = services
.rooms
@ -1778,7 +1779,17 @@ pub async fn leave_all_rooms(services: &Services, user_id: &UserId) {
.rooms_invited(user_id)
.map(|(r, _)| r);
let all_rooms: Vec<_> = rooms_joined.chain(rooms_invited).collect().await;
let rooms_knocked = services
.rooms
.state_cache
.rooms_knocked(user_id)
.map(|(r, _)| r);
let all_rooms: Vec<_> = rooms_joined
.chain(rooms_invited)
.chain(rooms_knocked)
.collect()
.await;
for room_id in all_rooms {
// ignore errors
@ -1795,7 +1806,40 @@ pub async fn leave_room(
user_id: &UserId,
room_id: &RoomId,
reason: Option<String>,
) -> Result<()> {
) -> Result {
let default_member_content = RoomMemberEventContent {
membership: MembershipState::Leave,
reason: reason.clone(),
join_authorized_via_users_server: None,
is_direct: None,
avatar_url: None,
displayname: None,
third_party_invite: None,
blurhash: None,
};
if services.rooms.metadata.is_banned(room_id).await
|| services.rooms.metadata.is_disabled(room_id).await
{
// the room is banned/disabled, the room must be rejected locally since we
// cant/dont want to federate with this server
services
.rooms
.state_cache
.update_membership(
room_id,
user_id,
default_member_content,
user_id,
None,
None,
true,
)
.await?;
return Ok(());
}
// Ask a remote server if we don't have this room and are not knocking on it
if !services
.rooms
@ -1828,7 +1872,7 @@ pub async fn leave_room(
.update_membership(
room_id,
user_id,
RoomMemberEventContent::new(MembershipState::Leave),
default_member_content,
user_id,
last_state,
None,
@ -1848,26 +1892,23 @@ pub async fn leave_room(
)
.await
else {
// Fix for broken rooms
warn!(
debug_warn!(
"Trying to leave a room you are not a member of, marking room as left locally."
);
services
return services
.rooms
.state_cache
.update_membership(
room_id,
user_id,
RoomMemberEventContent::new(MembershipState::Leave),
default_member_content,
user_id,
None,
None,
true,
)
.await?;
return Ok(());
.await;
};
services
@ -1897,7 +1938,7 @@ async fn remote_leave_room(
room_id: &RoomId,
) -> Result<()> {
let mut make_leave_response_and_server =
Err!(BadServerResponse("No server available to assist in leaving."));
Err!(BadServerResponse("No remote server available to assist in leaving {room_id}."));
let mut servers: HashSet<OwnedServerName> = services
.rooms
@ -1977,20 +2018,25 @@ async fn remote_leave_room(
let (make_leave_response, remote_server) = make_leave_response_and_server?;
let Some(room_version_id) = make_leave_response.room_version else {
return Err!(BadServerResponse("Remote room version is not supported by conduwuit"));
return Err!(BadServerResponse(warn!(
"No room version was returned by {remote_server} for {room_id}, room version is \
likely not supported by conduwuit"
)));
};
if !services.server.supported_room_version(&room_version_id) {
return Err!(BadServerResponse(
"Remote room version {room_version_id} is not supported by conduwuit"
));
return Err!(BadServerResponse(warn!(
"Remote room version {room_version_id} for {room_id} is not supported by conduwuit",
)));
}
let mut leave_event_stub = serde_json::from_str::<CanonicalJsonObject>(
make_leave_response.event.get(),
)
.map_err(|e| {
err!(BadServerResponse("Invalid make_leave event json received from server: {e:?}"))
err!(BadServerResponse(warn!(
"Invalid make_leave event json received from {remote_server} for {room_id}: {e:?}"
)))
})?;
// TODO: Is origin needed?

View file

@ -1,12 +1,24 @@
use axum::extract::State;
use conduwuit::{
Err, Event, PduCount, PduEvent, Result, at,
Err, Result, at,
matrix::{
Event,
pdu::{PduCount, PduEvent},
},
utils::{
IterStream, ReadyExt,
result::{FlatOk, LogErr},
stream::{BroadbandExt, TryIgnore, WidebandExt},
},
};
use conduwuit_service::{
Services,
rooms::{
lazy_loading,
lazy_loading::{Options, Witness},
timeline::PdusIterItem,
},
};
use futures::{FutureExt, StreamExt, TryFutureExt, future::OptionFuture, pin_mut};
use ruma::{
RoomId, UserId,
@ -17,14 +29,6 @@ use ruma::{
events::{AnyStateEvent, StateEventType, TimelineEventType, TimelineEventType::*},
serde::Raw,
};
use service::{
Services,
rooms::{
lazy_loading,
lazy_loading::{Options, Witness},
timeline::PdusIterItem,
},
};
use crate::Ruma;
@ -257,10 +261,9 @@ pub(crate) async fn is_ignored_pdu(
let ignored_type = IGNORED_MESSAGE_TYPES.binary_search(&pdu.kind).is_ok();
let ignored_server = services
.server
.config
.forbidden_remote_server_names
.contains(pdu.sender().server_name());
.is_match(pdu.sender().server_name().host());
if ignored_type
&& (ignored_server || services.users.user_is_ignored(&pdu.sender, user_id).await)

View file

@ -1,14 +1,14 @@
use std::time::Duration;
use axum::extract::State;
use conduwuit::utils;
use conduwuit::{Error, Result, utils};
use ruma::{
api::client::{account, error::ErrorKind},
authentication::TokenType,
};
use super::TOKEN_LENGTH;
use crate::{Error, Result, Ruma};
use crate::Ruma;
/// # `POST /_matrix/client/v3/user/{userId}/openid/request_token`
///

View file

@ -3,10 +3,11 @@ use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{
Err, Error, Result,
pdu::PduBuilder,
matrix::pdu::PduBuilder,
utils::{IterStream, stream::TryIgnore},
warn,
};
use conduwuit_service::Services;
use futures::{StreamExt, TryStreamExt, future::join3};
use ruma::{
OwnedMxcUri, OwnedRoomId, UserId,
@ -22,7 +23,6 @@ use ruma::{
events::room::member::{MembershipState, RoomMemberEventContent},
presence::PresenceState,
};
use service::Services;
use crate::Ruma;

View file

@ -1,5 +1,6 @@
use axum::extract::State;
use conduwuit::{Err, err};
use conduwuit::{Err, Error, Result, err};
use conduwuit_service::Services;
use ruma::{
CanonicalJsonObject, CanonicalJsonValue,
api::client::{
@ -19,9 +20,8 @@ use ruma::{
RemovePushRuleError, Ruleset,
},
};
use service::Services;
use crate::{Error, Result, Ruma};
use crate::Ruma;
/// # `GET /_matrix/client/r0/pushrules/`
///

View file

@ -1,7 +1,7 @@
use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{Err, PduCount, err};
use conduwuit::{Err, PduCount, Result, err};
use ruma::{
MilliSecondsSinceUnixEpoch,
api::client::{read_marker::set_read_marker, receipt::create_receipt},
@ -11,7 +11,7 @@ use ruma::{
},
};
use crate::{Result, Ruma};
use crate::Ruma;
/// # `POST /_matrix/client/r0/rooms/{roomId}/read_markers`
///

View file

@ -1,9 +1,10 @@
use axum::extract::State;
use conduwuit::{Result, matrix::pdu::PduBuilder};
use ruma::{
api::client::redact::redact_event, events::room::redaction::RoomRedactionEventContent,
};
use crate::{Result, Ruma, service::pdu::PduBuilder};
use crate::Ruma;
/// # `PUT /_matrix/client/r0/rooms/{roomId}/redact/{eventId}/{txnId}`
///

View file

@ -1,8 +1,10 @@
use axum::extract::State;
use conduwuit::{
PduCount, Result, at,
Result, at,
matrix::pdu::PduCount,
utils::{IterStream, ReadyExt, result::FlatOk, stream::WidebandExt},
};
use conduwuit_service::{Services, rooms::timeline::PdusIterItem};
use futures::StreamExt;
use ruma::{
EventId, RoomId, UInt, UserId,
@ -15,7 +17,6 @@ use ruma::{
},
events::{TimelineEventType, relation::RelationType},
};
use service::{Services, rooms::timeline::PdusIterItem};
use crate::Ruma;

View file

@ -2,7 +2,8 @@ use std::time::Duration;
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{Err, info, utils::ReadyExt};
use conduwuit::{Err, Error, Result, debug_info, info, matrix::pdu::PduEvent, utils::ReadyExt};
use conduwuit_service::Services;
use rand::Rng;
use ruma::{
EventId, RoomId, UserId,
@ -15,10 +16,7 @@ use ruma::{
};
use tokio::time::sleep;
use crate::{
Error, Result, Ruma, debug_info,
service::{Services, pdu::PduEvent},
};
use crate::Ruma;
/// # `POST /_matrix/client/v3/rooms/{roomId}/report`
///

View file

@ -2,8 +2,11 @@ use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{
Err, Error, Result, StateKey, debug_info, debug_warn, err, error, info, pdu::PduBuilder, warn,
Err, Error, Result, debug_info, debug_warn, err, error, info,
matrix::{StateKey, pdu::PduBuilder},
warn,
};
use conduwuit_service::{Services, appservice::RegistrationInfo};
use futures::FutureExt;
use ruma::{
CanonicalJsonObject, Int, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId,
@ -29,7 +32,6 @@ use ruma::{
serde::{JsonObject, Raw},
};
use serde_json::{json, value::to_raw_value};
use service::{Services, appservice::RegistrationInfo};
use crate::{Ruma, client::invite_helper};

View file

@ -2,9 +2,14 @@ mod aliases;
mod create;
mod event;
mod initial_sync;
mod summary;
mod upgrade;
pub(crate) use self::{
aliases::get_room_aliases_route, create::create_room_route, event::get_room_event_route,
initial_sync::room_initial_sync_route, upgrade::upgrade_room_route,
aliases::get_room_aliases_route,
create::create_room_route,
event::get_room_event_route,
initial_sync::room_initial_sync_route,
summary::{get_room_summary, get_room_summary_legacy},
upgrade::upgrade_room_route,
};

View file

@ -0,0 +1,330 @@
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{
Err, Result, debug_warn, trace,
utils::{IterStream, future::TryExtExt},
};
use futures::{
FutureExt, StreamExt,
future::{OptionFuture, join3},
stream::FuturesUnordered,
};
use ruma::{
OwnedServerName, RoomId, UserId,
api::{
client::room::get_summary,
federation::space::{SpaceHierarchyParentSummary, get_hierarchy},
},
events::room::member::MembershipState,
space::SpaceRoomJoinRule::{self, *},
};
use service::Services;
use crate::{Ruma, RumaResponse};
/// # `GET /_matrix/client/unstable/im.nheko.summary/rooms/{roomIdOrAlias}/summary`
///
/// Returns a short description of the state of a room.
///
/// This is the "wrong" endpoint that some implementations/clients may use
/// according to the MSC. Request and response bodies are the same as
/// `get_room_summary`.
///
/// An implementation of [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266)
pub(crate) async fn get_room_summary_legacy(
State(services): State<crate::State>,
InsecureClientIp(client): InsecureClientIp,
body: Ruma<get_summary::msc3266::Request>,
) -> Result<RumaResponse<get_summary::msc3266::Response>> {
get_room_summary(State(services), InsecureClientIp(client), body)
.boxed()
.await
.map(RumaResponse)
}
/// # `GET /_matrix/client/unstable/im.nheko.summary/summary/{roomIdOrAlias}`
///
/// Returns a short description of the state of a room.
///
/// An implementation of [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266)
#[tracing::instrument(skip_all, fields(%client), name = "room_summary")]
pub(crate) async fn get_room_summary(
State(services): State<crate::State>,
InsecureClientIp(client): InsecureClientIp,
body: Ruma<get_summary::msc3266::Request>,
) -> Result<get_summary::msc3266::Response> {
let (room_id, servers) = services
.rooms
.alias
.resolve_with_servers(&body.room_id_or_alias, Some(body.via.clone()))
.await?;
if services.rooms.metadata.is_banned(&room_id).await {
return Err!(Request(Forbidden("This room is banned on this homeserver.")));
}
room_summary_response(&services, &room_id, &servers, body.sender_user.as_deref())
.boxed()
.await
}
async fn room_summary_response(
services: &Services,
room_id: &RoomId,
servers: &[OwnedServerName],
sender_user: Option<&UserId>,
) -> Result<get_summary::msc3266::Response> {
if services
.rooms
.state_cache
.server_in_room(services.globals.server_name(), room_id)
.await
{
return local_room_summary_response(services, room_id, sender_user)
.boxed()
.await;
}
let room =
remote_room_summary_hierarchy_response(services, room_id, servers, sender_user).await?;
Ok(get_summary::msc3266::Response {
room_id: room_id.to_owned(),
canonical_alias: room.canonical_alias,
avatar_url: room.avatar_url,
guest_can_join: room.guest_can_join,
name: room.name,
num_joined_members: room.num_joined_members,
topic: room.topic,
world_readable: room.world_readable,
join_rule: room.join_rule,
room_type: room.room_type,
room_version: room.room_version,
encryption: room.encryption,
allowed_room_ids: room.allowed_room_ids,
membership: sender_user.is_some().then_some(MembershipState::Leave),
})
}
async fn local_room_summary_response(
services: &Services,
room_id: &RoomId,
sender_user: Option<&UserId>,
) -> Result<get_summary::msc3266::Response> {
trace!(?sender_user, "Sending local room summary response for {room_id:?}");
let join_rule = services.rooms.state_accessor.get_join_rules(room_id);
let world_readable = services.rooms.state_accessor.is_world_readable(room_id);
let guest_can_join = services.rooms.state_accessor.guest_can_join(room_id);
let (join_rule, world_readable, guest_can_join) =
join3(join_rule, world_readable, guest_can_join).await;
trace!("{join_rule:?}, {world_readable:?}, {guest_can_join:?}");
user_can_see_summary(
services,
room_id,
&join_rule.clone().into(),
guest_can_join,
world_readable,
join_rule.allowed_rooms(),
sender_user,
)
.await?;
let canonical_alias = services
.rooms
.state_accessor
.get_canonical_alias(room_id)
.ok();
let name = services.rooms.state_accessor.get_name(room_id).ok();
let topic = services.rooms.state_accessor.get_room_topic(room_id).ok();
let room_type = services.rooms.state_accessor.get_room_type(room_id).ok();
let avatar_url = services
.rooms
.state_accessor
.get_avatar(room_id)
.map(|res| res.into_option().unwrap_or_default().url);
let room_version = services.rooms.state.get_room_version(room_id).ok();
let encryption = services
.rooms
.state_accessor
.get_room_encryption(room_id)
.ok();
let num_joined_members = services
.rooms
.state_cache
.room_joined_count(room_id)
.unwrap_or(0);
let membership: OptionFuture<_> = sender_user
.map(|sender_user| {
services
.rooms
.state_accessor
.get_member(room_id, sender_user)
.map_ok_or(MembershipState::Leave, |content| content.membership)
})
.into();
let (
canonical_alias,
name,
num_joined_members,
topic,
avatar_url,
room_type,
room_version,
encryption,
membership,
) = futures::join!(
canonical_alias,
name,
num_joined_members,
topic,
avatar_url,
room_type,
room_version,
encryption,
membership,
);
Ok(get_summary::msc3266::Response {
room_id: room_id.to_owned(),
canonical_alias,
avatar_url,
guest_can_join,
name,
num_joined_members: num_joined_members.try_into().unwrap_or_default(),
topic,
world_readable,
room_type,
room_version,
encryption,
membership,
allowed_room_ids: join_rule.allowed_rooms().map(Into::into).collect(),
join_rule: join_rule.into(),
})
}
/// used by MSC3266 to fetch a room's info if we do not know about it
async fn remote_room_summary_hierarchy_response(
services: &Services,
room_id: &RoomId,
servers: &[OwnedServerName],
sender_user: Option<&UserId>,
) -> Result<SpaceHierarchyParentSummary> {
trace!(?sender_user, ?servers, "Sending remote room summary response for {room_id:?}");
if !services.config.allow_federation {
return Err!(Request(Forbidden("Federation is disabled.")));
}
if services.rooms.metadata.is_disabled(room_id).await {
return Err!(Request(Forbidden(
"Federaton of room {room_id} is currently disabled on this server."
)));
}
let request = get_hierarchy::v1::Request::new(room_id.to_owned());
let mut requests: FuturesUnordered<_> = servers
.iter()
.map(|server| {
services
.sending
.send_federation_request(server, request.clone())
})
.collect();
while let Some(Ok(response)) = requests.next().await {
trace!("{response:?}");
let room = response.room.clone();
if room.room_id != room_id {
debug_warn!(
"Room ID {} returned does not belong to the requested room ID {}",
room.room_id,
room_id
);
continue;
}
return user_can_see_summary(
services,
room_id,
&room.join_rule,
room.guest_can_join,
room.world_readable,
room.allowed_room_ids.iter().map(AsRef::as_ref),
sender_user,
)
.await
.map(|()| room);
}
Err!(Request(NotFound(
"Room is unknown to this server and was unable to fetch over federation with the \
provided servers available"
)))
}
async fn user_can_see_summary<'a, I>(
services: &Services,
room_id: &RoomId,
join_rule: &SpaceRoomJoinRule,
guest_can_join: bool,
world_readable: bool,
allowed_room_ids: I,
sender_user: Option<&UserId>,
) -> Result
where
I: Iterator<Item = &'a RoomId> + Send,
{
let is_public_room = matches!(join_rule, Public | Knock | KnockRestricted);
match sender_user {
| Some(sender_user) => {
let user_can_see_state_events = services
.rooms
.state_accessor
.user_can_see_state_events(sender_user, room_id);
let is_guest = services.users.is_deactivated(sender_user).unwrap_or(false);
let user_in_allowed_restricted_room = allowed_room_ids
.stream()
.any(|room| services.rooms.state_cache.is_joined(sender_user, room));
let (user_can_see_state_events, is_guest, user_in_allowed_restricted_room) =
join3(user_can_see_state_events, is_guest, user_in_allowed_restricted_room)
.boxed()
.await;
if user_can_see_state_events
|| (is_guest && guest_can_join)
|| is_public_room
|| user_in_allowed_restricted_room
{
return Ok(());
}
Err!(Request(Forbidden(
"Room is not world readable, not publicly accessible/joinable, restricted room \
conditions not met, and guest access is forbidden. Not allowed to see details \
of this room."
)))
},
| None => {
if is_public_room || world_readable {
return Ok(());
}
Err!(Request(Forbidden(
"Room is not world readable or publicly accessible/joinable, authentication is \
required"
)))
},
}
}

View file

@ -1,7 +1,10 @@
use std::cmp::max;
use axum::extract::State;
use conduwuit::{Error, Result, StateKey, err, info, pdu::PduBuilder};
use conduwuit::{
Error, Result, err, info,
matrix::{StateKey, pdu::PduBuilder},
};
use futures::StreamExt;
use ruma::{
CanonicalJsonObject, RoomId, RoomVersionId,
@ -103,7 +106,7 @@ pub(crate) async fn upgrade_room_route(
// Use the m.room.tombstone event as the predecessor
let predecessor = Some(ruma::events::room::create::PreviousRoom::new(
body.room_id.clone(),
(*tombstone_event_id).to_owned(),
Some(tombstone_event_id),
));
// Send a m.room.create event containing a predecessor field and the applicable

View file

@ -2,10 +2,12 @@ use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{
Err, PduEvent, Result, at, is_true,
Err, Result, at, is_true,
matrix::pdu::PduEvent,
result::FlatOk,
utils::{IterStream, stream::ReadyExt},
};
use conduwuit_service::{Services, rooms::search::RoomQuery};
use futures::{FutureExt, StreamExt, TryFutureExt, TryStreamExt, future::OptionFuture};
use ruma::{
OwnedRoomId, RoomId, UInt, UserId,
@ -17,7 +19,6 @@ use ruma::{
serde::Raw,
};
use search_events::v3::{Request, Response};
use service::{Services, rooms::search::RoomQuery};
use crate::Ruma;

View file

@ -1,11 +1,11 @@
use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{Err, err};
use conduwuit::{Err, Result, err, matrix::pdu::PduBuilder, utils};
use ruma::{api::client::message::send_message_event, events::MessageLikeEventType};
use serde_json::from_str;
use crate::{Result, Ruma, service::pdu::PduBuilder, utils};
use crate::Ruma;
/// # `PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}`
///

View file

@ -2,7 +2,11 @@ use std::time::Duration;
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{Err, debug, err, info, utils::ReadyExt};
use conduwuit::{
Err, Error, Result, debug, err, info, utils,
utils::{ReadyExt, hash},
};
use conduwuit_service::uiaa::SESSION_ID_LENGTH;
use futures::StreamExt;
use ruma::{
UserId,
@ -22,10 +26,9 @@ use ruma::{
uiaa,
},
};
use service::uiaa::SESSION_ID_LENGTH;
use super::{DEVICE_ID_LENGTH, TOKEN_LENGTH};
use crate::{Error, Result, Ruma, utils, utils::hash};
use crate::Ruma;
/// # `GET /_matrix/client/v3/login`
///

View file

@ -8,16 +8,16 @@ use conduwuit::{
Err, Result,
utils::{future::TryExtExt, stream::IterStream},
};
use futures::{StreamExt, TryFutureExt, future::OptionFuture};
use ruma::{
OwnedRoomId, OwnedServerName, RoomId, UInt, UserId, api::client::space::get_hierarchy,
};
use service::{
use conduwuit_service::{
Services,
rooms::spaces::{
PaginationToken, SummaryAccessibility, get_parent_children_via, summary_to_chunk,
},
};
use futures::{StreamExt, TryFutureExt, future::OptionFuture};
use ruma::{
OwnedRoomId, OwnedServerName, RoomId, UInt, UserId, api::client::space::get_hierarchy,
};
use crate::Ruma;

View file

@ -1,5 +1,10 @@
use axum::extract::State;
use conduwuit::{Err, PduEvent, Result, err, pdu::PduBuilder, utils::BoolExt};
use conduwuit::{
Err, Result, err,
matrix::pdu::{PduBuilder, PduEvent},
utils::BoolExt,
};
use conduwuit_service::Services;
use futures::TryStreamExt;
use ruma::{
OwnedEventId, RoomId, UserId,
@ -16,7 +21,6 @@ use ruma::{
},
serde::Raw,
};
use service::Services;
use crate::{Ruma, RumaResponse};
@ -207,7 +211,7 @@ async fn allowed_to_send_state_event(
// irreversible mistakes
match json.deserialize_as::<RoomServerAclEventContent>() {
| Ok(acl_content) => {
if acl_content.allow.is_empty() {
if acl_content.allow_is_empty() {
return Err!(Request(BadJson(debug_warn!(
?room_id,
"Sending an ACL event with an empty allow key will permanently \
@ -216,9 +220,7 @@ async fn allowed_to_send_state_event(
))));
}
if acl_content.deny.contains(&String::from("*"))
&& acl_content.allow.contains(&String::from("*"))
{
if acl_content.deny_contains("*") && acl_content.allow_contains("*") {
return Err!(Request(BadJson(debug_warn!(
?room_id,
"Sending an ACL event with a deny and allow key value of \"*\" will \
@ -227,8 +229,9 @@ async fn allowed_to_send_state_event(
))));
}
if acl_content.deny.contains(&String::from("*"))
if acl_content.deny_contains("*")
&& !acl_content.is_allowed(services.globals.server_name())
&& !acl_content.allow_contains(services.globals.server_name().as_str())
{
return Err!(Request(BadJson(debug_warn!(
?room_id,
@ -238,8 +241,9 @@ async fn allowed_to_send_state_event(
))));
}
if !acl_content.allow.contains(&String::from("*"))
if !acl_content.allow_contains("*")
&& !acl_content.is_allowed(services.globals.server_name())
&& !acl_content.allow_contains(services.globals.server_name().as_str())
{
return Err!(Request(BadJson(debug_warn!(
?room_id,

View file

@ -3,12 +3,14 @@ mod v4;
mod v5;
use conduwuit::{
PduCount,
Error, PduCount, Result,
matrix::pdu::PduEvent,
utils::{
IterStream,
stream::{BroadbandExt, ReadyExt, TryIgnore},
},
};
use conduwuit_service::Services;
use futures::{StreamExt, pin_mut};
use ruma::{
RoomId, UserId,
@ -21,7 +23,6 @@ use ruma::{
pub(crate) use self::{
v3::sync_events_route, v4::sync_events_v4_route, v5::sync_events_v5_route,
};
use crate::{Error, PduEvent, Result, service::Services};
pub(crate) const DEFAULT_BUMP_TYPES: &[TimelineEventType; 6] =
&[CallInvite, PollStart, Beacon, RoomEncrypted, RoomMessage, Sticker];

View file

@ -6,15 +6,20 @@ use std::{
use axum::extract::State;
use conduwuit::{
PduCount, PduEvent, Result, at, err, error, extract_variant, is_equal_to, pair_of,
pdu::{Event, EventHash},
ref_at,
Result, at, err, error, extract_variant, is_equal_to,
matrix::{
Event,
pdu::{EventHash, PduCount, PduEvent},
},
pair_of, ref_at,
result::FlatOk,
utils::{
self, BoolExt, IterStream, ReadyExt, TryFutureExtExt,
future::OptionStream,
math::ruma_from_u64,
stream::{BroadbandExt, Tools, TryExpect, WidebandExt},
},
warn,
};
use conduwuit_service::{
Services,
@ -428,9 +433,12 @@ async fn handle_left_room(
return Ok(None);
}
if !services.rooms.metadata.exists(room_id).await {
if !services.rooms.metadata.exists(room_id).await
|| services.rooms.metadata.is_disabled(room_id).await
|| services.rooms.metadata.is_banned(room_id).await
{
// This is just a rejected invite, not a room we know
// Insert a leave event anyways
// Insert a leave event anyways for the client
let event = PduEvent {
event_id: EventId::new(services.globals.server_name()),
sender: sender_user.to_owned(),
@ -489,7 +497,7 @@ async fn handle_left_room(
.room_state_get_id(room_id, &StateEventType::RoomMember, sender_user.as_str())
.await
else {
error!("Left room but no left state event");
warn!("Left {room_id} but no left state event");
return Ok(None);
};
@ -499,7 +507,7 @@ async fn handle_left_room(
.pdu_shortstatehash(&left_event_id)
.await
else {
error!(event_id = %left_event_id, "Leave event has no state");
warn!(event_id = %left_event_id, "Leave event has no state in {room_id}");
return Ok(None);
};
@ -1029,7 +1037,7 @@ async fn calculate_state_incremental<'a>(
})
.into();
let state_diff: OptionFuture<_> = (!full_state && state_changed)
let state_diff_ids: OptionFuture<_> = (!full_state && state_changed)
.then(|| {
StreamExt::into_future(
services
@ -1054,45 +1062,9 @@ async fn calculate_state_incremental<'a>(
})
.into();
let lazy_state_ids = lazy_state_ids
.map(|opt| {
opt.map(|(curr, next)| {
let opt = curr;
let iter = Option::into_iter(opt);
IterStream::stream(iter).chain(next)
})
})
.map(Option::into_iter)
.map(IterStream::stream)
.flatten_stream()
.flatten();
let state_diff_ids = state_diff
.map(|opt| {
opt.map(|(curr, next)| {
let opt = curr;
let iter = Option::into_iter(opt);
IterStream::stream(iter).chain(next)
})
})
.map(Option::into_iter)
.map(IterStream::stream)
.flatten_stream()
.flatten();
let state_events = current_state_ids
.map(|opt| {
opt.map(|(curr, next)| {
let opt = curr;
let iter = Option::into_iter(opt);
IterStream::stream(iter).chain(next)
})
})
.map(Option::into_iter)
.map(IterStream::stream)
.flatten_stream()
.flatten()
.chain(state_diff_ids)
.stream()
.chain(state_diff_ids.stream())
.broad_filter_map(|(shortstatekey, shorteventid)| async move {
if witness.is_none() || encrypted_room {
return Some(shorteventid);
@ -1100,7 +1072,7 @@ async fn calculate_state_incremental<'a>(
lazy_filter(services, sender_user, shortstatekey, shorteventid).await
})
.chain(lazy_state_ids)
.chain(lazy_state_ids.stream())
.broad_filter_map(|shorteventid| {
services
.rooms

View file

@ -438,7 +438,10 @@ pub(crate) async fn sync_events_v4_route(
let mut known_subscription_rooms = BTreeSet::new();
for (room_id, room) in &body.room_subscriptions {
if !services.rooms.metadata.exists(room_id).await {
if !services.rooms.metadata.exists(room_id).await
|| services.rooms.metadata.is_disabled(room_id).await
|| services.rooms.metadata.is_banned(room_id).await
{
continue;
}
let todo_room =

View file

@ -6,13 +6,19 @@ use std::{
use axum::extract::State;
use conduwuit::{
Error, PduEvent, Result, TypeStateKey, debug, error, extract_variant, trace,
Error, Result, debug, error, extract_variant,
matrix::{
TypeStateKey,
pdu::{PduCount, PduEvent},
},
trace,
utils::{
BoolExt, IterStream, ReadyExt, TryFutureExtExt,
math::{ruma_from_usize, usize_from_ruma},
},
warn,
};
use conduwuit_service::rooms::read_receipt::pack_receipts;
use futures::{FutureExt, StreamExt, TryFutureExt};
use ruma::{
DeviceId, OwnedEventId, OwnedRoomId, RoomId, UInt, UserId,
@ -27,7 +33,6 @@ use ruma::{
serde::Raw,
uint,
};
use service::{PduCount, rooms::read_receipt::pack_receipts};
use super::{filter_rooms, share_encrypted_room};
use crate::{
@ -214,7 +219,10 @@ async fn fetch_subscriptions(
) {
let mut known_subscription_rooms = BTreeSet::new();
for (room_id, room) in &body.room_subscriptions {
if !services.rooms.metadata.exists(room_id).await {
if !services.rooms.metadata.exists(room_id).await
|| services.rooms.metadata.is_disabled(room_id).await
|| services.rooms.metadata.is_banned(room_id).await
{
continue;
}
let todo_room =

View file

@ -1,6 +1,7 @@
use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::Result;
use ruma::{
api::client::tag::{create_tag, delete_tag, get_tags},
events::{
@ -9,7 +10,7 @@ use ruma::{
},
};
use crate::{Result, Ruma};
use crate::Ruma;
/// # `PUT /_matrix/client/r0/user/{userId}/rooms/{roomId}/tags/{tag}`
///

View file

@ -1,8 +1,9 @@
use std::collections::BTreeMap;
use conduwuit::Result;
use ruma::api::client::thirdparty::get_protocols;
use crate::{Result, Ruma, RumaResponse};
use crate::{Ruma, RumaResponse};
/// # `GET /_matrix/client/r0/thirdparty/protocols`
///

View file

@ -1,9 +1,12 @@
use axum::extract::State;
use conduwuit::{PduCount, PduEvent, at};
use conduwuit::{
Result, at,
matrix::pdu::{PduCount, PduEvent},
};
use futures::StreamExt;
use ruma::{api::client::threads::get_threads, uint};
use crate::{Result, Ruma};
use crate::Ruma;
/// # `GET /_matrix/client/r0/rooms/{roomId}/threads`
pub(crate) async fn get_threads_route(

View file

@ -2,6 +2,7 @@ use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{Error, Result};
use conduwuit_service::sending::EduBuf;
use futures::StreamExt;
use ruma::{
api::{
@ -10,7 +11,6 @@ use ruma::{
},
to_device::DeviceIdOrAllDevices,
};
use service::sending::EduBuf;
use crate::Ruma;

View file

@ -1,8 +1,8 @@
use axum::extract::State;
use conduwuit::{Err, utils::math::Tried};
use conduwuit::{Err, Result, utils, utils::math::Tried};
use ruma::api::client::typing::create_typing_event;
use crate::{Result, Ruma, utils};
use crate::Ruma;
/// # `PUT /_matrix/client/r0/rooms/{roomId}/typing/{userId}`
///

View file

@ -2,7 +2,7 @@ use std::collections::BTreeMap;
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::Err;
use conduwuit::{Err, Error, Result};
use futures::StreamExt;
use ruma::{
OwnedRoomId,
@ -14,16 +14,14 @@ use ruma::{
delete_profile_key, delete_timezone_key, get_profile_key, get_timezone_key,
set_profile_key, set_timezone_key,
},
room::get_summary,
},
federation,
},
events::room::member::MembershipState,
presence::PresenceState,
};
use super::{update_avatar_url, update_displayname};
use crate::{Error, Result, Ruma, RumaResponse};
use crate::Ruma;
/// # `GET /_matrix/client/unstable/uk.half-shot.msc2666/user/mutual_rooms`
///
@ -38,13 +36,10 @@ pub(crate) async fn get_mutual_rooms_route(
InsecureClientIp(client): InsecureClientIp,
body: Ruma<mutual_rooms::unstable::Request>,
) -> Result<mutual_rooms::unstable::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let sender_user = body.sender_user();
if sender_user == &body.user_id {
return Err(Error::BadRequest(
ErrorKind::Unknown,
"You cannot request rooms in common with yourself.",
));
if sender_user == body.user_id {
return Err!(Request(Unknown("You cannot request rooms in common with yourself.")));
}
if !services.users.exists(&body.user_id).await {
@ -65,129 +60,6 @@ pub(crate) async fn get_mutual_rooms_route(
})
}
/// # `GET /_matrix/client/unstable/im.nheko.summary/rooms/{roomIdOrAlias}/summary`
///
/// Returns a short description of the state of a room.
///
/// This is the "wrong" endpoint that some implementations/clients may use
/// according to the MSC. Request and response bodies are the same as
/// `get_room_summary`.
///
/// An implementation of [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266)
pub(crate) async fn get_room_summary_legacy(
State(services): State<crate::State>,
InsecureClientIp(client): InsecureClientIp,
body: Ruma<get_summary::msc3266::Request>,
) -> Result<RumaResponse<get_summary::msc3266::Response>> {
get_room_summary(State(services), InsecureClientIp(client), body)
.await
.map(RumaResponse)
}
/// # `GET /_matrix/client/unstable/im.nheko.summary/summary/{roomIdOrAlias}`
///
/// Returns a short description of the state of a room.
///
/// TODO: support fetching remote room info if we don't know the room
///
/// An implementation of [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266)
#[tracing::instrument(skip_all, fields(%client), name = "room_summary")]
pub(crate) async fn get_room_summary(
State(services): State<crate::State>,
InsecureClientIp(client): InsecureClientIp,
body: Ruma<get_summary::msc3266::Request>,
) -> Result<get_summary::msc3266::Response> {
let sender_user = body.sender_user.as_ref();
let room_id = services.rooms.alias.resolve(&body.room_id_or_alias).await?;
if !services.rooms.metadata.exists(&room_id).await {
return Err(Error::BadRequest(ErrorKind::NotFound, "Room is unknown to this server"));
}
if sender_user.is_none()
&& !services
.rooms
.state_accessor
.is_world_readable(&room_id)
.await
{
return Err(Error::BadRequest(
ErrorKind::forbidden(),
"Room is not world readable, authentication is required",
));
}
Ok(get_summary::msc3266::Response {
room_id: room_id.clone(),
canonical_alias: services
.rooms
.state_accessor
.get_canonical_alias(&room_id)
.await
.ok(),
avatar_url: services
.rooms
.state_accessor
.get_avatar(&room_id)
.await
.into_option()
.unwrap_or_default()
.url,
guest_can_join: services.rooms.state_accessor.guest_can_join(&room_id).await,
name: services.rooms.state_accessor.get_name(&room_id).await.ok(),
num_joined_members: services
.rooms
.state_cache
.room_joined_count(&room_id)
.await
.unwrap_or(0)
.try_into()?,
topic: services
.rooms
.state_accessor
.get_room_topic(&room_id)
.await
.ok(),
world_readable: services
.rooms
.state_accessor
.is_world_readable(&room_id)
.await,
join_rule: services
.rooms
.state_accessor
.get_join_rule(&room_id)
.await
.unwrap_or_default()
.0,
room_type: services
.rooms
.state_accessor
.get_room_type(&room_id)
.await
.ok(),
room_version: services.rooms.state.get_room_version(&room_id).await.ok(),
membership: if let Some(sender_user) = sender_user {
services
.rooms
.state_accessor
.get_member(&room_id, sender_user)
.await
.map_or_else(|_| MembershipState::Leave, |content| content.membership)
.into()
} else {
None
},
encryption: services
.rooms
.state_accessor
.get_room_encryption(&room_id)
.await
.ok(),
})
}
/// # `DELETE /_matrix/client/unstable/uk.tcpip.msc4133/profile/:user_id/us.cloke.msc4175.tz`
///
/// Deletes the `tz` (timezone) of a user, as per MSC4133 and MSC4175.

View file

@ -1,10 +1,11 @@
use std::collections::BTreeMap;
use axum::{Json, extract::State, response::IntoResponse};
use conduwuit::Result;
use futures::StreamExt;
use ruma::api::client::discovery::get_supported_versions;
use crate::{Result, Ruma};
use crate::Ruma;
/// # `GET /_matrix/client/versions`
///

View file

@ -1,15 +1,19 @@
use axum::extract::State;
use conduwuit::utils::TryFutureExtExt;
use futures::{StreamExt, pin_mut};
use conduwuit::{
Result,
utils::{future::BoolExt, stream::BroadbandExt},
};
use futures::{FutureExt, StreamExt, pin_mut};
use ruma::{
api::client::user_directory::search_users,
events::{
StateEventType,
room::join_rules::{JoinRule, RoomJoinRulesEventContent},
},
api::client::user_directory::search_users::{self},
events::room::join_rules::JoinRule,
};
use crate::{Result, Ruma};
use crate::Ruma;
// conduwuit can handle a lot more results than synapse
const LIMIT_MAX: usize = 500;
const LIMIT_DEFAULT: usize = 10;
/// # `POST /_matrix/client/r0/user_directory/search`
///
@ -21,78 +25,63 @@ pub(crate) async fn search_users_route(
State(services): State<crate::State>,
body: Ruma<search_users::v3::Request>,
) -> Result<search_users::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let limit = usize::try_from(body.limit).map_or(10, usize::from).min(100); // default limit is 10
let sender_user = body.sender_user();
let limit = usize::try_from(body.limit)
.map_or(LIMIT_DEFAULT, usize::from)
.min(LIMIT_MAX);
let users = services.users.stream().filter_map(|user_id| async {
// Filter out buggy users (they should not exist, but you never know...)
let user = search_users::v3::User {
user_id: user_id.to_owned(),
display_name: services.users.displayname(user_id).await.ok(),
avatar_url: services.users.avatar_url(user_id).await.ok(),
};
let mut users = services
.users
.stream()
.map(ToOwned::to_owned)
.broad_filter_map(async |user_id| {
let user = search_users::v3::User {
user_id: user_id.clone(),
display_name: services.users.displayname(&user_id).await.ok(),
avatar_url: services.users.avatar_url(&user_id).await.ok(),
};
let user_id_matches = user
.user_id
.to_string()
.to_lowercase()
.contains(&body.search_term.to_lowercase());
let user_id_matches = user
.user_id
.as_str()
.to_lowercase()
.contains(&body.search_term.to_lowercase());
let user_displayname_matches = user
.display_name
.as_ref()
.filter(|name| {
let user_displayname_matches = user.display_name.as_ref().is_some_and(|name| {
name.to_lowercase()
.contains(&body.search_term.to_lowercase())
})
.is_some();
});
if !user_id_matches && !user_displayname_matches {
return None;
}
if !user_id_matches && !user_displayname_matches {
return None;
}
// It's a matching user, but is the sender allowed to see them?
let mut user_visible = false;
let user_is_in_public_rooms = services
.rooms
.state_cache
.rooms_joined(&user.user_id)
.any(|room| {
services
.rooms
.state_accessor
.room_state_get_content::<RoomJoinRulesEventContent>(
room,
&StateEventType::RoomJoinRules,
"",
)
.map_ok_or(false, |content| content.join_rule == JoinRule::Public)
})
.await;
if user_is_in_public_rooms {
user_visible = true;
} else {
let user_is_in_shared_rooms = services
let user_in_public_room = services
.rooms
.state_cache
.user_sees_user(sender_user, &user.user_id)
.await;
.rooms_joined(&user_id)
.map(ToOwned::to_owned)
.any(|room| async move {
services
.rooms
.state_accessor
.get_join_rules(&room)
.map(|rule| matches!(rule, JoinRule::Public))
.await
});
if user_is_in_shared_rooms {
user_visible = true;
}
}
let user_sees_user = services
.rooms
.state_cache
.user_sees_user(sender_user, &user_id);
user_visible.then_some(user)
});
pin_mut!(user_in_public_room, user_sees_user);
pin_mut!(users);
user_in_public_room.or(user_sees_user).await.then_some(user)
});
let limited = users.by_ref().next().await.is_some();
let results = users.take(limit).collect().await;
let results = users.by_ref().take(limit).collect().await;
let limited = users.next().await.is_some();
Ok(search_users::v3::Response { results, limited })
}

View file

@ -2,12 +2,12 @@ use std::time::{Duration, SystemTime};
use axum::extract::State;
use base64::{Engine as _, engine::general_purpose};
use conduwuit::{Err, utils};
use conduwuit::{Err, Result, utils};
use hmac::{Hmac, Mac};
use ruma::{SecondsSinceUnixEpoch, UserId, api::client::voip::get_turn_server_info};
use sha1::Sha1;
use crate::{Result, Ruma};
use crate::Ruma;
const RANDOM_USER_ID_LENGTH: usize = 10;

View file

@ -1,4 +1,5 @@
use axum::{Json, extract::State, response::IntoResponse};
use conduwuit::{Error, Result};
use ruma::api::client::{
discovery::{
discover_homeserver::{self, HomeserverInfo, SlidingSyncProxyInfo},
@ -7,7 +8,7 @@ use ruma::api::client::{
error::ErrorKind,
};
use crate::{Error, Result, Ruma};
use crate::Ruma;
/// # `GET /.well-known/matrix/client`
///

View file

@ -8,8 +8,6 @@ pub mod server;
extern crate conduwuit_core as conduwuit;
extern crate conduwuit_service as service;
pub(crate) use conduwuit::{Error, Result, debug_info, pdu::PduEvent, utils};
pub(crate) use self::router::{Ruma, RumaResponse, State};
conduwuit::mod_ctor! {}

View file

@ -317,10 +317,9 @@ fn auth_server_checks(services: &Services, x_matrix: &XMatrix) -> Result<()> {
let origin = &x_matrix.origin;
if services
.server
.config
.forbidden_remote_server_names
.contains(origin)
.is_match(origin.host())
{
return Err!(Request(Forbidden(debug_warn!(
"Federation requests from {origin} denied."

View file

@ -6,11 +6,17 @@ use conduwuit::{
utils::{IterStream, ReadyExt, stream::TryTools},
};
use futures::{FutureExt, StreamExt, TryStreamExt};
use ruma::{MilliSecondsSinceUnixEpoch, api::federation::backfill::get_backfill, uint};
use ruma::{MilliSecondsSinceUnixEpoch, api::federation::backfill::get_backfill};
use super::AccessCheck;
use crate::Ruma;
/// arbitrary number but synapse's is 100 and we can handle lots of these
/// anyways
const LIMIT_MAX: usize = 150;
/// no spec defined number but we can handle a lot of these
const LIMIT_DEFAULT: usize = 50;
/// # `GET /_matrix/federation/v1/backfill/<room_id>`
///
/// Retrieves events from before the sender joined the room, if the room's
@ -30,9 +36,9 @@ pub(crate) async fn get_backfill_route(
let limit = body
.limit
.min(uint!(100))
.try_into()
.expect("UInt could not be converted to usize");
.unwrap_or(LIMIT_DEFAULT)
.min(LIMIT_MAX);
let from = body
.v

View file

@ -1,13 +1,15 @@
use axum::extract::State;
use conduwuit::{Error, Result};
use ruma::{
CanonicalJsonValue, EventId, RoomId,
api::{client::error::ErrorKind, federation::event::get_missing_events},
};
use conduwuit::{Result, debug, debug_error, utils::to_canonical_object};
use ruma::api::federation::event::get_missing_events;
use super::AccessCheck;
use crate::Ruma;
/// arbitrary number but synapse's is 20 and we can handle lots of these anyways
const LIMIT_MAX: usize = 50;
/// spec says default is 10
const LIMIT_DEFAULT: usize = 10;
/// # `POST /_matrix/federation/v1/get_missing_events/{roomId}`
///
/// Retrieves events that the sender is missing.
@ -24,7 +26,11 @@ pub(crate) async fn get_missing_events_route(
.check()
.await?;
let limit = body.limit.try_into()?;
let limit = body
.limit
.try_into()
.unwrap_or(LIMIT_DEFAULT)
.min(LIMIT_MAX);
let mut queued_events = body.latest_events.clone();
// the vec will never have more entries the limit
@ -32,60 +38,52 @@ pub(crate) async fn get_missing_events_route(
let mut i: usize = 0;
while i < queued_events.len() && events.len() < limit {
if let Ok(pdu) = services
let Ok(pdu) = services.rooms.timeline.get_pdu(&queued_events[i]).await else {
debug!(
?body.origin,
"Event {} does not exist locally, skipping", &queued_events[i]
);
i = i.saturating_add(1);
continue;
};
if body.earliest_events.contains(&queued_events[i]) {
i = i.saturating_add(1);
continue;
}
if !services
.rooms
.timeline
.get_pdu_json(&queued_events[i])
.state_accessor
.server_can_see_event(body.origin(), &body.room_id, &queued_events[i])
.await
{
let room_id_str = pdu
.get("room_id")
.and_then(|val| val.as_str())
.ok_or_else(|| Error::bad_database("Invalid event in database."))?;
let event_room_id = <&RoomId>::try_from(room_id_str)
.map_err(|_| Error::bad_database("Invalid room_id in event in database."))?;
if event_room_id != body.room_id {
return Err(Error::BadRequest(ErrorKind::InvalidParam, "Event from wrong room."));
}
if body.earliest_events.contains(&queued_events[i]) {
i = i.saturating_add(1);
continue;
}
if !services
.rooms
.state_accessor
.server_can_see_event(body.origin(), &body.room_id, &queued_events[i])
.await
{
i = i.saturating_add(1);
continue;
}
let prev_events = pdu
.get("prev_events")
.and_then(CanonicalJsonValue::as_array)
.unwrap_or_default();
queued_events.extend(
prev_events
.iter()
.map(<&EventId>::try_from)
.filter_map(Result::ok)
.map(ToOwned::to_owned),
);
events.push(
services
.sending
.convert_to_outgoing_federation_event(pdu)
.await,
debug!(
?body.origin,
"Server cannot see {:?} in {:?}, skipping", pdu.event_id, pdu.room_id
);
i = i.saturating_add(1);
continue;
}
i = i.saturating_add(1);
let Ok(event) = to_canonical_object(&pdu) else {
debug_error!(
?body.origin,
"Failed to convert PDU in database to canonical JSON: {pdu:?}"
);
i = i.saturating_add(1);
continue;
};
let prev_events = pdu.prev_events.iter().map(ToOwned::to_owned);
let event = services
.sending
.convert_to_outgoing_federation_event(event)
.await;
queued_events.extend(prev_events);
events.push(event);
}
Ok(get_missing_events::v1::Response { events })

View file

@ -3,9 +3,11 @@ use conduwuit::{
Err, Result,
utils::stream::{BroadbandExt, IterStream},
};
use conduwuit_service::rooms::spaces::{
Identifier, SummaryAccessibility, get_parent_children_via,
};
use futures::{FutureExt, StreamExt};
use ruma::api::federation::space::get_hierarchy;
use service::rooms::spaces::{Identifier, SummaryAccessibility, get_parent_children_via};
use crate::Ruma;

View file

@ -1,14 +1,15 @@
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use base64::{Engine as _, engine::general_purpose};
use conduwuit::{Err, Error, PduEvent, Result, err, utils, utils::hash::sha256, warn};
use conduwuit::{
Err, Error, PduEvent, Result, err, pdu::gen_event_id, utils, utils::hash::sha256, warn,
};
use ruma::{
CanonicalJsonValue, OwnedUserId, UserId,
api::{client::error::ErrorKind, federation::membership::create_invite},
events::room::member::{MembershipState, RoomMemberEventContent},
serde::JsonObject,
};
use service::pdu::gen_event_id;
use crate::Ruma;
@ -37,20 +38,18 @@ pub(crate) async fn create_invite_route(
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
.is_match(server.host())
{
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
}
}
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.is_match(body.origin().host())
{
warn!(
"Received federated/remote invite from banned server {} for room ID {}. Rejecting.",

View file

@ -1,5 +1,8 @@
use axum::extract::State;
use conduwuit::{Err, debug_info, utils::IterStream, warn};
use conduwuit::{
Err, Error, Result, debug_info, matrix::pdu::PduBuilder, utils::IterStream, warn,
};
use conduwuit_service::Services;
use futures::StreamExt;
use ruma::{
CanonicalJsonObject, OwnedUserId, RoomId, RoomVersionId, UserId,
@ -14,10 +17,7 @@ use ruma::{
};
use serde_json::value::to_raw_value;
use crate::{
Error, Result, Ruma,
service::{Services, pdu::PduBuilder},
};
use crate::Ruma;
/// # `GET /_matrix/federation/v1/make_join/{roomId}/{userId}`
///
@ -42,10 +42,9 @@ pub(crate) async fn create_join_event_template_route(
.await?;
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.is_match(body.origin().host())
{
warn!(
"Server {} for remote user {} tried joining room ID {} which has a server name that \
@ -59,10 +58,9 @@ pub(crate) async fn create_join_event_template_route(
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
.is_match(server.host())
{
return Err!(Request(Forbidden(warn!(
"Room ID server name {server} is banned on this homeserver."

View file

@ -1,15 +1,14 @@
use RoomVersionId::*;
use axum::extract::State;
use conduwuit::{Err, debug_warn};
use conduwuit::{Err, Error, Result, debug_warn, matrix::pdu::PduBuilder, warn};
use ruma::{
RoomVersionId,
api::{client::error::ErrorKind, federation::knock::create_knock_event_template},
events::room::member::{MembershipState, RoomMemberEventContent},
};
use serde_json::value::to_raw_value;
use tracing::warn;
use crate::{Error, Result, Ruma, service::pdu::PduBuilder};
use crate::Ruma;
/// # `GET /_matrix/federation/v1/make_knock/{roomId}/{userId}`
///
@ -34,10 +33,9 @@ pub(crate) async fn create_knock_event_template_route(
.await?;
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.is_match(body.origin().host())
{
warn!(
"Server {} for remote user {} tried knocking room ID {} which has a server name \
@ -51,10 +49,9 @@ pub(crate) async fn create_knock_event_template_route(
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
.is_match(server.host())
{
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
}

View file

@ -1,5 +1,5 @@
use axum::extract::State;
use conduwuit::{Err, Result};
use conduwuit::{Err, Result, matrix::pdu::PduBuilder};
use ruma::{
api::federation::membership::prepare_leave_event,
events::room::member::{MembershipState, RoomMemberEventContent},
@ -7,7 +7,7 @@ use ruma::{
use serde_json::value::to_raw_value;
use super::make_join::maybe_strip_event_id;
use crate::{Ruma, service::pdu::PduBuilder};
use crate::Ruma;
/// # `GET /_matrix/federation/v1/make_leave/{roomId}/{eventId}`
///

View file

@ -1,7 +1,8 @@
use axum::extract::State;
use conduwuit::Result;
use ruma::api::federation::openid::get_openid_userinfo;
use crate::{Result, Ruma};
use crate::Ruma;
/// # `GET /_matrix/federation/v1/openid/userinfo`
///

View file

@ -1,5 +1,6 @@
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{Error, Result};
use ruma::{
api::{
client::error::ErrorKind,
@ -8,7 +9,7 @@ use ruma::{
directory::Filter,
};
use crate::{Error, Result, Ruma};
use crate::Ruma;
/// # `POST /_matrix/federation/v1/publicRooms`
///

View file

@ -9,11 +9,15 @@ use conduwuit::{
result::LogErr,
trace,
utils::{
IterStream, ReadyExt,
IterStream, ReadyExt, millis_since_unix_epoch,
stream::{BroadbandExt, TryBroadbandExt, automatic_width},
},
warn,
};
use conduwuit_service::{
Services,
sending::{EDU_LIMIT, PDU_LIMIT},
};
use futures::{FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt};
use itertools::Itertools;
use ruma::{
@ -33,16 +37,8 @@ use ruma::{
serde::Raw,
to_device::DeviceIdOrAllDevices,
};
use service::{
Services,
sending::{EDU_LIMIT, PDU_LIMIT},
};
use utils::millis_since_unix_epoch;
use crate::{
Ruma,
utils::{self},
};
use crate::Ruma;
type ResolvedMap = BTreeMap<OwnedEventId, Result>;
type Pdu = (OwnedRoomId, OwnedEventId, CanonicalJsonObject);

View file

@ -9,6 +9,7 @@ use conduwuit::{
utils::stream::{IterStream, TryBroadbandExt},
warn,
};
use conduwuit_service::Services;
use futures::{FutureExt, StreamExt, TryStreamExt};
use ruma::{
CanonicalJsonValue, OwnedEventId, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId,
@ -20,7 +21,6 @@ use ruma::{
},
};
use serde_json::value::{RawValue as RawJsonValue, to_raw_value};
use service::Services;
use crate::Ruma;
@ -268,10 +268,9 @@ pub(crate) async fn create_join_event_v1_route(
body: Ruma<create_join_event::v1::Request>,
) -> Result<create_join_event::v1::Response> {
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.is_match(body.origin().host())
{
warn!(
"Server {} tried joining room ID {} through us who has a server name that is \
@ -284,10 +283,9 @@ pub(crate) async fn create_join_event_v1_route(
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
.is_match(server.host())
{
warn!(
"Server {} tried joining room ID {} through us which has a server name that is \
@ -316,20 +314,18 @@ pub(crate) async fn create_join_event_v2_route(
body: Ruma<create_join_event::v2::Request>,
) -> Result<create_join_event::v2::Response> {
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.is_match(body.origin().host())
{
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
}
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
.is_match(server.host())
{
warn!(
"Server {} tried joining room ID {} through us which has a server name that is \

View file

@ -1,5 +1,9 @@
use axum::extract::State;
use conduwuit::{Err, PduEvent, Result, err, pdu::gen_event_id_canonical_json, warn};
use conduwuit::{
Err, Result, err,
matrix::pdu::{PduEvent, gen_event_id_canonical_json},
warn,
};
use futures::FutureExt;
use ruma::{
OwnedServerName, OwnedUserId,
@ -22,10 +26,9 @@ pub(crate) async fn create_knock_event_v1_route(
body: Ruma<send_knock::v1::Request>,
) -> Result<send_knock::v1::Response> {
if services
.server
.config
.forbidden_remote_server_names
.contains(body.origin())
.is_match(body.origin().host())
{
warn!(
"Server {} tried knocking room ID {} who has a server name that is globally \
@ -38,10 +41,9 @@ pub(crate) async fn create_knock_event_v1_route(
if let Some(server) = body.room_id.server_name() {
if services
.server
.config
.forbidden_remote_server_names
.contains(&server.to_owned())
.is_match(server.host())
{
warn!(
"Server {} tried knocking room ID {} which has a server name that is globally \

View file

@ -1,7 +1,8 @@
#![allow(deprecated)]
use axum::extract::State;
use conduwuit::{Err, Result, err};
use conduwuit::{Err, Result, err, matrix::pdu::gen_event_id_canonical_json};
use conduwuit_service::Services;
use futures::FutureExt;
use ruma::{
OwnedRoomId, OwnedUserId, RoomId, ServerName,
@ -13,10 +14,7 @@ use ruma::{
};
use serde_json::value::RawValue as RawJsonValue;
use crate::{
Ruma,
service::{Services, pdu::gen_event_id_canonical_json},
};
use crate::Ruma;
/// # `PUT /_matrix/federation/v1/send_leave/{roomId}/{eventId}`
///

View file

@ -1,6 +1,7 @@
use conduwuit::Result;
use ruma::api::federation::discovery::get_server_version;
use crate::{Result, Ruma};
use crate::Ruma;
/// # `GET /_matrix/federation/v1/version`
///

View file

@ -1,7 +1,8 @@
use axum::extract::State;
use conduwuit::{Error, Result};
use ruma::api::{client::error::ErrorKind, federation::discovery::discover_homeserver};
use crate::{Error, Result, Ruma};
use crate::Ruma;
/// # `GET /.well-known/matrix/server`
///

View file

@ -3,7 +3,7 @@ pub mod manager;
pub mod proxy;
use std::{
collections::{BTreeMap, BTreeSet, HashSet},
collections::{BTreeMap, BTreeSet},
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
path::{Path, PathBuf},
};
@ -252,14 +252,6 @@ pub struct Config {
#[serde(default = "default_servernameevent_data_cache_capacity")]
pub servernameevent_data_cache_capacity: u32,
/// default: varies by system
#[serde(default = "default_server_visibility_cache_capacity")]
pub server_visibility_cache_capacity: u32,
/// default: varies by system
#[serde(default = "default_user_visibility_cache_capacity")]
pub user_visibility_cache_capacity: u32,
/// default: varies by system
#[serde(default = "default_stateinfo_cache_capacity")]
pub stateinfo_cache_capacity: u32,
@ -648,9 +640,9 @@ pub struct Config {
/// Default room version conduwuit will create rooms with.
///
/// Per spec, room version 10 is the default.
/// Per spec, room version 11 is the default.
///
/// default: 10
/// default: 11
#[serde(default = "default_default_room_version")]
pub default_room_version: RoomVersionId,
@ -723,7 +715,7 @@ pub struct Config {
/// Currently, conduwuit doesn't support inbound batched key requests, so
/// this list should only contain other Synapse servers.
///
/// example: ["matrix.org", "envs.net", "tchncs.de"]
/// example: ["matrix.org", "tchncs.de"]
///
/// default: ["matrix.org"]
#[serde(default = "default_trusted_servers")]
@ -1369,15 +1361,18 @@ pub struct Config {
#[serde(default)]
pub prune_missing_media: bool,
/// Vector list of servers that conduwuit will refuse to download remote
/// media from.
/// Vector list of regex patterns of server names that conduwuit will refuse
/// to download remote media from.
///
/// example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
///
/// default: []
#[serde(default)]
pub prevent_media_downloads_from: HashSet<OwnedServerName>,
#[serde(default, with = "serde_regex")]
pub prevent_media_downloads_from: RegexSet,
/// List of forbidden server names that we will block incoming AND outgoing
/// federation with, and block client room joins / remote user invites.
/// List of forbidden server names via regex patterns that we will block
/// incoming AND outgoing federation with, and block client room joins /
/// remote user invites.
///
/// This check is applied on the room ID, room alias, sender server name,
/// sender user's server name, inbound federation X-Matrix origin, and
@ -1385,17 +1380,21 @@ pub struct Config {
///
/// Basically "global" ACLs.
///
/// default: []
#[serde(default)]
pub forbidden_remote_server_names: HashSet<OwnedServerName>,
/// List of forbidden server names that we will block all outgoing federated
/// room directory requests for. Useful for preventing our users from
/// wandering into bad servers or spaces.
/// example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
///
/// default: []
#[serde(default = "HashSet::new")]
pub forbidden_remote_room_directory_server_names: HashSet<OwnedServerName>,
#[serde(default, with = "serde_regex")]
pub forbidden_remote_server_names: RegexSet,
/// List of forbidden server names via regex patterns that we will block all
/// outgoing federated room directory requests for. Useful for preventing
/// our users from wandering into bad servers or spaces.
///
/// example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
///
/// default: []
#[serde(default, with = "serde_regex")]
pub forbidden_remote_room_directory_server_names: RegexSet,
/// Vector list of IPv4 and IPv6 CIDR ranges / subnets *in quotes* that you
/// do not want conduwuit to send outbound requests to. Defaults to
@ -1516,11 +1515,10 @@ pub struct Config {
/// used, and startup as warnings if any room aliases in your database have
/// a forbidden room alias/ID.
///
/// example: ["19dollarfortnitecards", "b[4a]droom"]
/// example: ["19dollarfortnitecards", "b[4a]droom", "badphrase"]
///
/// default: []
#[serde(default)]
#[serde(with = "serde_regex")]
#[serde(default, with = "serde_regex")]
pub forbidden_alias_names: RegexSet,
/// List of forbidden username patterns/strings.
@ -1532,11 +1530,10 @@ pub struct Config {
/// startup as warnings if any local users in your database have a forbidden
/// username.
///
/// example: ["administrator", "b[a4]dusernam[3e]"]
/// example: ["administrator", "b[a4]dusernam[3e]", "badphrase"]
///
/// default: []
#[serde(default)]
#[serde(with = "serde_regex")]
#[serde(default, with = "serde_regex")]
pub forbidden_usernames: RegexSet,
/// Retry failed and incomplete messages to remote servers immediately upon
@ -2035,10 +2032,6 @@ fn default_servernameevent_data_cache_capacity() -> u32 {
parallelism_scaled_u32(100_000).saturating_add(500_000)
}
fn default_server_visibility_cache_capacity() -> u32 { parallelism_scaled_u32(500) }
fn default_user_visibility_cache_capacity() -> u32 { parallelism_scaled_u32(1000) }
fn default_stateinfo_cache_capacity() -> u32 { parallelism_scaled_u32(100) }
fn default_roomid_spacehierarchy_cache_capacity() -> u32 { parallelism_scaled_u32(1000) }
@ -2182,7 +2175,7 @@ fn default_rocksdb_stats_level() -> u8 { 1 }
// I know, it's a great name
#[must_use]
#[inline]
pub fn default_default_room_version() -> RoomVersionId { RoomVersionId::V10 }
pub fn default_default_room_version() -> RoomVersionId { RoomVersionId::V11 }
fn default_ip_range_denylist() -> Vec<String> {
vec![

9
src/core/matrix/mod.rs Normal file
View file

@ -0,0 +1,9 @@
//! Core Matrix Library
pub mod event;
pub mod pdu;
pub mod state_res;
pub use event::Event;
pub use pdu::{PduBuilder, PduCount, PduEvent, PduId, RawPduId, StateKey};
pub use state_res::{EventTypeExt, RoomVersion, StateMap, TypeStateKey};

View file

@ -1,7 +1,6 @@
mod builder;
mod content;
mod count;
mod event;
mod event_id;
mod filter;
mod id;
@ -17,8 +16,8 @@ mod unsigned;
use std::cmp::Ordering;
use ruma::{
CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, OwnedServerName,
OwnedUserId, UInt, events::TimelineEventType,
CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId,
OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, UInt, UserId, events::TimelineEventType,
};
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue as RawJsonValue;
@ -27,12 +26,12 @@ pub use self::{
Count as PduCount, Id as PduId, Pdu as PduEvent, RawId as RawPduId,
builder::{Builder, Builder as PduBuilder},
count::Count,
event::Event,
event_id::*,
id::*,
raw_id::*,
state_key::{ShortStateKey, StateKey},
};
use super::Event;
use crate::Result;
/// Persistent Data Unit (Event)
@ -79,6 +78,36 @@ impl Pdu {
}
}
impl Event for Pdu {
type Id = OwnedEventId;
fn event_id(&self) -> &Self::Id { &self.event_id }
fn room_id(&self) -> &RoomId { &self.room_id }
fn sender(&self) -> &UserId { &self.sender }
fn event_type(&self) -> &TimelineEventType { &self.kind }
fn content(&self) -> &RawJsonValue { &self.content }
fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
MilliSecondsSinceUnixEpoch(self.origin_server_ts)
}
fn state_key(&self) -> Option<&str> { self.state_key.as_deref() }
fn prev_events(&self) -> impl DoubleEndedIterator<Item = &Self::Id> + Send + '_ {
self.prev_events.iter()
}
fn auth_events(&self) -> impl DoubleEndedIterator<Item = &Self::Id> + Send + '_ {
self.auth_events.iter()
}
fn redacts(&self) -> Option<&Self::Id> { self.redacts.as_ref() }
}
/// Prevent derived equality which wouldn't limit itself to event_id
impl Eq for Pdu {}
@ -87,12 +116,12 @@ impl PartialEq for Pdu {
fn eq(&self, other: &Self) -> bool { self.event_id == other.event_id }
}
/// Ordering determined by the Pdu's ID, not the memory representations.
impl PartialOrd for Pdu {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
}
/// Ordering determined by the Pdu's ID, not the memory representations.
impl Ord for Pdu {
fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) }
}
/// Ordering determined by the Pdu's ID, not the memory representations.
impl PartialOrd for Pdu {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
}

View file

@ -4,7 +4,6 @@ pub(crate) mod error;
pub mod event_auth;
mod power_levels;
mod room_version;
mod state_event;
#[cfg(test)]
mod test_utils;
@ -36,9 +35,12 @@ use self::power_levels::PowerLevelsContentFields;
pub use self::{
event_auth::{auth_check, auth_types_for_event},
room_version::RoomVersion,
state_event::Event,
};
use crate::{debug, pdu::StateKey, trace, warn};
use crate::{
debug,
matrix::{event::Event, pdu::StateKey},
trace, warn,
};
/// A mapping of event type and state_key to some value `T`, usually an
/// `EventId`.

View file

@ -11,9 +11,9 @@ use ruma::{
};
use serde::Deserialize;
use serde_json::{Error, from_str as from_json_str};
use tracing::error;
use super::{Result, RoomVersion};
use crate::error;
#[derive(Deserialize)]
struct IntRoomPowerLevelsEventContent {

View file

@ -28,7 +28,10 @@ use serde_json::{
pub(crate) use self::event::PduEvent;
use super::auth_types_for_event;
use crate::{Event, EventTypeExt, Result, StateMap, info};
use crate::{
Result, info,
matrix::{Event, EventTypeExt, StateMap},
};
static SERVER_TIMESTAMP: AtomicU64 = AtomicU64::new(0);

View file

@ -6,11 +6,10 @@ pub mod debug;
pub mod error;
pub mod info;
pub mod log;
pub mod matrix;
pub mod metrics;
pub mod mods;
pub mod pdu;
pub mod server;
pub mod state_res;
pub mod utils;
pub use ::arrayvec;
@ -23,9 +22,8 @@ pub use ::tracing;
pub use config::Config;
pub use error::Error;
pub use info::{rustc_flags_capture, version, version::version};
pub use pdu::{Event, PduBuilder, PduCount, PduEvent, PduId, RawPduId, StateKey};
pub use matrix::{Event, EventTypeExt, PduCount, PduEvent, PduId, RoomVersion, pdu, state_res};
pub use server::Server;
pub use state_res::{EventTypeExt, RoomVersion, StateMap, TypeStateKey};
pub use utils::{ctor, dtor, implement, result, result::Result};
pub use crate as conduwuit_core;

View file

@ -1,35 +0,0 @@
use ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId, RoomId, UserId, events::TimelineEventType};
use serde_json::value::RawValue as RawJsonValue;
use super::Pdu;
pub use crate::state_res::Event;
impl Event for Pdu {
type Id = OwnedEventId;
fn event_id(&self) -> &Self::Id { &self.event_id }
fn room_id(&self) -> &RoomId { &self.room_id }
fn sender(&self) -> &UserId { &self.sender }
fn event_type(&self) -> &TimelineEventType { &self.kind }
fn content(&self) -> &RawJsonValue { &self.content }
fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
MilliSecondsSinceUnixEpoch(self.origin_server_ts)
}
fn state_key(&self) -> Option<&str> { self.state_key.as_deref() }
fn prev_events(&self) -> impl DoubleEndedIterator<Item = &Self::Id> + Send + '_ {
self.prev_events.iter()
}
fn auth_events(&self) -> impl DoubleEndedIterator<Item = &Self::Id> + Send + '_ {
self.auth_events.iter()
}
fn redacts(&self) -> Option<&Self::Id> { self.redacts.as_ref() }
}

View file

@ -69,10 +69,6 @@ impl Server {
return Err!("Reloading not enabled");
}
#[cfg(all(feature = "systemd", target_os = "linux"))]
sd_notify::notify(true, &[sd_notify::NotifyState::Reloading])
.expect("failed to notify systemd of reloading state");
if self.reloading.swap(true, Ordering::AcqRel) {
return Err!("Reloading already in progress");
}
@ -98,10 +94,6 @@ impl Server {
}
pub fn shutdown(&self) -> Result {
#[cfg(all(feature = "systemd", target_os = "linux"))]
sd_notify::notify(true, &[sd_notify::NotifyState::Stopping])
.expect("failed to notify systemd of stopping state");
if self.stopping.swap(true, Ordering::AcqRel) {
return Err!("Shutdown already in progress");
}
@ -144,7 +136,16 @@ impl Server {
}
#[inline]
pub fn running(&self) -> bool { !self.stopping.load(Ordering::Acquire) }
pub fn running(&self) -> bool { !self.is_stopping() }
#[inline]
pub fn is_stopping(&self) -> bool { self.stopping.load(Ordering::Relaxed) }
#[inline]
pub fn is_reloading(&self) -> bool { self.reloading.load(Ordering::Relaxed) }
#[inline]
pub fn is_restarting(&self) -> bool { self.restarting.load(Ordering::Relaxed) }
#[inline]
pub fn is_ours(&self, name: &str) -> bool { name == self.config.server_name }

View file

@ -1,9 +1,11 @@
mod bool_ext;
mod ext_ext;
mod option_ext;
mod option_stream;
mod try_ext_ext;
pub use bool_ext::{BoolExt, and, or};
pub use ext_ext::ExtExt;
pub use option_ext::OptionExt;
pub use option_stream::OptionStream;
pub use try_ext_ext::TryExtExt;

View file

@ -11,11 +11,14 @@ pub trait OptionExt<T> {
impl<T, Fut> OptionExt<T> for OptionFuture<Fut>
where
Fut: Future<Output = T> + Send,
T: Send,
{
#[inline]
fn is_none_or(self, f: impl FnOnce(&T) -> bool + Send) -> impl Future<Output = bool> + Send {
self.map(|o| o.as_ref().is_none_or(f))
}
#[inline]
fn is_some_and(self, f: impl FnOnce(&T) -> bool + Send) -> impl Future<Output = bool> + Send {
self.map(|o| o.as_ref().is_some_and(f))
}

View file

@ -0,0 +1,25 @@
use futures::{Future, FutureExt, Stream, StreamExt, future::OptionFuture};
use super::super::IterStream;
pub trait OptionStream<T> {
fn stream(self) -> impl Stream<Item = T> + Send;
}
impl<T, O, S, Fut> OptionStream<T> for OptionFuture<Fut>
where
Fut: Future<Output = (O, S)> + Send,
S: Stream<Item = T> + Send,
O: IntoIterator<Item = T> + Send,
<O as IntoIterator>::IntoIter: Send,
T: Send,
{
#[inline]
fn stream(self) -> impl Stream<Item = T> + Send {
self.map(|opt| opt.map(|(curr, next)| curr.into_iter().stream().chain(next)))
.map(Option::into_iter)
.map(IterStream::stream)
.flatten_stream()
.flatten()
}
}

View file

@ -49,10 +49,10 @@ pub fn exchange<T>(state: &mut T, source: T) -> T { std::mem::replace(state, sou
#[macro_export]
macro_rules! extract_variant {
($e:expr_2021, $variant:path) => {
( $e:expr_2021, $( $variant:path )|* ) => {
match $e {
| $variant(value) => Some(value),
| _ => None,
$( $variant(value) => Some(value), )*
_ => None,
}
};
}

View file

@ -12,7 +12,7 @@ use std::{
use async_channel::{QueueStrategy, Receiver, RecvError, Sender};
use conduwuit::{
Error, Result, Server, debug, debug_warn, err, error, implement,
Error, Result, Server, debug, err, error, implement,
result::DebugInspect,
smallvec::SmallVec,
trace,
@ -245,13 +245,6 @@ async fn execute(&self, queue: &Sender<Cmd>, cmd: Cmd) -> Result {
self.queued_max.fetch_max(queue.len(), Ordering::Relaxed);
}
if queue.is_full() {
debug_warn!(
capacity = ?queue.capacity(),
"pool queue is full"
);
}
queue
.send(cmd)
.await

Some files were not shown because too many files have changed in this diff Show more