Replace several expects with error coercions.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-07-08 12:36:03 +00:00
parent 23d188f612
commit cca0f20148
5 changed files with 53 additions and 74 deletions

View File

@@ -487,43 +487,32 @@ fn default_power_levels_content(
visibility: &room::Visibility, visibility: &room::Visibility,
users: BTreeMap<OwnedUserId, Int>, users: BTreeMap<OwnedUserId, Int>,
) -> Result<serde_json::Value> { ) -> Result<serde_json::Value> {
use serde_json::to_value;
let mut power_levels_content = let mut power_levels_content =
serde_json::to_value(RoomPowerLevelsEventContent { users, ..Default::default() }) to_value(RoomPowerLevelsEventContent { users, ..Default::default() })?;
.expect("event is valid, we just created it");
// secure proper defaults of sensitive/dangerous permissions that moderators // secure proper defaults of sensitive/dangerous permissions that moderators
// (power level 50) should not have easy access to // (power level 50) should not have easy access to
power_levels_content["events"]["m.room.power_levels"] = power_levels_content["events"]["m.room.power_levels"] = to_value(100)?;
serde_json::to_value(100).expect("100 is valid Value"); power_levels_content["events"]["m.room.server_acl"] = to_value(100)?;
power_levels_content["events"]["m.room.server_acl"] = power_levels_content["events"]["m.room.tombstone"] = to_value(100)?;
serde_json::to_value(100).expect("100 is valid Value"); power_levels_content["events"]["m.room.encryption"] = to_value(100)?;
power_levels_content["events"]["m.room.tombstone"] = power_levels_content["events"]["m.room.history_visibility"] = to_value(100)?;
serde_json::to_value(100).expect("100 is valid Value");
power_levels_content["events"]["m.room.encryption"] =
serde_json::to_value(100).expect("100 is valid Value");
power_levels_content["events"]["m.room.history_visibility"] =
serde_json::to_value(100).expect("100 is valid Value");
// always allow users to respond (not post new) to polls. this is primarily // always allow users to respond (not post new) to polls. this is primarily
// useful in read-only announcement rooms that post a public poll. // useful in read-only announcement rooms that post a public poll.
power_levels_content["events"]["org.matrix.msc3381.poll.response"] = power_levels_content["events"]["org.matrix.msc3381.poll.response"] = to_value(0)?;
serde_json::to_value(0).expect("0 is valid Value"); power_levels_content["events"]["m.poll.response"] = to_value(0)?;
power_levels_content["events"]["m.poll.response"] =
serde_json::to_value(0).expect("0 is valid Value");
// synapse does this too. clients do not expose these permissions. it prevents // synapse does this too. clients do not expose these permissions. it prevents
// default users from calling public rooms, for obvious reasons. // default users from calling public rooms, for obvious reasons.
if *visibility == room::Visibility::Public { if *visibility == room::Visibility::Public {
power_levels_content["events"]["m.call.invite"] = power_levels_content["events"]["m.call.invite"] = to_value(50)?;
serde_json::to_value(50).expect("50 is valid Value"); power_levels_content["events"]["m.call"] = to_value(50)?;
power_levels_content["events"]["m.call"] = power_levels_content["events"]["m.call.member"] = to_value(50)?;
serde_json::to_value(50).expect("50 is valid Value"); power_levels_content["events"]["org.matrix.msc3401.call"] = to_value(50)?;
power_levels_content["events"]["m.call.member"] = power_levels_content["events"]["org.matrix.msc3401.call.member"] = to_value(50)?;
serde_json::to_value(50).expect("50 is valid Value");
power_levels_content["events"]["org.matrix.msc3401.call"] =
serde_json::to_value(50).expect("50 is valid Value");
power_levels_content["events"]["org.matrix.msc3401.call.member"] =
serde_json::to_value(50).expect("50 is valid Value");
} }
if let Some(power_level_content_override) = power_level_content_override { if let Some(power_level_content_override) = power_level_content_override {

View File

@@ -17,7 +17,7 @@ use ruma::{
}; };
use serde_json::{json, value::to_raw_value}; use serde_json::{json, value::to_raw_value};
use tuwunel_core::{ use tuwunel_core::{
Error, Result, err, info, Err, Error, Result, err,
matrix::{Event, StateKey, pdu::PduBuilder}, matrix::{Event, StateKey, pdu::PduBuilder},
}; };
@@ -54,10 +54,8 @@ pub(crate) async fn upgrade_room_route(
TRANSFERABLE_STATE_EVENTS.is_sorted(), TRANSFERABLE_STATE_EVENTS.is_sorted(),
"TRANSFERABLE_STATE_EVENTS is not sorted" "TRANSFERABLE_STATE_EVENTS is not sorted"
); );
let sender_user = body
.sender_user let sender_user = body.sender_user();
.as_ref()
.expect("user is authenticated");
if !services if !services
.server .server
@@ -134,8 +132,7 @@ pub(crate) async fn upgrade_room_route(
create_event_content.insert( create_event_content.insert(
"creator".into(), "creator".into(),
json!(&sender_user).try_into().map_err(|e| { json!(&sender_user).try_into().map_err(|e| {
info!("Error forming creation event: {e}"); err!(Request(BadJson(error!("Error forming creation event: {e}"))))
Error::BadRequest(ErrorKind::BadJson, "Error forming creation event")
})?, })?,
); );
}, },
@@ -150,24 +147,20 @@ pub(crate) async fn upgrade_room_route(
"room_version".into(), "room_version".into(),
json!(&body.new_version) json!(&body.new_version)
.try_into() .try_into()
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Error forming creation event"))?, .map_err(|_| err!(Request(BadJson("Error forming creation event"))))?,
); );
create_event_content.insert( create_event_content.insert(
"predecessor".into(), "predecessor".into(),
json!(predecessor) json!(predecessor)
.try_into() .try_into()
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Error forming creation event"))?, .map_err(|_| err!(Request(BadJson("Error forming creation event"))))?,
); );
// Validate creation event content // Validate creation event content
if serde_json::from_str::<CanonicalJsonObject>( if serde_json::from_str::<CanonicalJsonObject>(to_raw_value(&create_event_content)?.get())
to_raw_value(&create_event_content) .is_err()
.expect("Error forming creation event")
.get(),
)
.is_err()
{ {
return Err(Error::BadRequest(ErrorKind::BadJson, "Error forming creation event")); return Err!(Request(BadJson("Error forming creation event")));
} }
services services
@@ -176,8 +169,7 @@ pub(crate) async fn upgrade_room_route(
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder { PduBuilder {
event_type: TimelineEventType::RoomCreate, event_type: TimelineEventType::RoomCreate,
content: to_raw_value(&create_event_content) content: to_raw_value(&create_event_content)?,
.expect("event is valid, we just created it"),
unsigned: None, unsigned: None,
state_key: Some(StateKey::new()), state_key: Some(StateKey::new()),
redacts: None, redacts: None,
@@ -205,8 +197,7 @@ pub(crate) async fn upgrade_room_route(
blurhash: services.users.blurhash(sender_user).await.ok(), blurhash: services.users.blurhash(sender_user).await.ok(),
reason: None, reason: None,
join_authorized_via_users_server: None, join_authorized_via_users_server: None,
}) })?,
.expect("event is valid, we just created it"),
unsigned: None, unsigned: None,
state_key: Some(sender_user.as_str().into()), state_key: Some(sender_user.as_str().into()),
redacts: None, redacts: None,

