chore(crates): bump

This commit is contained in:
Matthias Ahouansou
2025-05-08 21:26:55 +01:00
parent bdc6dabe3a
commit 88c95d36a8
17 changed files with 1344 additions and 809 deletions

1704
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,7 @@ workspace = true
[dependencies] [dependencies]
# Web framework # Web framework
# Can't bump until https://github.com/ruma/ruma/pull/1846 is merged or superseded
axum = { version = "0.7", default-features = false, features = [ axum = { version = "0.7", default-features = false, features = [
"form", "form",
"http1", "http1",
@@ -37,7 +38,7 @@ axum = { version = "0.7", default-features = false, features = [
], optional = true } ], optional = true }
axum-extra = { version = "0.9", features = ["typed-header"] } axum-extra = { version = "0.9", features = ["typed-header"] }
axum-server = { version = "0.6", features = ["tls-rustls"] } axum-server = { version = "0.6", features = ["tls-rustls"] }
tower = { version = "0.4.13", features = ["util"] } tower = { version = "0.4", features = ["util"] }
tower-http = { version = "0.5", features = [ tower-http = { version = "0.5", features = [
"add-extension", "add-extension",
"cors", "cors",
@@ -48,25 +49,25 @@ tower-http = { version = "0.5", features = [
tower-service = "0.3" tower-service = "0.3"
# Async runtime and utilities # Async runtime and utilities
tokio = { version = "1.28.1", features = ["fs", "macros", "signal", "sync"] } tokio = { version = "1", features = ["fs", "macros", "signal", "sync"] }
# Used for the http request / response body type for Ruma endpoints used with reqwest # Used for the http request / response body type for Ruma endpoints used with reqwest
bytes = "1.4.0" bytes = "1"
http = "1" http = "1"
# Used to find data directory for default db path # Used to find data directory for default db path
directories = "5" directories = "6"
# Used for ruma wrapper # Used for ruma wrapper
serde_json = { version = "1.0.96", features = ["raw_value"] } serde_json = { version = "1", features = ["raw_value"] }
# Used for appservice registration files # Used for appservice registration files
serde_yaml = "0.9.21" serde_yaml = "0.9"
# Used for pdu definition # Used for pdu definition
serde = { version = "1.0.163", features = ["rc"] } serde = { version = "1", features = ["rc"] }
# Used for secure identifiers # Used for secure identifiers
rand = "0.8.5" rand = "0.9"
# Used to hash passwords # Used to hash passwords
rust-argon2 = "2" rust-argon2 = "2"
# Used to send requests # Used to send requests
hyper = "1.1" hyper = "1"
hyper-util = { version = "0.1", features = [ hyper-util = { version = "0.1", features = [
"client", "client",
"client-legacy", "client-legacy",
@@ -78,7 +79,7 @@ reqwest = { version = "0.12", default-features = false, features = [
"socks", "socks",
] } ] }
# Used for conduit::Error type # Used for conduit::Error type
thiserror = "1.0.40" thiserror = "2" #TODO: 2
# Used to generate thumbnails for images # Used to generate thumbnails for images
image = { version = "0.25", default-features = false, features = [ image = { version = "0.25", default-features = false, features = [
"gif", "gif",
@@ -95,40 +96,40 @@ humantime-serde = "1"
# Used to encode server public key # Used to encode server public key
base64 = "0.22" base64 = "0.22"
# Used when hashing the state # Used when hashing the state
ring = "0.17.7" ring = "0.17"
# Used when querying the SRV record of other servers # Used when querying the SRV record of other servers
hickory-resolver = "0.24" hickory-resolver = "0.25"
# Used to find matching events for appservices # Used to find matching events for appservices
regex = "1.8.1" regex = "1"
# jwt jsonwebtokens # jwt jsonwebtokens
jsonwebtoken = "9.2.0" jsonwebtoken = "9"
# Performance measurements # Performance measurements
opentelemetry = "0.22" opentelemetry = "0.29"
opentelemetry-jaeger-propagator = "0.1" opentelemetry-jaeger-propagator = "0.29"
opentelemetry-otlp = "0.15" opentelemetry-otlp = { version = "0.29", features = ["grpc-tonic"] }
opentelemetry_sdk = { version = "0.22", features = ["rt-tokio"] } opentelemetry_sdk = { version = "0.29", features = ["rt-tokio"] }
tracing = "0.1.37" tracing = "0.1"
tracing-flame = "0.2.0" tracing-flame = "0.2.0"
tracing-opentelemetry = "0.23" tracing-opentelemetry = "0.30"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] }
lru-cache = "0.1.2" lru-cache = "0.1.2"
parking_lot = { version = "0.12.1", optional = true } parking_lot = { version = "0.12", optional = true }
rusqlite = { version = "0.31", optional = true, features = ["bundled"] } rusqlite = { version = "0.35", optional = true, features = ["bundled"] }
# crossbeam = { version = "0.8.2", optional = true } # crossbeam = { version = "0.8.2", optional = true }
num_cpus = "1.15.0" num_cpus = "1"
threadpool = "1.8.1" threadpool = "1"
# Used for ruma wrapper # Used for ruma wrapper
serde_html_form = "0.2.0" serde_html_form = "0.2"
thread_local = "1.1.7" thread_local = "1"
# used for TURN server authentication # used for TURN server authentication
hmac = "0.12.1" hmac = "0.12"
sha-1 = "0.10.1" sha-1 = "0.10"
# used for conduit's CLI and admin room command parsing # used for conduit's CLI and admin room command parsing
chrono = "0.4" chrono = "0.4"
clap = { version = "4.3.0", default-features = false, features = [ clap = { version = "4", default-features = false, features = [
"derive", "derive",
"error-context", "error-context",
"help", "help",
@@ -138,19 +139,19 @@ clap = { version = "4.3.0", default-features = false, features = [
] } ] }
humantime = "2" humantime = "2"
futures-util = { version = "0.3.28", default-features = false } futures-util = { version = "0.3", default-features = false }
# Used for reading the configuration from conduit.toml & environment variables # Used for reading the configuration from conduit.toml & environment variables
figment = { version = "0.10.8", features = ["env", "toml"] } figment = { version = "0.10", features = ["env", "toml"] }
# Validating urls in config # Validating urls in config
url = { version = "2", features = ["serde"] } url = { version = "2", features = ["serde"] }
async-trait = "0.1.68" async-trait = "0.1"
tikv-jemallocator = { version = "0.5.0", features = [ tikv-jemallocator = { version = "0.6", features = [
"unprefixed_malloc_on_supported_platforms", "unprefixed_malloc_on_supported_platforms",
], optional = true } ], optional = true }
sd-notify = { version = "0.4.1", optional = true } sd-notify = { version = "0.4", optional = true }
# Used for matrix spec type definitions and helpers # Used for matrix spec type definitions and helpers
[dependencies.ruma] [dependencies.ruma]
@@ -179,10 +180,10 @@ git = "https://github.com/ruma/ruma.git"
features = ["lz4", "multi-threaded-cf", "zstd"] features = ["lz4", "multi-threaded-cf", "zstd"]
optional = true optional = true
package = "rust-rocksdb" package = "rust-rocksdb"
version = "0.25" version = "0.41"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
nix = { version = "0.28", features = ["resource"] } nix = { version = "0.30", features = ["resource"] }
[features] [features]
backend_rocksdb = ["rocksdb"] backend_rocksdb = ["rocksdb"]

View File

@@ -36,7 +36,7 @@
rocksdb = rocksdb =
let let
version = "9.1.1"; version = "10.2.1";
in in
pkgs.rocksdb.overrideAttrs (old: { pkgs.rocksdb.overrideAttrs (old: {
inherit version; inherit version;
@@ -44,7 +44,7 @@
owner = "facebook"; owner = "facebook";
repo = "rocksdb"; repo = "rocksdb";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-/Xf0bzNJPclH9IP80QNaABfhj4IAR5LycYET18VFCXc="; hash = "sha256-v8kZShgz0O3nHZwWjTvhcM56qAs/le1XgMVYyvVd4tg=";
}; };
}); });

View File

@@ -178,13 +178,25 @@ pub async fn knock_room_route(
info!("make_knock finished"); info!("make_knock finished");
let room_version_id = knock_template.room_version; let room_version_id = match knock_template.room_version {
version
if services()
.globals
.supported_room_versions()
.contains(&version) =>
{
version
}
_ => return Err(Error::BadServerResponse("Room version is not supported")),
};
let (event_id, knock_event, _) = services().rooms.helpers.populate_membership_template( let (event_id, knock_event, _) = services().rooms.helpers.populate_membership_template(
&knock_template.event, &knock_template.event,
sender_user, sender_user,
body.reason, body.reason,
&room_version_id, &room_version_id
.rules()
.expect("Supported room version has rules"),
MembershipState::Knock, MembershipState::Knock,
)?; )?;
@@ -716,8 +728,12 @@ pub(crate) async fn invite_helper<'a>(
let pub_key_map = RwLock::new(BTreeMap::new()); let pub_key_map = RwLock::new(BTreeMap::new());
// We do not add the event_id field to the pdu here because of signature and hashes checks // We do not add the event_id field to the pdu here because of signature and hashes checks
let (event_id, value) = match gen_event_id_canonical_json(&response.event, &room_version_id) let (event_id, value) = match gen_event_id_canonical_json(
{ &response.event,
&room_version_id
.rules()
.expect("Supported room version has rules"),
) {
Ok(t) => t, Ok(t) => t,
Err(_) => { Err(_) => {
// Event could not be converted to canonical json // Event could not be converted to canonical json
@@ -1025,15 +1041,23 @@ async fn remote_leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> {
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut leave_event_stub, &mut leave_event_stub,
&room_version_id, &room_version_id
.rules()
.expect("Supported room version has rules")
.redaction,
) )
.expect("event is valid, we just created it"); .expect("event is valid, we just created it");
// Generate event id // Generate event id
let event_id = EventId::parse(format!( let event_id = EventId::parse(format!(
"${}", "${}",
ruma::signatures::reference_hash(&leave_event_stub, &room_version_id) ruma::signatures::reference_hash(
.expect("Event format validated when event was hashed") &leave_event_stub,
&room_version_id
.rules()
.expect("Supported room version has rules")
)
.expect("Event format validated when event was hashed")
)) ))
.expect("ruma's reference hashes are valid event ids"); .expect("ruma's reference hashes are valid event ids");

View File

@@ -12,7 +12,7 @@ use ruma::{
serde::Raw, serde::Raw,
EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId,
}; };
use tracing::log::warn; use tracing::warn;
/// # `PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}` /// # `PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}`
/// ///

View File

@@ -815,7 +815,12 @@ pub fn parse_incoming_pdu(
let room_version_id = services().rooms.state.get_room_version(&room_id)?; let room_version_id = services().rooms.state.get_room_version(&room_id)?;
let (event_id, value) = match gen_event_id_canonical_json(pdu, &room_version_id) { let (event_id, value) = match gen_event_id_canonical_json(
pdu,
&room_version_id
.rules()
.expect("Supported room version has rules"),
) {
Ok(t) => t, Ok(t) => t,
Err(e) => { Err(e) => {
// Event could not be converted to canonical json // Event could not be converted to canonical json
@@ -1756,7 +1761,12 @@ async fn append_member_pdu(
// We do not add the event_id field to the pdu here because of signature and hashes checks // We do not add the event_id field to the pdu here because of signature and hashes checks
let room_version_id = services().rooms.state.get_room_version(room_id)?; let room_version_id = services().rooms.state.get_room_version(room_id)?;
let (event_id, mut value) = match gen_event_id_canonical_json(pdu, &room_version_id) { let (event_id, mut value) = match gen_event_id_canonical_json(
pdu,
&room_version_id
.rules()
.expect("Supported room version has rules"),
) {
Ok(t) => t, Ok(t) => t,
Err(_) => { Err(_) => {
// Event could not be converted to canonical json // Event could not be converted to canonical json
@@ -1845,7 +1855,10 @@ async fn append_member_pdu(
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut value, &mut value,
&room_version_id, &room_version_id
.rules()
.expect("Supported room version has rules")
.redaction,
) )
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Failed to sign event."))?; .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Failed to sign event."))?;
} }
@@ -2099,15 +2112,23 @@ pub async fn create_invite_route(
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut signed_event, &mut signed_event,
&room_version, &room_version
.rules()
.expect("Supported room version has rules")
.redaction,
) )
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Failed to sign event."))?; .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Failed to sign event."))?;
// Generate event id // Generate event id
let event_id = EventId::parse(format!( let event_id = EventId::parse(format!(
"${}", "${}",
ruma::signatures::reference_hash(&signed_event, &room_version) ruma::signatures::reference_hash(
.expect("Event format validated when event was hashed") &signed_event,
&room_version
.rules()
.expect("Supported room version has rules")
)
.expect("Event format validated when event was hashed")
)) ))
.expect("ruma's reference hashes are valid event ids"); .expect("ruma's reference hashes are valid event ids");

View File

@@ -19,6 +19,7 @@ use http::{
header::{self, HeaderName, CONTENT_SECURITY_POLICY}, header::{self, HeaderName, CONTENT_SECURITY_POLICY},
Method, StatusCode, Uri, Method, StatusCode, Uri,
}; };
use opentelemetry::trace::TracerProvider;
use ruma::api::{ use ruma::api::{
client::{ client::{
error::{Error as RumaError, ErrorBody, ErrorKind}, error::{Error as RumaError, ErrorBody, ErrorKind},
@@ -105,15 +106,21 @@ async fn main() {
config.warn_deprecated(); config.warn_deprecated();
if config.allow_jaeger { let jaeger = if config.allow_jaeger {
opentelemetry::global::set_text_map_propagator( opentelemetry::global::set_text_map_propagator(
opentelemetry_jaeger_propagator::Propagator::new(), opentelemetry_jaeger_propagator::Propagator::new(),
); );
let tracer = opentelemetry_otlp::new_pipeline() let exporter = opentelemetry_otlp::SpanExporter::builder()
.tracing() .with_tonic()
.with_exporter(opentelemetry_otlp::new_exporter().tonic()) .build()
.install_batch(opentelemetry_sdk::runtime::Tokio)
.unwrap(); .unwrap();
let provider = opentelemetry_sdk::trace::SdkTracerProvider::builder()
.with_simple_exporter(exporter)
.build();
let tracer = provider.tracer("");
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
let filter_layer = match EnvFilter::try_new(&config.log) { let filter_layer = match EnvFilter::try_new(&config.log) {
@@ -130,6 +137,8 @@ async fn main() {
.with(filter_layer) .with(filter_layer)
.with(telemetry); .with(telemetry);
tracing::subscriber::set_global_default(subscriber).unwrap(); tracing::subscriber::set_global_default(subscriber).unwrap();
Some(provider)
} else if config.tracing_flame { } else if config.tracing_flame {
let registry = tracing_subscriber::Registry::default(); let registry = tracing_subscriber::Registry::default();
let (flame_layer, _guard) = let (flame_layer, _guard) =
@@ -140,6 +149,8 @@ async fn main() {
let subscriber = registry.with(filter_layer).with(flame_layer); let subscriber = registry.with(filter_layer).with(flame_layer);
tracing::subscriber::set_global_default(subscriber).unwrap(); tracing::subscriber::set_global_default(subscriber).unwrap();
None
} else { } else {
let registry = tracing_subscriber::Registry::default(); let registry = tracing_subscriber::Registry::default();
let fmt_layer = tracing_subscriber::fmt::Layer::new(); let fmt_layer = tracing_subscriber::fmt::Layer::new();
@@ -153,7 +164,9 @@ async fn main() {
let subscriber = registry.with(filter_layer).with(fmt_layer); let subscriber = registry.with(filter_layer).with(fmt_layer);
tracing::subscriber::set_global_default(subscriber).unwrap(); tracing::subscriber::set_global_default(subscriber).unwrap();
}
None
};
// This is needed for opening lots of file descriptors, which tends to // This is needed for opening lots of file descriptors, which tends to
// happen more often when using RocksDB and making lots of federation // happen more often when using RocksDB and making lots of federation
@@ -171,13 +184,12 @@ async fn main() {
std::process::exit(1); std::process::exit(1);
}; };
let config = &services().globals.config;
info!("Starting server"); info!("Starting server");
run_server().await.unwrap(); run_server().await.unwrap();
if config.allow_jaeger { if let Some(provider) = jaeger {
opentelemetry::global::shutdown_tracer_provider(); let _ = provider.shutdown();
} }
} }

View File

@@ -32,6 +32,7 @@ use ruma::{
}, },
TimelineEventType, TimelineEventType,
}, },
room_version_rules::RoomVersionRules,
EventId, MilliSecondsSinceUnixEpoch, MxcUri, OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId, EventId, MilliSecondsSinceUnixEpoch, MxcUri, OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId,
OwnedServerName, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId, OwnedServerName, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId,
}; };
@@ -685,7 +686,7 @@ impl Service {
let string = body[1..body.len() - 1].join("\n"); let string = body[1..body.len() - 1].join("\n");
match serde_json::from_str(&string) { match serde_json::from_str(&string) {
Ok(value) => { Ok(value) => {
match ruma::signatures::reference_hash(&value, &RoomVersionId::V6) { match ruma::signatures::reference_hash(&value, &RoomVersionRules::V11) {
Ok(hash) => { Ok(hash) => {
let event_id = EventId::parse(format!("${hash}")); let event_id = EventId::parse(format!("${hash}"));
@@ -1160,6 +1161,7 @@ impl Service {
thumbnail_info: None, thumbnail_info: None,
thumbnail_source: None, thumbnail_source: None,
blurhash: None, blurhash: None,
thumbhash: None,
})), })),
}) })
} else { } else {
@@ -1534,7 +1536,7 @@ impl Service {
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut value, &mut value,
&room_version_id, &room_version_id.rules().expect("Supported room version has rules").redaction,
) { ) {
RoomMessageEventContent::text_plain(format!("Invalid event: {e}")) RoomMessageEventContent::text_plain(format!("Invalid event: {e}"))
} else { } else {

View File

@@ -12,7 +12,7 @@ use crate::{
services, Config, Error, Result, services, Config, Error, Result,
}; };
use futures_util::FutureExt; use futures_util::FutureExt;
use hickory_resolver::TokioAsyncResolver; use hickory_resolver::TokioResolver;
use hyper_util::client::legacy::connect::dns::{GaiResolver, Name as HyperName}; use hyper_util::client::legacy::connect::dns::{GaiResolver, Name as HyperName};
use reqwest::dns::{Addrs, Name, Resolve, Resolving}; use reqwest::dns::{Addrs, Name, Resolve, Resolving};
use ruma::{ use ruma::{
@@ -54,7 +54,7 @@ pub struct Service {
pub config: Config, pub config: Config,
allow_registration: RwLock<bool>, allow_registration: RwLock<bool>,
keypair: Arc<ruma::signatures::Ed25519KeyPair>, keypair: Arc<ruma::signatures::Ed25519KeyPair>,
dns_resolver: TokioAsyncResolver, dns_resolver: TokioResolver,
jwt_decoding_key: Option<jsonwebtoken::DecodingKey>, jwt_decoding_key: Option<jsonwebtoken::DecodingKey>,
federation_client: reqwest::Client, federation_client: reqwest::Client,
default_client: reqwest::Client, default_client: reqwest::Client,
@@ -200,13 +200,15 @@ impl Service {
db, db,
config, config,
keypair: Arc::new(keypair), keypair: Arc::new(keypair),
dns_resolver: TokioAsyncResolver::tokio_from_system_conf().map_err(|e| { dns_resolver: TokioResolver::builder_tokio()
error!( .map_err(|e| {
"Failed to set up trust dns resolver with system config: {}", error!(
e "Failed to set up trust dns resolver with system config: {}",
); e
Error::bad_config("Failed to set up trust dns resolver with system config.") );
})?, Error::bad_config("Failed to set up trust dns resolver with system config.")
})?
.build(),
actual_destination_cache: Arc::new(RwLock::new(WellKnownMap::new())), actual_destination_cache: Arc::new(RwLock::new(WellKnownMap::new())),
tls_name_override, tls_name_override,
federation_client, federation_client,
@@ -368,7 +370,7 @@ impl Service {
self.config.well_known.client.clone() self.config.well_known.client.clone()
} }
pub fn dns_resolver(&self) -> &TokioAsyncResolver { pub fn dns_resolver(&self) -> &TokioResolver {
&self.dns_resolver &self.dns_resolver
} }

View File

@@ -8,9 +8,10 @@ use ruma::{
AnyEphemeralRoomEvent, AnyMessageLikeEvent, AnyStateEvent, AnyStrippedStateEvent, AnyEphemeralRoomEvent, AnyMessageLikeEvent, AnyStateEvent, AnyStrippedStateEvent,
AnySyncStateEvent, AnySyncTimelineEvent, AnyTimelineEvent, StateEvent, TimelineEventType, AnySyncStateEvent, AnySyncTimelineEvent, AnyTimelineEvent, StateEvent, TimelineEventType,
}, },
room_version_rules::{RedactionRules, RoomVersionRules},
serde::Raw, serde::Raw,
state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch,
OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId, UInt, UserId, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UInt, UserId,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{ use serde_json::{
@@ -54,14 +55,14 @@ impl PduEvent {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
pub fn redact( pub fn redact(
&mut self, &mut self,
room_version_id: RoomVersionId, redaction_rules: RedactionRules,
reason: &PduEvent, reason: &PduEvent,
) -> crate::Result<()> { ) -> crate::Result<()> {
self.unsigned = None; self.unsigned = None;
let mut content = serde_json::from_str(self.content.get()) let mut content = serde_json::from_str(self.content.get())
.map_err(|_| Error::bad_database("PDU in db has invalid content."))?; .map_err(|_| Error::bad_database("PDU in db has invalid content."))?;
redact_content_in_place(&mut content, &room_version_id, self.kind.to_string()) redact_content_in_place(&mut content, &redaction_rules, self.kind.to_string())
.map_err(|e| Error::RedactionError(self.sender.server_name().to_owned(), e))?; .map_err(|e| Error::RedactionError(self.sender.server_name().to_owned(), e))?;
self.unsigned = Some(to_raw_value(&json!({ self.unsigned = Some(to_raw_value(&json!({
@@ -433,7 +434,7 @@ impl Ord for PduEvent {
/// Returns a tuple of the new `EventId` and the PDU as a `BTreeMap<String, CanonicalJsonValue>`. /// Returns a tuple of the new `EventId` and the PDU as a `BTreeMap<String, CanonicalJsonValue>`.
pub(crate) fn gen_event_id_canonical_json( pub(crate) fn gen_event_id_canonical_json(
pdu: &RawJsonValue, pdu: &RawJsonValue,
room_version_id: &RoomVersionId, room_version_rules: &RoomVersionRules,
) -> crate::Result<(OwnedEventId, CanonicalJsonObject)> { ) -> crate::Result<(OwnedEventId, CanonicalJsonObject)> {
let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| { let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| {
warn!("Error parsing incoming event {:?}: {:?}", pdu, e); warn!("Error parsing incoming event {:?}: {:?}", pdu, e);
@@ -443,7 +444,7 @@ pub(crate) fn gen_event_id_canonical_json(
let event_id = format!( let event_id = format!(
"${}", "${}",
// Anything higher than version3 behaves the same // Anything higher than version3 behaves the same
ruma::signatures::reference_hash(&value, room_version_id) ruma::signatures::reference_hash(&value, room_version_rules)
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid PDU format"))? .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid PDU format"))?
) )
.try_into() .try_into()

View File

@@ -122,7 +122,7 @@ impl Service {
.await?; .await?;
let mut servers = response.servers; let mut servers = response.servers;
servers.shuffle(&mut rand::thread_rng()); servers.shuffle(&mut rand::rng());
return Ok(get_alias::v3::Response::new(response.room_id, servers)); return Ok(get_alias::v3::Response::new(response.room_id, servers));
} }

View File

@@ -31,7 +31,8 @@ use ruma::{
StateEventType, TimelineEventType, StateEventType, TimelineEventType,
}, },
int, int,
state_res::{self, RoomVersion, StateMap}, room_version_rules::{AuthorizationRules, RoomVersionRules},
state_res::{self, StateMap},
uint, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, uint, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch,
OwnedServerName, OwnedServerSigningKeyId, RoomId, RoomVersionId, ServerName, OwnedServerName, OwnedServerSigningKeyId, RoomId, RoomVersionId, ServerName,
}; };
@@ -150,7 +151,9 @@ impl Service {
origin, origin,
&create_event, &create_event,
room_id, room_id,
room_version_id, &room_version_id
.rules()
.expect("Supported room version has rules"),
pub_key_map, pub_key_map,
incoming_pdu.prev_events.clone(), incoming_pdu.prev_events.clone(),
) )
@@ -319,8 +322,9 @@ impl Service {
})?; })?;
let room_version_id = &create_event_content.room_version; let room_version_id = &create_event_content.room_version;
let room_version = let room_version_rules = room_version_id
RoomVersion::new(room_version_id).expect("room version is supported"); .rules()
.expect("Supported room version has rules");
// TODO: For RoomVersion6 we must check that Raw<..> is canonical do we anywhere?: https://matrix.org/docs/spec/rooms/v6#canonical-json // TODO: For RoomVersion6 we must check that Raw<..> is canonical do we anywhere?: https://matrix.org/docs/spec/rooms/v6#canonical-json
@@ -362,7 +366,7 @@ impl Service {
); );
let mut val = let mut val =
match ruma::signatures::verify_event(&filtered_keys, &value, room_version_id) { match ruma::signatures::verify_event(&filtered_keys, &value, &room_version_rules) {
Err(e) => { Err(e) => {
// Drop // Drop
warn!("Dropping bad event {}: {}", event_id, e,); warn!("Dropping bad event {}: {}", event_id, e,);
@@ -374,7 +378,11 @@ impl Service {
Ok(ruma::signatures::Verified::Signatures) => { Ok(ruma::signatures::Verified::Signatures) => {
// Redact // Redact
warn!("Calculated hash does not match: {}", event_id); warn!("Calculated hash does not match: {}", event_id);
let obj = match ruma::canonical_json::redact(value, room_version_id, None) { let obj = match ruma::canonical_json::redact(
value,
&room_version_rules.redaction,
None,
) {
Ok(obj) => obj, Ok(obj) => obj,
Err(_) => { Err(_) => {
return Err(Error::BadRequest( return Err(Error::BadRequest(
@@ -426,7 +434,7 @@ impl Service {
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
create_event, create_event,
room_id, room_id,
room_version_id, &room_version_rules,
pub_key_map, pub_key_map,
) )
.await; .await;
@@ -483,10 +491,12 @@ impl Service {
)); ));
} }
if !state_res::event_auth::auth_check(&room_version, &incoming_pdu, |k, s| { if state_res::event_auth::auth_check(
auth_events.get(&(k.to_string().into(), s.to_owned())) &room_version_rules.authorization,
}) &incoming_pdu,
.map_err(|_e| Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed"))? |k, s| auth_events.get(&(k.to_string().into(), s.to_owned())),
)
.is_err()
{ {
return Err(Error::BadRequest( return Err(Error::BadRequest(
ErrorKind::InvalidParam, ErrorKind::InvalidParam,
@@ -543,7 +553,9 @@ impl Service {
})?; })?;
let room_version_id = &create_event_content.room_version; let room_version_id = &create_event_content.room_version;
let room_version = RoomVersion::new(room_version_id).expect("room version is supported"); let room_version_rules = room_version_id
.rules()
.expect("Supported room version has rules");
// 10. Fetch missing state and auth chain events by calling /state_ids at backwards extremities // 10. Fetch missing state and auth chain events by calling /state_ids at backwards extremities
// doing all the checks in this list starting at 1. These are not timeline events. // doing all the checks in this list starting at 1. These are not timeline events.
@@ -674,14 +686,21 @@ impl Service {
let lock = services().globals.stateres_mutex.lock(); let lock = services().globals.stateres_mutex.lock();
let result = let result = state_res::resolve(
state_res::resolve(room_version_id, &fork_states, auth_chain_sets, |id| { &room_version_id
.rules()
.expect("Supported room version has rules")
.authorization,
&fork_states,
auth_chain_sets,
|id| {
let res = services().rooms.timeline.get_pdu(id); let res = services().rooms.timeline.get_pdu(id);
if let Err(e) = &res { if let Err(e) = &res {
error!("LOOK AT ME Failed to fetch event: {}", e); error!("LOOK AT ME Failed to fetch event: {}", e);
} }
res.ok().flatten() res.ok().flatten()
}); },
);
drop(lock); drop(lock);
state_at_incoming_event = match result { state_at_incoming_event = match result {
@@ -734,7 +753,7 @@ impl Service {
&collect, &collect,
create_event, create_event,
room_id, room_id,
room_version_id, &room_version_rules,
pub_key_map, pub_key_map,
) )
.await; .await;
@@ -789,8 +808,10 @@ impl Service {
debug!("Starting auth check"); debug!("Starting auth check");
// 11. Check the auth of the event passes based on the state of the event // 11. Check the auth of the event passes based on the state of the event
let check_result = if state_res::event_auth::auth_check(
state_res::event_auth::auth_check(&room_version, &incoming_pdu, |k, s| { &room_version_rules.authorization,
&incoming_pdu,
|k, s| {
services() services()
.rooms .rooms
.short .short
@@ -799,10 +820,10 @@ impl Service {
.flatten() .flatten()
.and_then(|shortstatekey| state_at_incoming_event.get(&shortstatekey)) .and_then(|shortstatekey| state_at_incoming_event.get(&shortstatekey))
.and_then(|event_id| services().rooms.timeline.get_pdu(event_id).ok().flatten()) .and_then(|event_id| services().rooms.timeline.get_pdu(event_id).ok().flatten())
}) },
.map_err(|_e| Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed."))?; )
.is_err()
if !check_result { {
return Err(Error::bad_database( return Err(Error::bad_database(
"Event has failed auth check with state at the event.", "Event has failed auth check with state at the event.",
)); ));
@@ -816,12 +837,15 @@ impl Service {
&incoming_pdu.sender, &incoming_pdu.sender,
incoming_pdu.state_key.as_deref(), incoming_pdu.state_key.as_deref(),
&incoming_pdu.content, &incoming_pdu.content,
&room_version_rules.authorization,
)?; )?;
let soft_fail = !state_res::event_auth::auth_check(&room_version, &incoming_pdu, |k, s| { let soft_fail = state_res::event_auth::auth_check(
auth_events.get(&(k.clone(), s.to_owned())) &room_version_rules.authorization,
}) &incoming_pdu,
.map_err(|_e| Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed."))? |k, s| auth_events.get(&(k.clone(), s.to_owned())),
)
.is_err()
|| incoming_pdu.kind == TimelineEventType::RoomRedaction || incoming_pdu.kind == TimelineEventType::RoomRedaction
&& match room_version_id { && match room_version_id {
RoomVersionId::V1 RoomVersionId::V1
@@ -932,7 +956,7 @@ impl Service {
} }
let new_room_state = self let new_room_state = self
.resolve_state(room_id, room_version_id, state_after) .resolve_state(room_id, &room_version_rules.authorization, state_after)
.await?; .await?;
// Set the new room state to the resolved state // Set the new room state to the resolved state
@@ -1009,7 +1033,7 @@ impl Service {
async fn resolve_state( async fn resolve_state(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
room_version_id: &RoomVersionId, auth_rules: &AuthorizationRules,
incoming_state: HashMap<u64, Arc<EventId>>, incoming_state: HashMap<u64, Arc<EventId>>,
) -> Result<Arc<HashSet<CompressedStateEvent>>> { ) -> Result<Arc<HashSet<CompressedStateEvent>>> {
debug!("Loading current room state ids"); debug!("Loading current room state ids");
@@ -1068,12 +1092,8 @@ impl Service {
}; };
let lock = services().globals.stateres_mutex.lock(); let lock = services().globals.stateres_mutex.lock();
let state = match state_res::resolve( let state = match state_res::resolve(auth_rules, &fork_states, auth_chain_sets, fetch_event)
room_version_id, {
&fork_states,
auth_chain_sets,
fetch_event,
) {
Ok(new_state) => new_state, Ok(new_state) => new_state,
Err(_) => { Err(_) => {
return Err(Error::bad_database("State resolution failed, either an event could not be found or deserialization")); return Err(Error::bad_database("State resolution failed, either an event could not be found or deserialization"));
@@ -1118,7 +1138,7 @@ impl Service {
events: &'a [Arc<EventId>], events: &'a [Arc<EventId>],
create_event: &'a PduEvent, create_event: &'a PduEvent,
room_id: &'a RoomId, room_id: &'a RoomId,
room_version_id: &'a RoomVersionId, room_version_rules: &'a RoomVersionRules,
pub_key_map: &'a RwLock<BTreeMap<String, SigningKeys>>, pub_key_map: &'a RwLock<BTreeMap<String, SigningKeys>>,
) -> AsyncRecursiveType<'a, Vec<(Arc<PduEvent>, Option<BTreeMap<String, CanonicalJsonValue>>)>> ) -> AsyncRecursiveType<'a, Vec<(Arc<PduEvent>, Option<BTreeMap<String, CanonicalJsonValue>>)>>
{ {
@@ -1207,7 +1227,8 @@ impl Service {
Ok(res) => { Ok(res) => {
info!("Got {} over federation", next_id); info!("Got {} over federation", next_id);
let (calculated_event_id, value) = let (calculated_event_id, value) =
match pdu::gen_event_id_canonical_json(&res.pdu, room_version_id) { match pdu::gen_event_id_canonical_json(&res.pdu, room_version_rules)
{
Ok(t) => t, Ok(t) => t,
Err(_) => { Err(_) => {
back_off((*next_id).to_owned()).await; back_off((*next_id).to_owned()).await;
@@ -1301,7 +1322,7 @@ impl Service {
origin: &ServerName, origin: &ServerName,
create_event: &PduEvent, create_event: &PduEvent,
room_id: &RoomId, room_id: &RoomId,
room_version_id: &RoomVersionId, room_version_rules: &RoomVersionRules,
pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>, pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>,
initial_set: Vec<Arc<EventId>>, initial_set: Vec<Arc<EventId>>,
) -> Result<( ) -> Result<(
@@ -1327,7 +1348,7 @@ impl Service {
&[prev_event_id.clone()], &[prev_event_id.clone()],
create_event, create_event,
room_id, room_id,
room_version_id, room_version_rules,
pub_key_map, pub_key_map,
) )
.await .await
@@ -1456,7 +1477,7 @@ impl Service {
&self, &self,
pdu: &RawJsonValue, pdu: &RawJsonValue,
servers: &mut BTreeMap<OwnedServerName, BTreeMap<OwnedServerSigningKeyId, QueryCriteria>>, servers: &mut BTreeMap<OwnedServerName, BTreeMap<OwnedServerSigningKeyId, QueryCriteria>>,
room_version: &RoomVersionId, room_version_rules: &RoomVersionRules,
pub_key_map: &mut RwLockWriteGuard<'_, BTreeMap<String, SigningKeys>>, pub_key_map: &mut RwLockWriteGuard<'_, BTreeMap<String, SigningKeys>>,
) -> Result<()> { ) -> Result<()> {
let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| { let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| {
@@ -1466,7 +1487,7 @@ impl Service {
let event_id = format!( let event_id = format!(
"${}", "${}",
ruma::signatures::reference_hash(&value, room_version) ruma::signatures::reference_hash(&value, room_version_rules)
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid PDU format"))? .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid PDU format"))?
); );
let event_id = <&EventId>::try_from(event_id.as_str()) let event_id = <&EventId>::try_from(event_id.as_str())
@@ -1548,7 +1569,7 @@ impl Service {
pub(crate) async fn fetch_join_signing_keys( pub(crate) async fn fetch_join_signing_keys(
&self, &self,
event: &create_join_event::v2::Response, event: &create_join_event::v2::Response,
room_version: &RoomVersionId, room_version_rules: &RoomVersionRules,
pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>, pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>,
) -> Result<()> { ) -> Result<()> {
let mut servers: BTreeMap< let mut servers: BTreeMap<
@@ -1563,12 +1584,12 @@ impl Service {
// Servers we couldn't find in the cache will be added to `servers` // Servers we couldn't find in the cache will be added to `servers`
for pdu in &event.room_state.state { for pdu in &event.room_state.state {
let _ = self let _ = self
.get_server_keys_from_cache(pdu, &mut servers, room_version, &mut pkm) .get_server_keys_from_cache(pdu, &mut servers, room_version_rules, &mut pkm)
.await; .await;
} }
for pdu in &event.room_state.auth_chain { for pdu in &event.room_state.auth_chain {
let _ = self let _ = self
.get_server_keys_from_cache(pdu, &mut servers, room_version, &mut pkm) .get_server_keys_from_cache(pdu, &mut servers, room_version_rules, &mut pkm)
.await; .await;
} }

View File

@@ -20,6 +20,7 @@ use ruma::{
}, },
TimelineEventType, TimelineEventType,
}, },
room_version_rules::RoomVersionRules,
state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch,
OwnedEventId, OwnedServerName, OwnedUserId, RoomId, RoomVersionId, UserId, OwnedEventId, OwnedServerName, OwnedUserId, RoomId, RoomVersionId, UserId,
}; };
@@ -91,12 +92,15 @@ impl Service {
} }
_ => return Err(Error::BadServerResponse("Room version is not supported")), _ => return Err(Error::BadServerResponse("Room version is not supported")),
}; };
let room_version_rules = room_version_id
.rules()
.expect("Supported room version has rules");
let (event_id, mut join_event, _) = self.populate_membership_template( let (event_id, mut join_event, _) = self.populate_membership_template(
&make_join_response.event, &make_join_response.event,
sender_user, sender_user,
reason, reason,
&room_version_id, &room_version_rules,
MembershipState::Join, MembershipState::Join,
)?; )?;
@@ -119,7 +123,7 @@ impl Service {
if let Some(signed_raw) = &send_join_response.room_state.event { if let Some(signed_raw) = &send_join_response.room_state.event {
info!("There is a signed event. This room is probably using restricted joins. Adding signature to our event"); info!("There is a signed event. This room is probably using restricted joins. Adding signature to our event");
let (signed_event_id, signed_value) = let (signed_event_id, signed_value) =
match gen_event_id_canonical_json(signed_raw, &room_version_id) { match gen_event_id_canonical_json(signed_raw, &room_version_rules) {
Ok(t) => t, Ok(t) => t,
Err(_) => { Err(_) => {
// Event could not be converted to canonical json // Event could not be converted to canonical json
@@ -178,7 +182,13 @@ impl Service {
services() services()
.rooms .rooms
.event_handler .event_handler
.fetch_join_signing_keys(&send_join_response, &room_version_id, &pub_key_map) .fetch_join_signing_keys(
&send_join_response,
&room_version_id
.rules()
.expect("Supported room version has rules"),
&pub_key_map,
)
.await?; .await?;
info!("Going through send_join response room_state"); info!("Going through send_join response room_state");
@@ -230,8 +240,11 @@ impl Service {
} }
info!("Running send_join auth check"); info!("Running send_join auth check");
let authenticated = state_res::event_auth::auth_check( if let Err(e) = state_res::event_auth::auth_check(
&state_res::RoomVersion::new(&room_version_id).expect("room version is supported"), &room_version_id
.rules()
.expect("Supported room version has rules")
.authorization,
&parsed_join_pdu, &parsed_join_pdu,
|k, s| { |k, s| {
services() services()
@@ -248,18 +261,13 @@ impl Service {
) )
.ok()? .ok()?
}, },
) ) {
.map_err(|e| {
warn!("Auth check failed: {e}"); warn!("Auth check failed: {e}");
Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed")
})?;
if !authenticated {
return Err(Error::BadRequest( return Err(Error::BadRequest(
ErrorKind::InvalidParam, ErrorKind::InvalidParam,
"Auth check failed", "Auth check failed",
)); ));
} };
info!("Saving state from send_join"); info!("Saving state from send_join");
let (statehash_before_join, new, removed) = let (statehash_before_join, new, removed) =
@@ -424,7 +432,9 @@ impl Service {
&make_join_response.event, &make_join_response.event,
sender_user, sender_user,
reason, reason,
&room_version_id, &room_version_id
.rules()
.expect("Supported room version has rules"),
MembershipState::Join, MembershipState::Join,
)?; )?;
@@ -442,8 +452,12 @@ impl Service {
.await?; .await?;
let pdu = if let Some(signed_raw) = send_join_response.room_state.event { let pdu = if let Some(signed_raw) = send_join_response.room_state.event {
let (signed_event_id, signed_pdu) = let (signed_event_id, signed_pdu) = gen_event_id_canonical_json(
gen_event_id_canonical_json(&signed_raw, &room_version_id)?; &signed_raw,
&room_version_id
.rules()
.expect("Supported room version has rules"),
)?;
if signed_event_id != event_id { if signed_event_id != event_id {
return Err(Error::BadServerResponse( return Err(Error::BadServerResponse(
@@ -491,7 +505,7 @@ impl Service {
member_template: &RawJsonValue, member_template: &RawJsonValue,
sender_user: &UserId, sender_user: &UserId,
reason: Option<String>, reason: Option<String>,
room_version_id: &RoomVersionId, room_version_rules: &RoomVersionRules,
membership: MembershipState, membership: MembershipState,
) -> Result<(OwnedEventId, BTreeMap<String, CanonicalJsonValue>, bool), Error> { ) -> Result<(OwnedEventId, BTreeMap<String, CanonicalJsonValue>, bool), Error> {
let mut member_event_stub: CanonicalJsonObject = let mut member_event_stub: CanonicalJsonObject =
@@ -545,13 +559,13 @@ impl Service {
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut member_event_stub, &mut member_event_stub,
room_version_id, &room_version_rules.redaction,
) )
.expect("event is valid, we just created it"); .expect("event is valid, we just created it");
let event_id = format!( let event_id = format!(
"${}", "${}",
ruma::signatures::reference_hash(&member_event_stub, room_version_id) ruma::signatures::reference_hash(&member_event_stub, room_version_rules)
.expect("Event format validated when event was hashed") .expect("Event format validated when event was hashed")
); );
@@ -616,8 +630,13 @@ async fn validate_and_add_event_id(
})?; })?;
let event_id = EventId::parse(format!( let event_id = EventId::parse(format!(
"${}", "${}",
ruma::signatures::reference_hash(&value, room_version) ruma::signatures::reference_hash(
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid PDU format"))? &value,
&room_version
.rules()
.expect("Supported room version has rules")
)
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid PDU format"))?
)) ))
.expect("ruma's reference hashes are valid event ids"); .expect("ruma's reference hashes are valid event ids");
@@ -683,7 +702,13 @@ async fn validate_and_add_event_id(
.globals .globals
.filter_keys_server_map(unfiltered_keys, origin_server_ts, room_version); .filter_keys_server_map(unfiltered_keys, origin_server_ts, room_version);
if let Err(e) = ruma::signatures::verify_event(&keys, &value, room_version) { if let Err(e) = ruma::signatures::verify_event(
&keys,
&value,
&room_version
.rules()
.expect("Supported room version has rules"),
) {
warn!("Event {} failed verification {:?} {}", event_id, pdu, e); warn!("Event {} failed verification {:?} {}", event_id, pdu, e);
back_off(event_id).await; back_off(event_id).await;
return Err(Error::BadServerResponse("Event failed verification.")); return Err(Error::BadServerResponse("Event failed verification."));

View File

@@ -12,6 +12,7 @@ use ruma::{
AnyStrippedStateEvent, StateEventType, TimelineEventType, AnyStrippedStateEvent, StateEventType, TimelineEventType,
RECOMMENDED_STRIPPED_STATE_EVENT_TYPES, RECOMMENDED_STRIPPED_STATE_EVENT_TYPES,
}, },
room_version_rules::AuthorizationRules,
serde::Raw, serde::Raw,
state_res::{self, StateMap}, state_res::{self, StateMap},
EventId, OwnedEventId, RoomId, RoomVersionId, UserId, EventId, OwnedEventId, RoomId, RoomVersionId, UserId,
@@ -338,6 +339,7 @@ impl Service {
sender: &UserId, sender: &UserId,
state_key: Option<&str>, state_key: Option<&str>,
content: &serde_json::value::RawValue, content: &serde_json::value::RawValue,
auth_rules: &AuthorizationRules,
) -> Result<StateMap<Arc<PduEvent>>> { ) -> Result<StateMap<Arc<PduEvent>>> {
let shortstatehash = if let Some(current_shortstatehash) = let shortstatehash = if let Some(current_shortstatehash) =
services().rooms.state.get_room_shortstatehash(room_id)? services().rooms.state.get_room_shortstatehash(room_id)?
@@ -347,8 +349,9 @@ impl Service {
return Ok(HashMap::new()); return Ok(HashMap::new());
}; };
let auth_events = state_res::auth_types_for_event(kind, sender, state_key, content) let auth_events =
.expect("content is a valid JSON object"); state_res::auth_types_for_event(kind, sender, state_key, content, auth_rules)
.expect("content is a valid JSON object");
let mut sauthevents = auth_events let mut sauthevents = auth_events
.into_iter() .into_iter()

View File

@@ -21,7 +21,7 @@ use ruma::{
GlobalAccountDataEventType, StateEventType, TimelineEventType, GlobalAccountDataEventType, StateEventType, TimelineEventType,
}, },
push::{Action, Ruleset, Tweak}, push::{Action, Ruleset, Tweak},
state_res::{self, Event, RoomVersion}, state_res::{self, Event},
uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch,
OwnedEventId, OwnedRoomId, OwnedServerName, RoomId, RoomVersionId, ServerName, UserId, OwnedEventId, OwnedRoomId, OwnedServerName, RoomId, RoomVersionId, ServerName, UserId,
}; };
@@ -701,7 +701,9 @@ impl Service {
} }
})?; })?;
let room_version = RoomVersion::new(&room_version_id).expect("room version is supported"); let room_version_rules = room_version_id
.rules()
.expect("Supported room version has rules");
let auth_events = services().rooms.state.get_auth_events( let auth_events = services().rooms.state.get_auth_events(
room_id, room_id,
@@ -709,6 +711,7 @@ impl Service {
sender, sender,
state_key.as_deref(), state_key.as_deref(),
&content, &content,
&room_version_rules.authorization,
)?; )?;
// Our depth is the maximum depth of prev_events + 1 // Our depth is the maximum depth of prev_events + 1
@@ -766,15 +769,11 @@ impl Service {
signatures: None, signatures: None,
}; };
let auth_check = state_res::auth_check(&room_version, &pdu, |k, s| { if state_res::auth_check(&room_version_rules.authorization, &pdu, |k, s| {
auth_events.get(&(k.clone(), s.to_owned())) auth_events.get(&(k.clone(), s.to_owned()))
}) })
.map_err(|e| { .is_err()
error!("{:?}", e); {
Error::bad_database("Auth check failed.")
})?;
if !auth_check {
return Err(Error::BadRequest( return Err(Error::BadRequest(
ErrorKind::forbidden(), ErrorKind::forbidden(),
"Event is not authorized.", "Event is not authorized.",
@@ -798,7 +797,7 @@ impl Service {
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut pdu_json, &mut pdu_json,
&room_version_id, &room_version_rules.redaction,
) { ) {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
@@ -818,8 +817,13 @@ impl Service {
// Generate event id // Generate event id
pdu.event_id = EventId::parse_arc(format!( pdu.event_id = EventId::parse_arc(format!(
"${}", "${}",
ruma::signatures::reference_hash(&pdu_json, &room_version_id) ruma::signatures::reference_hash(
.expect("Event format validated when event was hashed") &pdu_json,
&room_version_id
.rules()
.expect("Supported room version has rules")
)
.expect("Event format validated when event was hashed")
)) ))
.expect("ruma's reference hashes are valid event ids"); .expect("ruma's reference hashes are valid event ids");
@@ -1139,7 +1143,13 @@ impl Service {
} }
let room_version_id = services().rooms.state.get_room_version(&pdu.room_id)?; let room_version_id = services().rooms.state.get_room_version(&pdu.room_id)?;
pdu.redact(room_version_id, reason)?; pdu.redact(
room_version_id
.rules()
.expect("Supported room version has rules")
.redaction,
reason,
)?;
self.replace_pdu( self.replace_pdu(
&pdu_id, &pdu_id,

View File

@@ -60,7 +60,7 @@ pub enum Error {
BadDatabase(&'static str), BadDatabase(&'static str),
#[error("uiaa")] #[error("uiaa")]
Uiaa(UiaaInfo), Uiaa(UiaaInfo),
#[error("{}: {1}",.0.errcode())] #[error("{n}: {1}", n = _0.errcode())]
BadRequest(ErrorKind, &'static str), BadRequest(ErrorKind, &'static str),
#[error("{0}")] #[error("{0}")]
Conflict(&'static str), // This is only needed for when a room alias already exists Conflict(&'static str), // This is only needed for when a room alias already exists
@@ -70,6 +70,9 @@ pub enum Error {
#[cfg(feature = "conduit_bin")] #[cfg(feature = "conduit_bin")]
#[error("{0}")] #[error("{0}")]
PathError(#[from] axum::extract::rejection::PathRejection), PathError(#[from] axum::extract::rejection::PathRejection),
#[cfg(feature = "conduit_bin")]
#[error("{0}")]
TypedHeaderError(#[from] axum_extra::typed_header::TypedHeaderRejection),
#[error("{0}")] #[error("{0}")]
AdminCommand(&'static str), AdminCommand(&'static str),
#[error("from {0}: {1}")] #[error("from {0}: {1}")]

View File

@@ -59,8 +59,8 @@ pub fn string_from_bytes(bytes: &[u8]) -> Result<String, std::string::FromUtf8Er
} }
pub fn random_string(length: usize) -> String { pub fn random_string(length: usize) -> String {
thread_rng() rand::rng()
.sample_iter(&rand::distributions::Alphanumeric) .sample_iter(&rand::distr::Alphanumeric)
.take(length) .take(length)
.map(char::from) .map(char::from)
.collect() .collect()