diff --git a/src/api/client_server/state.rs b/src/api/client_server/state.rs index 54621603..85cd2a61 100644 --- a/src/api/client_server/state.rs +++ b/src/api/client_server/state.rs @@ -210,40 +210,8 @@ async fn send_state_event_for_key_helper( ) -> Result> { 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, +) -> 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(()) +}