signatures: Add redact_content function

This commit is contained in:
Jonathan de Jong 2022-02-02 14:27:27 +01:00 committed by GitHub
parent 96b879eb2a
commit e4d8761222
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 16 deletions

View File

@ -736,29 +736,23 @@ pub fn redact_in_place(
event: &mut CanonicalJsonObject, event: &mut CanonicalJsonObject,
version: &RoomVersionId, version: &RoomVersionId,
) -> Result<(), Error> { ) -> Result<(), Error> {
let event_type_value = match event.get("type") { // Get the content keys here instead of the event type, because we cant teach rust that this is
Some(event_type_value) => event_type_value, // a disjoint borrow.
let allowed_content_keys: &[&str] = match event.get("type") {
Some(CanonicalJsonValue::String(event_type)) => {
allowed_content_keys_for(event_type, version)
}
Some(_) => return Err(JsonError::not_of_type("type", JsonType::String)),
None => return Err(JsonError::field_missing_from_object("type")), None => return Err(JsonError::field_missing_from_object("type")),
}; };
let allowed_content_keys = match event_type_value {
CanonicalJsonValue::String(event_type) => allowed_content_keys_for(event_type, version),
_ => return Err(JsonError::not_of_type("type", JsonType::String)),
};
if let Some(content_value) = event.get_mut("content") { if let Some(content_value) = event.get_mut("content") {
let content = match content_value { let content = match content_value {
CanonicalJsonValue::Object(map) => map, CanonicalJsonValue::Object(map) => map,
_ => return Err(JsonError::not_of_type("content", JsonType::Object)), _ => return Err(JsonError::not_of_type("content", JsonType::Object)),
}; };
let mut old_content = mem::take(content); object_retain_keys(content, allowed_content_keys);
for &key in allowed_content_keys {
if let Some(value) = old_content.remove(key) {
content.insert(key.to_owned(), value);
}
}
} }
let mut old_event = mem::take(event); let mut old_event = mem::take(event);
@ -772,6 +766,27 @@ pub fn redact_in_place(
Ok(()) Ok(())
} }
/// Redacts event content using the rules specified in the Matrix client-server specification.
///
/// Edits the `object` in-place.
pub fn redact_content_in_place(
object: &mut CanonicalJsonObject,
version: &RoomVersionId,
event_type: impl AsRef<str>,
) {
object_retain_keys(object, allowed_content_keys_for(event_type.as_ref(), version))
}
fn object_retain_keys(object: &mut CanonicalJsonObject, keys: &[&str]) {
let mut old_content = mem::take(object);
for &key in keys {
if let Some(value) = old_content.remove(key) {
object.insert(key.to_owned(), value);
}
}
}
/// Extracts the server names to check signatures for given event. /// Extracts the server names to check signatures for given event.
/// ///
/// It will return the sender's server (unless it's a third party invite) and the event id server /// It will return the sender's server (unless it's a third party invite) and the event id server

View File

@ -48,8 +48,8 @@ use ruma_serde::{AsRefStr, DisplayAsRefStr};
pub use error::{Error, JsonError, JsonType, ParseError, SplitError, VerificationError}; pub use error::{Error, JsonError, JsonType, ParseError, SplitError, VerificationError};
pub use functions::{ pub use functions::{
canonical_json, content_hash, hash_and_sign_event, redact, reference_hash, sign_json, canonical_json, content_hash, hash_and_sign_event, redact, redact_content_in_place,
verify_event, verify_json, redact_in_place, reference_hash, sign_json, verify_event, verify_json,
}; };
pub use keys::{Ed25519KeyPair, KeyPair, PublicKeyMap, PublicKeySet}; pub use keys::{Ed25519KeyPair, KeyPair, PublicKeyMap, PublicKeySet};
pub use ruma_serde::{CanonicalJsonError, CanonicalJsonObject, CanonicalJsonValue}; pub use ruma_serde::{CanonicalJsonError, CanonicalJsonObject, CanonicalJsonValue};