factor canonical alias event validation into a helper function

Not all the semantics from the spec quote in the doc comment are
implemented yet.
This commit is contained in:
Olivia Lee 2025-01-20 13:43:11 -08:00
parent 051221c0ab
commit 50c1e77cd6
No known key found for this signature in database
GPG key ID: 54D568A15B9CD1F9

View file

@ -210,40 +210,8 @@ async fn send_state_event_for_key_helper(
) -> Result<Arc<EventId>> {
let sender_user = sender;
// TODO: allow alias if it previously existed
if event_type == &StateEventType::RoomCanonicalAlias {
if let Ok(canonical_alias) = serde_json::from_str::<
RoomCanonicalAliasEventContent,
>(json.json().get())
{
let mut aliases = canonical_alias.alt_aliases.clone();
if let Some(alias) = canonical_alias.alias {
aliases.push(alias);
}
for alias in aliases {
if alias.server_name() != services().globals.server_name()
|| services()
.rooms
.alias
.resolve_local_alias(&alias)?
.filter(|room| room == room_id)
.is_none()
{
return Err(Error::BadRequest(
ErrorKind::BadAlias,
"You are only allowed to send canonical_alias events \
when it's aliases already exists",
));
}
}
} else {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"m.room.canonical_alias event did not match expected schema",
));
}
validate_canonical_alias_event(room_id, json.cast_ref())?;
}
let room_token = services()
@ -271,3 +239,56 @@ async fn send_state_event_for_key_helper(
Ok(event_id)
}
/// Checks that a new `m.room.canonical_alias` event is valid, by the spec's
/// requirements.
///
/// From the [spec]:
///
/// > If the event type being sent is m.room.canonical_alias servers SHOULD
/// > ensure that any new aliases being listed in the event are valid per their
/// > grammar/syntax and that they point to the room ID where the state event
/// > is to be sent. Servers do not validate aliases which are being removed or
/// > are already present in the state event.
///
/// [spec]: https://spec.matrix.org/v1.13/client-server-api/#put_matrixclientv3roomsroomidstateeventtypestatekey
fn validate_canonical_alias_event(
room_id: &RoomId,
json: &Raw<RoomCanonicalAliasEventContent>,
) -> Result<()> {
// TODO: allow alias if it previously existed
if let Ok(canonical_alias) = serde_json::from_str::<
RoomCanonicalAliasEventContent,
>(json.json().get())
{
let mut aliases = canonical_alias.alt_aliases.clone();
if let Some(alias) = canonical_alias.alias {
aliases.push(alias);
}
for alias in aliases {
if alias.server_name() != services().globals.server_name()
|| services()
.rooms
.alias
.resolve_local_alias(&alias)?
.filter(|room| room == room_id)
.is_none()
{
return Err(Error::BadRequest(
ErrorKind::BadAlias,
"You are only allowed to send canonical_alias events when \
it's aliases already exists",
));
}
}
} else {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"m.room.canonical_alias event did not match expected schema",
));
}
Ok(())
}