Check account data type match before storing to DB

This commit is contained in:
Lambda 2025-04-04 17:47:02 +00:00
parent d283da51c6
commit 33da7dcd96

View file

@ -3,6 +3,7 @@ use std::collections::HashMap;
use ruma::{api::client::error::ErrorKind, RoomId, UserId};
use serde::Deserialize;
use serde_json::value::RawValue;
use tracing::error;
use crate::{
database::KeyValueDatabase, service, services, utils, Error, Result,
@ -16,16 +17,6 @@ impl service::account_data::Data for KeyValueDatabase {
event_type: &str,
data: &RawValue,
) -> Result<()> {
// Allowed because we just use this type to validate the schema, and
// don't read the fields.
#[allow(dead_code)]
#[derive(Deserialize)]
struct ExtractEventFields<'a> {
#[serde(rename = "type")]
event_type: &'a str,
content: &'a RawValue,
}
let mut prefix = room_id
.map(ToString::to_string)
.unwrap_or_default()
@ -44,11 +35,41 @@ impl service::account_data::Data for KeyValueDatabase {
let mut key = prefix;
key.extend_from_slice(event_type.as_bytes());
if serde_json::from_str::<ExtractEventFields<'_>>(data.get()).is_err() {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Account data doesn't have all required fields.",
));
{
#[derive(Deserialize)]
struct ExtractEventFields<'a> {
#[serde(rename = "type")]
event_type: &'a str,
// Allowed because we just use this type to validate the schema
// and event type, and don't extract the content.
#[allow(dead_code)]
content: &'a RawValue,
}
let Ok(ExtractEventFields {
event_type: serialised_event_type,
..
}) = serde_json::from_str(data.get())
else {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Account data doesn't have all required fields.",
));
};
if serialised_event_type != event_type {
error!(
%user_id,
?room_id,
event_type,
serialised_event_type,
"Mismatch between discrete and serialised account data event type"
);
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Account data event type mismatch.",
));
}
}
self.roomuserdataid_accountdata