1
0
Fork 0
mirror of https://gitlab.com/famedly/conduit.git synced 2025-06-27 16:35:59 +00:00

chore(crates): bump

This commit is contained in:
Matthias Ahouansou 2025-05-08 21:26:55 +01:00
parent bdc6dabe3a
commit 88c95d36a8
No known key found for this signature in database
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,14 +1041,22 @@ 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(
&leave_event_stub,
&room_version_id
.rules()
.expect("Supported room version has rules")
)
.expect("Event format validated when event was hashed") .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,14 +2112,22 @@ 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(
&signed_event,
&room_version
.rules()
.expect("Supported room version has rules")
)
.expect("Event format validated when event was hashed") .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()
.map_err(|e| {
error!( error!(
"Failed to set up trust dns resolver with system config: {}", "Failed to set up trust dns resolver with system config: {}",
e 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,7 +630,12 @@ 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(
&value,
&room_version
.rules()
.expect("Supported room version has rules")
)
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid PDU format"))? .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,7 +349,8 @@ 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 =
state_res::auth_types_for_event(kind, sender, state_key, content, auth_rules)
.expect("content is a valid JSON object"); .expect("content is a valid JSON object");
let mut sauthevents = auth_events let mut sauthevents = auth_events

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,7 +817,12 @@ 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(
&pdu_json,
&room_version_id
.rules()
.expect("Supported room version has rules")
)
.expect("Event format validated when event was hashed") .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()