From 9836222b73c4b418fe202e2624cb277f07274334 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Thu, 13 Jun 2019 01:24:00 -0700 Subject: [PATCH] Add m.room.server_acl. --- src/collections/all.rs | 37 ++++++++++++++++++++++++++++ src/collections/only.rs | 2 ++ src/lib.rs | 4 +++ src/room.rs | 1 + src/room/server_acl.rs | 54 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 src/room/server_acl.rs diff --git a/src/collections/all.rs b/src/collections/all.rs index 62400f48..62d4494f 100644 --- a/src/collections/all.rs +++ b/src/collections/all.rs @@ -24,6 +24,7 @@ use crate::{ pinned_events::PinnedEventsEvent, power_levels::PowerLevelsEvent, redaction::RedactionEvent, + server_acl::ServerAclEvent, third_party_invite::ThirdPartyInviteEvent, topic::TopicEvent, }, @@ -86,6 +87,8 @@ pub enum Event { RoomPowerLevels(PowerLevelsEvent), /// m.room.redaction RoomRedaction(RedactionEvent), + /// m.room.server_acl, + RoomServerAcl(ServerAclEvent), /// m.room.third_party_invite RoomThirdPartyInvite(ThirdPartyInviteEvent), /// m.room.topic @@ -144,6 +147,8 @@ pub enum RoomEvent { RoomPowerLevels(PowerLevelsEvent), /// m.room.redaction RoomRedaction(RedactionEvent), + /// m.room.server_acl, + RoomServerAcl(ServerAclEvent), /// m.room.third_party_invite RoomThirdPartyInvite(ThirdPartyInviteEvent), /// m.room.topic @@ -182,6 +187,8 @@ pub enum StateEvent { RoomPinnedEvents(PinnedEventsEvent), /// m.room.power_levels RoomPowerLevels(PowerLevelsEvent), + /// m.room.server_acl, + RoomServerAcl(ServerAclEvent), /// m.room.third_party_invite RoomThirdPartyInvite(ThirdPartyInviteEvent), /// m.room.topic @@ -219,6 +226,7 @@ impl Serialize for Event { Event::RoomPinnedEvents(ref event) => event.serialize(serializer), Event::RoomPowerLevels(ref event) => event.serialize(serializer), Event::RoomRedaction(ref event) => event.serialize(serializer), + Event::RoomServerAcl(ref event) => event.serialize(serializer), Event::RoomThirdPartyInvite(ref event) => event.serialize(serializer), Event::RoomTopic(ref event) => event.serialize(serializer), Event::Sticker(ref event) => event.serialize(serializer), @@ -433,6 +441,14 @@ impl<'de> Deserialize<'de> for Event { Ok(Event::RoomRedaction(event)) } + EventType::RoomServerAcl => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(Event::RoomServerAcl(event)) + } EventType::RoomThirdPartyInvite => { let event = match from_value::(value) { Ok(event) => event, @@ -528,6 +544,7 @@ impl Serialize for RoomEvent { RoomEvent::RoomPinnedEvents(ref event) => event.serialize(serializer), RoomEvent::RoomPowerLevels(ref event) => event.serialize(serializer), RoomEvent::RoomRedaction(ref event) => event.serialize(serializer), + RoomEvent::RoomServerAcl(ref event) => event.serialize(serializer), RoomEvent::RoomThirdPartyInvite(ref event) => event.serialize(serializer), RoomEvent::RoomTopic(ref event) => event.serialize(serializer), RoomEvent::Sticker(ref event) => event.serialize(serializer), @@ -699,6 +716,14 @@ impl<'de> Deserialize<'de> for RoomEvent { Ok(RoomEvent::RoomRedaction(event)) } + EventType::RoomServerAcl => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(RoomEvent::RoomServerAcl(event)) + } EventType::RoomThirdPartyInvite => { let event = match from_value::(value) { Ok(event) => event, @@ -768,6 +793,7 @@ impl Serialize for StateEvent { StateEvent::RoomName(ref event) => event.serialize(serializer), StateEvent::RoomPinnedEvents(ref event) => event.serialize(serializer), StateEvent::RoomPowerLevels(ref event) => event.serialize(serializer), + StateEvent::RoomServerAcl(ref event) => event.serialize(serializer), StateEvent::RoomThirdPartyInvite(ref event) => event.serialize(serializer), StateEvent::RoomTopic(ref event) => event.serialize(serializer), StateEvent::CustomState(ref event) => event.serialize(serializer), @@ -881,6 +907,14 @@ impl<'de> Deserialize<'de> for StateEvent { Ok(StateEvent::RoomPowerLevels(event)) } + EventType::RoomServerAcl => { + let event = match from_value::(value) { + Ok(event) => event, + Err(error) => return Err(D::Error::custom(error.to_string())), + }; + + Ok(StateEvent::RoomServerAcl(event)) + } EventType::RoomThirdPartyInvite => { let event = match from_value::(value) { Ok(event) => event, @@ -957,6 +991,7 @@ impl_from_t_for_event!(NameEvent, RoomName); impl_from_t_for_event!(PinnedEventsEvent, RoomPinnedEvents); impl_from_t_for_event!(PowerLevelsEvent, RoomPowerLevels); impl_from_t_for_event!(RedactionEvent, RoomRedaction); +impl_from_t_for_event!(ServerAclEvent, RoomServerAcl); impl_from_t_for_event!(ThirdPartyInviteEvent, RoomThirdPartyInvite); impl_from_t_for_event!(TopicEvent, RoomTopic); impl_from_t_for_event!(StickerEvent, Sticker); @@ -994,6 +1029,7 @@ impl_from_t_for_room_event!(NameEvent, RoomName); impl_from_t_for_room_event!(PinnedEventsEvent, RoomPinnedEvents); impl_from_t_for_room_event!(PowerLevelsEvent, RoomPowerLevels); impl_from_t_for_room_event!(RedactionEvent, RoomRedaction); +impl_from_t_for_room_event!(ServerAclEvent, RoomServerAcl); impl_from_t_for_room_event!(StickerEvent, Sticker); impl_from_t_for_room_event!(ThirdPartyInviteEvent, RoomThirdPartyInvite); impl_from_t_for_room_event!(TopicEvent, RoomTopic); @@ -1021,6 +1057,7 @@ impl_from_t_for_state_event!(MemberEvent, RoomMember); impl_from_t_for_state_event!(NameEvent, RoomName); impl_from_t_for_state_event!(PinnedEventsEvent, RoomPinnedEvents); impl_from_t_for_state_event!(PowerLevelsEvent, RoomPowerLevels); +impl_from_t_for_state_event!(ServerAclEvent, RoomServerAcl); impl_from_t_for_state_event!(ThirdPartyInviteEvent, RoomThirdPartyInvite); impl_from_t_for_state_event!(TopicEvent, RoomTopic); impl_from_t_for_state_event!(CustomStateEvent, CustomState); diff --git a/src/collections/only.rs b/src/collections/only.rs index 853213a4..c958b0d9 100644 --- a/src/collections/only.rs +++ b/src/collections/only.rs @@ -187,6 +187,7 @@ impl<'de> Deserialize<'de> for Event { | EventType::RoomPinnedEvents | EventType::RoomPowerLevels | EventType::RoomRedaction + | EventType::RoomServerAcl | EventType::RoomThirdPartyInvite | EventType::RoomTopic | EventType::Sticker => Err(D::Error::custom( @@ -321,6 +322,7 @@ impl<'de> Deserialize<'de> for RoomEvent { | EventType::RoomName | EventType::RoomPinnedEvents | EventType::RoomPowerLevels + | EventType::RoomServerAcl | EventType::RoomThirdPartyInvite | EventType::RoomTopic | EventType::Tag diff --git a/src/lib.rs b/src/lib.rs index 49da7ced..9a16654e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -181,6 +181,8 @@ pub enum EventType { RoomPowerLevels, /// m.room.redaction RoomRedaction, + /// m.room.server_acl + RoomServerAcl, /// m.room.third_party_invite RoomThirdPartyInvite, /// m.room.topic @@ -282,6 +284,7 @@ impl Display for EventType { EventType::RoomPinnedEvents => "m.room.pinned_events", EventType::RoomPowerLevels => "m.room.power_levels", EventType::RoomRedaction => "m.room.redaction", + EventType::RoomServerAcl => "m.room.server_acl", EventType::RoomThirdPartyInvite => "m.room.third_party_invite", EventType::RoomTopic => "m.room.topic", EventType::Sticker => "m.sticker", @@ -320,6 +323,7 @@ impl<'a> From<&'a str> for EventType { "m.room.pinned_events" => EventType::RoomPinnedEvents, "m.room.power_levels" => EventType::RoomPowerLevels, "m.room.redaction" => EventType::RoomRedaction, + "m.room.server_acl" => EventType::RoomServerAcl, "m.room.third_party_invite" => EventType::RoomThirdPartyInvite, "m.room.topic" => EventType::RoomTopic, "m.sticker" => EventType::Sticker, diff --git a/src/room.rs b/src/room.rs index b460c77e..95ae0aca 100644 --- a/src/room.rs +++ b/src/room.rs @@ -19,6 +19,7 @@ pub mod name; pub mod pinned_events; pub mod power_levels; pub mod redaction; +pub mod server_acl; pub mod third_party_invite; pub mod topic; diff --git a/src/room/server_acl.rs b/src/room/server_acl.rs new file mode 100644 index 00000000..e5aa26e0 --- /dev/null +++ b/src/room/server_acl.rs @@ -0,0 +1,54 @@ +//! Types for the *m.room.server_acl* event. + +use serde::{Deserialize, Serialize}; + +state_event! { + /// An event to indicate which servers are permitted to participate in the room. + pub struct ServerAclEvent(ServerAclEventContent) {} +} + +/// The payload of an *m.room.server_acl* event. +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct ServerAclEventContent { + /// True to allow server names that are IP address literals. False to deny. Defaults to true if + /// missing or otherwise not a boolean. + /// + /// This is strongly recommended to be set to false as servers running with IP literal names are + /// strongly discouraged in order to require legitimate homeservers to be backed by a valid + /// registered domain name. + #[serde(default = "default_true")] + pub allow_ip_literals: bool, + /// The server names to allow in the room, excluding any port information. Wildcards may be used + /// to cover a wider range of hosts, where * matches zero or more characters and ? matches + /// exactly one character. + /// + /// **This defaults to an empty list when not provided, effectively disallowing every server.** + #[serde(default)] + pub allow: Vec, + /// The server names to disallow in the room, excluding any port information. Wildcards may be + /// used to cover a wider range of hosts, where * matches zero or more characters and ? matches + /// exactly one character. + /// + /// This defaults to an empty list when not provided. + #[serde(default)] + pub deny: Vec, +} + +/// Used to default the `allow_ip_literals` field to `true` during deserialization. +fn default_true() -> bool { + true +} + +#[cfg(test)] +mod tests { + use super::ServerAclEventContent; + + #[test] + fn default_values() { + let content: ServerAclEventContent = serde_json::from_str("{}").unwrap(); + + assert_eq!(content.allow_ip_literals, true); + assert!(content.allow.is_empty()); + assert!(content.deny.is_empty()); + } +}