View File

@@ -447,12 +447,9 @@ async fn handle_left_room(
event_id: EventId::new(services.globals.server_name()), event_id: EventId::new(services.globals.server_name()),
sender: sender_user.to_owned(), sender: sender_user.to_owned(),
origin: None, origin: None,
origin_server_ts: utils::millis_since_unix_epoch() origin_server_ts: utils::millis_since_unix_epoch().try_into()?,
.try_into()
.expect("Timestamp is valid js_int value"),
kind: RoomMember, kind: RoomMember,
content: serde_json::from_str(r#"{"membership":"leave"}"#) content: serde_json::from_str(r#"{"membership":"leave"}"#)?,
.expect("this is valid JSON"),
state_key: Some(sender_user.as_str().into()), state_key: Some(sender_user.as_str().into()),
unsigned: None, unsigned: None,
// The following keys are dropped on conversion // The following keys are dropped on conversion

View File

@@ -69,10 +69,8 @@ where
incoming_pdu incoming_pdu
.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.as_str().to_owned())); .insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.as_str().to_owned()));
let pdu_event = serde_json::from_value::<PduEvent>( let pdu_event = serde_json::from_value::<PduEvent>(serde_json::to_value(&incoming_pdu)?)
serde_json::to_value(&incoming_pdu).expect("CanonicalJsonObj is a valid JsonValue"), .map_err(|e| err!(Request(BadJson(debug_warn!("Event is not a valid PDU: {e}")))))?;
)
.map_err(|e| err!(Request(BadJson(debug_warn!("Event is not a valid PDU: {e}")))))?;
check_room_id(room_id, &pdu_event)?; check_room_id(room_id, &pdu_event)?;

View File

@@ -26,8 +26,8 @@ pub async fn create_hash_and_sign_event(
pdu_builder: PduBuilder, pdu_builder: PduBuilder,
sender: &UserId, sender: &UserId,
room_id: &RoomId, room_id: &RoomId,
_mutex_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room // Take mutex guard to make sure users get the room state mutex
* state mutex */ _mutex_lock: &RoomMutexGuard,
) -> Result<(PduEvent, CanonicalJsonObject)> { ) -> Result<(PduEvent, CanonicalJsonObject)> {
let PduBuilder { let PduBuilder {
event_type, event_type,
@@ -100,36 +100,40 @@ pub async fn create_hash_and_sign_event(
} }
} }
let unsigned = if unsigned.is_empty() {
None
} else {
Some(to_raw_value(&unsigned)?)
};
let origin_server_ts = timestamp.map_or_else(
|| {
utils::millis_since_unix_epoch()
.try_into()
.expect("timestamp to UInt")
},
|ts| ts.get(),
);
let mut pdu = PduEvent { let mut pdu = PduEvent {
event_id: ruma::event_id!("$thiswillbefilledinlater").into(), event_id: ruma::event_id!("$thiswillbefilledinlater").into(),
room_id: room_id.to_owned(), room_id: room_id.to_owned(),
sender: sender.to_owned(), sender: sender.to_owned(),
origin: None, origin: None,
origin_server_ts: timestamp.map_or_else( origin_server_ts,
|| {
utils::millis_since_unix_epoch()
.try_into()
.expect("u64 fits into UInt")
},
|ts| ts.get(),
),
kind: event_type, kind: event_type,
content, content,
state_key, state_key,
prev_events,
depth, depth,
redacts,
unsigned,
hashes: EventHash { sha256: "aaa".to_owned() },
signatures: None,
prev_events,
auth_events: auth_events auth_events: auth_events
.values() .values()
.map(|pdu| pdu.event_id.clone()) .map(|pdu| pdu.event_id.clone())
.collect(), .collect(),
redacts,
unsigned: if unsigned.is_empty() {
None
} else {
Some(to_raw_value(&unsigned)?)
},
hashes: EventHash { sha256: "aaa".to_owned() },
signatures: None,
}; };
let auth_fetch = |k: &StateEventType, s: &str| { let auth_fetch = |k: &StateEventType, s: &str| {