Add optional redacted_because insertion to redaction
This commit is contained in:
parent
4f821d39ce
commit
284b797e05
@ -8,6 +8,11 @@ use serde_json::Value as JsonValue;
|
|||||||
mod value;
|
mod value;
|
||||||
|
|
||||||
use crate::RoomVersionId;
|
use crate::RoomVersionId;
|
||||||
|
#[cfg(feature = "events")]
|
||||||
|
use crate::{
|
||||||
|
events::room::redaction::{OriginalRoomRedactionEvent, OriginalSyncRoomRedactionEvent},
|
||||||
|
serde::Raw,
|
||||||
|
};
|
||||||
|
|
||||||
pub use self::value::{CanonicalJsonObject, CanonicalJsonValue};
|
pub use self::value::{CanonicalJsonObject, CanonicalJsonValue};
|
||||||
|
|
||||||
@ -116,6 +121,36 @@ pub fn to_canonical_value<T: Serialize>(
|
|||||||
serde_json::to_value(value).map_err(CanonicalJsonError::SerDe)?.try_into()
|
serde_json::to_value(value).map_err(CanonicalJsonError::SerDe)?.try_into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The value to put in `unsigned.redacted_because`.
|
||||||
|
///
|
||||||
|
/// See `From` implementations for ways to create an instance of this type.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct RedactedBecause(CanonicalJsonObject);
|
||||||
|
|
||||||
|
impl From<CanonicalJsonObject> for RedactedBecause {
|
||||||
|
fn from(obj: CanonicalJsonObject) -> Self {
|
||||||
|
Self(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "events")]
|
||||||
|
impl TryFrom<&Raw<OriginalRoomRedactionEvent>> for RedactedBecause {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(value: &Raw<OriginalRoomRedactionEvent>) -> Result<Self, Self::Error> {
|
||||||
|
value.deserialize_as().map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "events")]
|
||||||
|
impl TryFrom<&Raw<OriginalSyncRoomRedactionEvent>> for RedactedBecause {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(value: &Raw<OriginalSyncRoomRedactionEvent>) -> Result<Self, Self::Error> {
|
||||||
|
value.deserialize_as().map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Redacts an event using the rules specified in the Matrix client-server specification.
|
/// Redacts an event using the rules specified in the Matrix client-server specification.
|
||||||
///
|
///
|
||||||
/// This is part of the process of signing an event.
|
/// This is part of the process of signing an event.
|
||||||
@ -127,7 +162,10 @@ pub fn to_canonical_value<T: Serialize>(
|
|||||||
///
|
///
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
///
|
///
|
||||||
/// * object: A JSON object to redact.
|
/// * `object`: A JSON object to redact.
|
||||||
|
/// * `version`: The room version, determines which keys to keep for a few event types.
|
||||||
|
/// * `redacted_because`: If this is set, an `unsigned` object with a `redacted_because` field set
|
||||||
|
/// to the given value is added to the event after redaction.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
@ -140,8 +178,9 @@ pub fn to_canonical_value<T: Serialize>(
|
|||||||
pub fn redact(
|
pub fn redact(
|
||||||
mut object: CanonicalJsonObject,
|
mut object: CanonicalJsonObject,
|
||||||
version: &RoomVersionId,
|
version: &RoomVersionId,
|
||||||
|
redacted_because: Option<RedactedBecause>,
|
||||||
) -> Result<CanonicalJsonObject, RedactionError> {
|
) -> Result<CanonicalJsonObject, RedactionError> {
|
||||||
redact_in_place(&mut object, version)?;
|
redact_in_place(&mut object, version, redacted_because)?;
|
||||||
Ok(object)
|
Ok(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +192,7 @@ pub fn redact(
|
|||||||
pub fn redact_in_place(
|
pub fn redact_in_place(
|
||||||
event: &mut CanonicalJsonObject,
|
event: &mut CanonicalJsonObject,
|
||||||
version: &RoomVersionId,
|
version: &RoomVersionId,
|
||||||
|
redacted_because: Option<RedactedBecause>,
|
||||||
) -> Result<(), RedactionError> {
|
) -> Result<(), RedactionError> {
|
||||||
// Get the content keys here even if they're only needed inside the branch below, because we
|
// Get the content keys here even if they're only needed inside the branch below, because we
|
||||||
// can't teach rust that this is a disjoint borrow with `get_mut("content")`.
|
// can't teach rust that this is a disjoint borrow with `get_mut("content")`.
|
||||||
@ -181,6 +221,14 @@ pub fn redact_in_place(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(redacted_because) = redacted_because {
|
||||||
|
let unsigned = CanonicalJsonObject::from_iter([(
|
||||||
|
"redacted_because".to_owned(),
|
||||||
|
redacted_because.0.into(),
|
||||||
|
)]);
|
||||||
|
event.insert("unsigned".to_owned(), unsigned.into());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::{collections::BTreeMap, fmt};
|
use std::{collections::BTreeMap, fmt};
|
||||||
|
|
||||||
use js_int::Int;
|
use js_int::{Int, UInt};
|
||||||
use serde::{de::Deserializer, ser::Serializer, Deserialize, Serialize};
|
use serde::{de::Deserializer, ser::Serializer, Deserialize, Serialize};
|
||||||
use serde_json::{to_string as to_json_string, Value as JsonValue};
|
use serde_json::{to_string as to_json_string, Value as JsonValue};
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ macro_rules! variant_impls {
|
|||||||
($variant:ident($ty:ty)) => {
|
($variant:ident($ty:ty)) => {
|
||||||
impl From<$ty> for CanonicalJsonValue {
|
impl From<$ty> for CanonicalJsonValue {
|
||||||
fn from(val: $ty) -> Self {
|
fn from(val: $ty) -> Self {
|
||||||
Self::$variant(val)
|
Self::$variant(val.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,9 +263,16 @@ macro_rules! variant_impls {
|
|||||||
variant_impls!(Bool(bool));
|
variant_impls!(Bool(bool));
|
||||||
variant_impls!(Integer(Int));
|
variant_impls!(Integer(Int));
|
||||||
variant_impls!(String(String));
|
variant_impls!(String(String));
|
||||||
|
variant_impls!(String(&str));
|
||||||
variant_impls!(Array(Vec<CanonicalJsonValue>));
|
variant_impls!(Array(Vec<CanonicalJsonValue>));
|
||||||
variant_impls!(Object(CanonicalJsonObject));
|
variant_impls!(Object(CanonicalJsonObject));
|
||||||
|
|
||||||
|
impl From<UInt> for CanonicalJsonValue {
|
||||||
|
fn from(value: UInt) -> Self {
|
||||||
|
Self::Integer(value.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Serialize for CanonicalJsonValue {
|
impl Serialize for CanonicalJsonValue {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -321,7 +321,7 @@ pub fn reference_hash(
|
|||||||
value: &CanonicalJsonObject,
|
value: &CanonicalJsonObject,
|
||||||
version: &RoomVersionId,
|
version: &RoomVersionId,
|
||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let redacted_value = redact(value.clone(), version)?;
|
let redacted_value = redact(value.clone(), version, None)?;
|
||||||
|
|
||||||
let json =
|
let json =
|
||||||
canonical_json_with_fields_to_remove(&redacted_value, REFERENCE_HASH_FIELDS_TO_REMOVE)?;
|
canonical_json_with_fields_to_remove(&redacted_value, REFERENCE_HASH_FIELDS_TO_REMOVE)?;
|
||||||
@ -458,7 +458,7 @@ where
|
|||||||
_ => return Err(JsonError::not_of_type("hashes", JsonType::Object)),
|
_ => return Err(JsonError::not_of_type("hashes", JsonType::Object)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut redacted = redact(object.clone(), version)?;
|
let mut redacted = redact(object.clone(), version, None)?;
|
||||||
|
|
||||||
sign_json(entity_id, key_pair, &mut redacted)?;
|
sign_json(entity_id, key_pair, &mut redacted)?;
|
||||||
|
|
||||||
@ -539,7 +539,7 @@ pub fn verify_event(
|
|||||||
object: &CanonicalJsonObject,
|
object: &CanonicalJsonObject,
|
||||||
version: &RoomVersionId,
|
version: &RoomVersionId,
|
||||||
) -> Result<Verified, Error> {
|
) -> Result<Verified, Error> {
|
||||||
let redacted = redact(object.clone(), version)?;
|
let redacted = redact(object.clone(), version, None)?;
|
||||||
|
|
||||||
let hash = match object.get("hashes") {
|
let hash = match object.get("hashes") {
|
||||||
Some(hashes_value) => match hashes_value {
|
Some(hashes_value) => match hashes_value {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user