state-res: Return borrowed content in Event method

This commit is contained in:
Jonas Platte 2021-09-13 18:51:37 +02:00
parent e49f76b4be
commit 0999e420ae
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
5 changed files with 43 additions and 27 deletions

View File

@ -573,10 +573,10 @@ mod event {
} }
} }
fn content(&self) -> serde_json::Value { fn content(&self) -> &serde_json::Value {
match &self.rest { match &self.rest {
Pdu::RoomV1Pdu(ev) => ev.content.clone(), Pdu::RoomV1Pdu(ev) => &ev.content,
Pdu::RoomV3Pdu(ev) => ev.content.clone(), Pdu::RoomV3Pdu(ev) => &ev.content,
#[cfg(not(feature = "unstable-exhaustive-types"))] #[cfg(not(feature = "unstable-exhaustive-types"))]
_ => unreachable!("new PDU version"), _ => unreachable!("new PDU version"),
} }

View File

@ -22,7 +22,7 @@ pub fn auth_types_for_event(
kind: &EventType, kind: &EventType,
sender: &UserId, sender: &UserId,
state_key: Option<&str>, state_key: Option<&str>,
content: serde_json::Value, content: &serde_json::Value,
) -> Vec<(EventType, String)> { ) -> Vec<(EventType, String)> {
if kind == &EventType::RoomCreate { if kind == &EventType::RoomCreate {
return vec![]; return vec![];
@ -269,7 +269,9 @@ where
} }
let sender_power_level = if let Some(pl) = &power_levels_event { let sender_power_level = if let Some(pl) = &power_levels_event {
if let Ok(content) = serde_json::from_value::<PowerLevelsEventContent>(pl.content()) { if let Ok(content) =
serde_json::from_value::<PowerLevelsEventContent>(pl.content().to_owned())
{
if let Some(level) = content.users.get(sender) { if let Some(level) = content.users.get(sender) {
*level *level
} else { } else {
@ -281,7 +283,9 @@ where
} else { } else {
// If no power level event found the creator gets 100 everyone else gets 0 // If no power level event found the creator gets 100 everyone else gets 0
room_create_event room_create_event
.and_then(|create| serde_json::from_value::<CreateEventContent>(create.content()).ok()) .and_then(|create| {
serde_json::from_value::<CreateEventContent>(create.content().to_owned()).ok()
})
.and_then(|create| (create.creator == *sender).then(|| int!(100))) .and_then(|create| (create.creator == *sender).then(|| int!(100)))
.unwrap_or_default() .unwrap_or_default()
}; };
@ -291,7 +295,10 @@ where
if *incoming_event.event_type() == EventType::RoomThirdPartyInvite { if *incoming_event.event_type() == EventType::RoomThirdPartyInvite {
let invite_level = match &power_levels_event { let invite_level = match &power_levels_event {
Some(power_levels) => { Some(power_levels) => {
serde_json::from_value::<PowerLevelsEventContent>(power_levels.content())?.invite serde_json::from_value::<PowerLevelsEventContent>(
power_levels.content().to_owned(),
)?
.invite
} }
None => int!(50), None => int!(50),
}; };
@ -376,7 +383,7 @@ fn valid_membership_change<E: Event>(
target_user_membership_event: Option<&E>, target_user_membership_event: Option<&E>,
sender: &UserId, sender: &UserId,
sender_membership_event: Option<&E>, sender_membership_event: Option<&E>,
content: serde_json::Value, content: &serde_json::Value,
prev_event: Option<&E>, prev_event: Option<&E>,
current_third_party_invite: Option<&E>, current_third_party_invite: Option<&E>,
power_levels_event: Option<&E>, power_levels_event: Option<&E>,
@ -412,7 +419,7 @@ fn valid_membership_change<E: Event>(
}; };
let power_levels: PowerLevelsEventContent = match &power_levels_event { let power_levels: PowerLevelsEventContent = match &power_levels_event {
Some(ev) => serde_json::from_value(ev.content())?, Some(ev) => serde_json::from_value(ev.content().to_owned())?,
None => PowerLevelsEventContent::default(), None => PowerLevelsEventContent::default(),
}; };
@ -427,7 +434,8 @@ fn valid_membership_change<E: Event>(
let mut join_rules = JoinRule::Invite; let mut join_rules = JoinRule::Invite;
if let Some(jr) = &join_rules_event { if let Some(jr) = &join_rules_event {
join_rules = serde_json::from_value::<JoinRulesEventContent>(jr.content())?.join_rule; join_rules =
serde_json::from_value::<JoinRulesEventContent>(jr.content().to_owned())?.join_rule;
} }
if let Some(prev) = prev_event { if let Some(prev) = prev_event {
@ -613,10 +621,12 @@ where
// If users key in content is not a dictionary with keys that are valid user IDs // If users key in content is not a dictionary with keys that are valid user IDs
// with values that are integers (or a string that is an integer), reject. // with values that are integers (or a string that is an integer), reject.
let user_content = let user_content =
serde_json::from_value::<PowerLevelsEventContent>(power_event.content()).unwrap(); serde_json::from_value::<PowerLevelsEventContent>(power_event.content().to_owned())
.unwrap();
let current_content = let current_content =
serde_json::from_value::<PowerLevelsEventContent>(current_state.content()).unwrap(); serde_json::from_value::<PowerLevelsEventContent>(current_state.content().to_owned())
.unwrap();
// Validation of users is done in Ruma, synapse for loops validating user_ids and integers here // Validation of users is done in Ruma, synapse for loops validating user_ids and integers here
info!("validation of power event finished"); info!("validation of power event finished");
@ -768,7 +778,7 @@ fn get_send_level<E: Event>(
) -> Int { ) -> Int {
power_lvl power_lvl
.and_then(|ple| { .and_then(|ple| {
serde_json::from_value::<PowerLevelsEventContent>(ple.content()) serde_json::from_value::<PowerLevelsEventContent>(ple.content().to_owned())
.map(|content| { .map(|content| {
content.events.get(e_type).copied().unwrap_or_else(|| { content.events.get(e_type).copied().unwrap_or_else(|| {
if state_key.is_some() { if state_key.is_some() {
@ -810,9 +820,9 @@ fn verify_third_party_invite<E: Event>(
// If any signature in signed matches any public key in the m.room.third_party_invite event, // If any signature in signed matches any public key in the m.room.third_party_invite event,
// allow // allow
if let Ok(tpid_ev) = if let Ok(tpid_ev) = serde_json::from_value::<ThirdPartyInviteEventContent>(
serde_json::from_value::<ThirdPartyInviteEventContent>(current_tpid.content()) current_tpid.content().to_owned(),
{ ) {
// A list of public keys in the public_keys field // A list of public keys in the public_keys field
for key in tpid_ev.public_keys.unwrap_or_default() { for key in tpid_ev.public_keys.unwrap_or_default() {
if key.public_key == tp_id.signed.token { if key.public_key == tp_id.signed.token {

View File

@ -343,9 +343,9 @@ where
return 0; return 0;
} }
if let Some(content) = if let Some(content) = pl.and_then(|pl| {
pl.and_then(|pl| serde_json::from_value::<PowerLevelsEventContent>(pl.content()).ok()) serde_json::from_value::<PowerLevelsEventContent>(pl.content().to_owned()).ok()
{ }) {
if let Some(ev) = event { if let Some(ev) = event {
if let Some(user) = content.users.get(ev.sender()) { if let Some(user) = content.users.get(ev.sender()) {
debug!("found {} at power_level {}", ev.sender(), user); debug!("found {} at power_level {}", ev.sender(), user);
@ -615,7 +615,9 @@ fn is_power_event<E: Event>(event: &E) -> bool {
event.state_key() == Some("") event.state_key() == Some("")
} }
EventType::RoomMember => { EventType::RoomMember => {
if let Ok(content) = serde_json::from_value::<MemberEventContent>(event.content()) { if let Ok(content) =
serde_json::from_value::<MemberEventContent>(event.content().to_owned())
{
if [MembershipState::Leave, MembershipState::Ban].contains(&content.membership) { if [MembershipState::Leave, MembershipState::Ban].contains(&content.membership) {
return Some(event.sender().as_str()) != event.state_key(); return Some(event.sender().as_str()) != event.state_key();
} }

View File

@ -24,7 +24,11 @@ pub trait Event {
fn event_type(&self) -> &EventType; fn event_type(&self) -> &EventType;
/// The event's content. /// The event's content.
fn content(&self) -> serde_json::Value; // FIXME: This forces a serde_json::Value to be stored, which the previous solution of returning
// an owned one did not. However, the previous signature was even less efficient and also
// heavily encouraged storing `serde_json::Value`. We should likely force usage of `RawValue`
// instead, or somehow allow different storage without pessimizing all but one.
fn content(&self) -> &serde_json::Value;
/// The state key for this event. /// The state key for this event.
fn state_key(&self) -> Option<&str>; fn state_key(&self) -> Option<&str>;
@ -77,7 +81,7 @@ impl<T: Event> Event for &T {
(*self).event_type() (*self).event_type()
} }
fn content(&self) -> serde_json::Value { fn content(&self) -> &serde_json::Value {
(*self).content() (*self).content()
} }
@ -135,7 +139,7 @@ impl<T: Event> Event for Arc<T> {
(&**self).event_type() (&**self).event_type()
} }
fn content(&self) -> serde_json::Value { fn content(&self) -> &serde_json::Value {
(&**self).content() (&**self).content()
} }

View File

@ -149,7 +149,7 @@ pub fn do_check(
e.sender().clone(), e.sender().clone(),
e.event_type().clone(), e.event_type().clone(),
e.state_key(), e.state_key(),
e.content(), e.content().to_owned(),
&auth_events, &auth_events,
&prev_events.iter().cloned().collect::<Vec<_>>(), &prev_events.iter().cloned().collect::<Vec<_>>(),
); );
@ -575,10 +575,10 @@ pub mod event {
} }
} }
fn content(&self) -> serde_json::Value { fn content(&self) -> &serde_json::Value {
match &self.rest { match &self.rest {
Pdu::RoomV1Pdu(ev) => ev.content.clone(), Pdu::RoomV1Pdu(ev) => &ev.content,
Pdu::RoomV3Pdu(ev) => ev.content.clone(), Pdu::RoomV3Pdu(ev) => &ev.content,
#[cfg(not(feature = "unstable-exhaustive-types"))] #[cfg(not(feature = "unstable-exhaustive-types"))]
_ => unreachable!("new PDU version"), _ => unreachable!("new PDU version"),
} }