more error checking for deserialising events and canonical JSON
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
c83acabfb0
commit
1a06c8c9d3
3 changed files with 69 additions and 8 deletions
|
@ -9,6 +9,7 @@ use ruma::{
|
||||||
},
|
},
|
||||||
events::{StateEventType, TimelineEventType},
|
events::{StateEventType, TimelineEventType},
|
||||||
};
|
};
|
||||||
|
use serde_json::from_str;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, HashSet},
|
collections::{BTreeMap, HashSet},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
|
@ -48,6 +49,52 @@ pub async fn send_message_event_route(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// certain event types require certain fields to be valid in request bodies.
|
||||||
|
// this helps prevent attempting to handle events that we can't deserialise later so don't waste resources on it.
|
||||||
|
//
|
||||||
|
// see https://spec.matrix.org/v1.9/client-server-api/#events-2 for what's required per event type.
|
||||||
|
match body.event_type.to_string().into() {
|
||||||
|
TimelineEventType::RoomMessage => {
|
||||||
|
let body_field = body.body.body.get_field::<String>("body");
|
||||||
|
let msgtype_field = body.body.body.get_field::<String>("msgtype");
|
||||||
|
|
||||||
|
if body_field.is_err() {
|
||||||
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::InvalidParam,
|
||||||
|
"'body' field in JSON request is invalid",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if msgtype_field.is_err() {
|
||||||
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::InvalidParam,
|
||||||
|
"'msgtype' field in JSON request is invalid",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TimelineEventType::RoomName => {
|
||||||
|
let name_field = body.body.body.get_field::<String>("name");
|
||||||
|
|
||||||
|
if name_field.is_err() {
|
||||||
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::InvalidParam,
|
||||||
|
"'name' field in JSON request is invalid",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TimelineEventType::RoomTopic => {
|
||||||
|
let topic_field = body.body.body.get_field::<String>("topic");
|
||||||
|
|
||||||
|
if topic_field.is_err() {
|
||||||
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::InvalidParam,
|
||||||
|
"'topic' field in JSON request is invalid",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {} // event may be custom/experimental or can be empty don't do anything with it
|
||||||
|
};
|
||||||
|
|
||||||
// Check if this is a new transaction id
|
// Check if this is a new transaction id
|
||||||
if let Some(response) =
|
if let Some(response) =
|
||||||
services()
|
services()
|
||||||
|
@ -79,7 +126,7 @@ pub async fn send_message_event_route(
|
||||||
.build_and_append_pdu(
|
.build_and_append_pdu(
|
||||||
PduBuilder {
|
PduBuilder {
|
||||||
event_type: body.event_type.to_string().into(),
|
event_type: body.event_type.to_string().into(),
|
||||||
content: serde_json::from_str(body.body.body.json().get())
|
content: from_str(body.body.body.json().get())
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?,
|
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?,
|
||||||
unsigned: Some(unsigned),
|
unsigned: Some(unsigned),
|
||||||
state_key: None,
|
state_key: None,
|
||||||
|
|
|
@ -1822,8 +1822,10 @@ pub async fn create_invite_route(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut signed_event = utils::to_canonical_object(&body.event)
|
let mut signed_event = utils::to_canonical_object(&body.event).map_err(|e| {
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invite event is invalid."))?;
|
error!("Failed to convert invite event to canonical JSON: {}", e);
|
||||||
|
Error::BadRequest(ErrorKind::InvalidParam, "Invite event is invalid.")
|
||||||
|
})?;
|
||||||
|
|
||||||
ruma::signatures::hash_and_sign_event(
|
ruma::signatures::hash_and_sign_event(
|
||||||
services().globals.server_name().as_str(),
|
services().globals.server_name().as_str(),
|
||||||
|
|
|
@ -260,8 +260,17 @@ impl Service {
|
||||||
unsigned.insert(
|
unsigned.insert(
|
||||||
"prev_content".to_owned(),
|
"prev_content".to_owned(),
|
||||||
CanonicalJsonValue::Object(
|
CanonicalJsonValue::Object(
|
||||||
utils::to_canonical_object(prev_state.content.clone())
|
utils::to_canonical_object(prev_state.content.clone()).map_err(
|
||||||
.expect("event is valid, we just created it"),
|
|e| {
|
||||||
|
error!(
|
||||||
|
"Failed to convert prev_state to canonical JSON: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
Error::bad_database(
|
||||||
|
"Failed to convert prev_state to canonical JSON.",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)?,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -802,7 +811,7 @@ impl Service {
|
||||||
|k, s| auth_events.get(&(k.clone(), s.to_owned())),
|
|k, s| auth_events.get(&(k.clone(), s.to_owned())),
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("Auth check for PDU {:?} failed: {:?}", &pdu, e);
|
error!("Auth check failed: {:?}", e);
|
||||||
Error::bad_database("Auth check failed.")
|
Error::bad_database("Auth check failed.")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -815,7 +824,7 @@ impl Service {
|
||||||
|
|
||||||
// Hash and sign
|
// Hash and sign
|
||||||
let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| {
|
let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| {
|
||||||
error!("Failed to convert PDU {:?} to canonical JSON: {}", &pdu, e);
|
error!("Failed to convert PDU to canonical JSON: {}", e);
|
||||||
Error::bad_database("Failed to convert PDU to canonical JSON.")
|
Error::bad_database("Failed to convert PDU to canonical JSON.")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -1105,7 +1114,10 @@ impl Service {
|
||||||
pdu.redact(room_version_id, reason)?;
|
pdu.redact(room_version_id, reason)?;
|
||||||
self.replace_pdu(
|
self.replace_pdu(
|
||||||
&pdu_id,
|
&pdu_id,
|
||||||
&utils::to_canonical_object(&pdu).expect("PDU is an object"),
|
&utils::to_canonical_object(&pdu).map_err(|e| {
|
||||||
|
error!("Failed to convert PDU to canonical JSON: {}", e);
|
||||||
|
Error::bad_database("Failed to convert PDU to canonical JSON.")
|
||||||
|
})?,
|
||||||
&pdu,
|
&pdu,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue