Compare commits

...
This repository has been archived on 2025-08-14. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.

37 commits

Author SHA1 Message Date
June Clementine Strawberry
d8311a5ff6
bump crossbeam-channel bc yanked crate with potential double free
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
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
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
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
Jason Volk
0f81c1e1cc revert hyper-util upgrade due to continued DNS issues
Signed-off-by: Jason Volk <jason@zemos.net>
2025-03-31 22:17:08 -04:00
132 changed files with 1809 additions and 1251 deletions

490
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",
@ -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.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
version = "0.1.11"
source = "git+https://github.com/girlbossceo/hyper-util?rev=e4ae7628fe4fcdacef9788c4c8415317a4489941#e4ae7628fe4fcdacef9788c4c8415317a4489941"
dependencies = [
"bytes",
"futures-channel",
@ -1959,6 +2038,7 @@ dependencies = [
"http",
"http-body",
"hyper",
"libc",
"pin-project-lite",
"socket2",
"tokio",
@ -2255,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",
]
@ -2438,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"
@ -2608,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"
@ -2772,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"
@ -3051,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"
@ -3451,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",
@ -3462,7 +3585,7 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"hickory-resolver",
"hickory-resolver 0.24.4",
"http",
"http-body",
"http-body-util",
@ -3489,6 +3612,7 @@ dependencies = [
"tokio-rustls",
"tokio-socks",
"tokio-util",
"tower 0.5.2",
"tower-service",
"url",
"wasm-bindgen",
@ -3501,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",
]
@ -3530,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",
@ -3550,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",
@ -3562,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",
@ -3585,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",
@ -3617,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",
@ -3642,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",
@ -3664,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",
@ -3673,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",
@ -3683,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",
@ -3698,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",
@ -3710,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",
@ -3892,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"
@ -3938,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",
@ -3960,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",
@ -4068,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",
@ -4463,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"
@ -4675,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",
@ -5366,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",
]
@ -5380,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"
@ -5399,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"
@ -5460,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"
@ -5479,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"
@ -5491,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"
@ -5503,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"
@ -5521,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"
@ -5533,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"
@ -5545,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"
@ -5557,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]
@ -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.10"
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