diff --git a/crates/matrix-sdk/src/widget/machine/mod.rs b/crates/matrix-sdk/src/widget/machine/mod.rs index 31e96fc7da9..eb0c521878e 100644 --- a/crates/matrix-sdk/src/widget/machine/mod.rs +++ b/crates/matrix-sdk/src/widget/machine/mod.rs @@ -295,7 +295,10 @@ impl WidgetMachine { ReadEventRequest::ReadMessageLikeEvent { event_type, limit } => { let filter_fn = |f: &EventFilter| f.matches_message_like_event_type(&event_type); if !capabilities.read.iter().any(filter_fn) { - return Some(self.send_from_widget_error_response(raw_request, "Not allowed")); + return Some(self.send_from_widget_error_response( + raw_request, + "Not allowed to read message like event", + )); } const DEFAULT_EVENT_LIMIT: u32 = 50; @@ -345,7 +348,10 @@ impl WidgetMachine { }); action } else { - Some(self.send_from_widget_error_response(raw_request, "Not allowed")) + Some(self.send_from_widget_error_response( + raw_request, + "Not allowed to read state event", + )) } } } @@ -381,7 +387,9 @@ impl WidgetMachine { )); } if !capabilities.send.iter().any(|filter| filter.matches(&filter_in)) { - return Some(self.send_from_widget_error_response(raw_request, "Not allowed")); + return Some( + self.send_from_widget_error_response(raw_request, "Not allowed to send event"), + ); } let (request, action) = self.send_matrix_driver_request(request); diff --git a/crates/matrix-sdk/src/widget/machine/tests/error.rs b/crates/matrix-sdk/src/widget/machine/tests/error.rs index 5db05727b33..699b198b49f 100644 --- a/crates/matrix-sdk/src/widget/machine/tests/error.rs +++ b/crates/matrix-sdk/src/widget/machine/tests/error.rs @@ -98,7 +98,10 @@ fn read_request_for_non_allowed_message_like_events() { assert_eq!(request_id, "get-me-some-messages"); assert_eq!(msg["api"], "fromWidget"); assert_eq!(msg["action"], "org.matrix.msc2876.read_events"); - assert_eq!(msg["response"]["error"]["message"].as_str().unwrap(), "Not allowed"); + assert_eq!( + msg["response"]["error"]["message"].as_str().unwrap(), + "Not allowed to read message like event" + ); } #[test] diff --git a/crates/matrix-sdk/src/widget/matrix.rs b/crates/matrix-sdk/src/widget/matrix.rs index 96a40d423aa..a997fa2a8af 100644 --- a/crates/matrix-sdk/src/widget/matrix.rs +++ b/crates/matrix-sdk/src/widget/matrix.rs @@ -29,8 +29,8 @@ use ruma::{ AnyMessageLikeEventContent, AnyStateEventContent, AnySyncTimelineEvent, AnyTimelineEvent, MessageLikeEventType, StateEventType, TimelineEventType, }, - serde::Raw, - RoomId, TransactionId, + serde::{from_raw_json_value, Raw}, + OwnedEventId, RoomId, TransactionId, }; use serde_json::value::RawValue as RawJsonValue; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver}; @@ -47,6 +47,11 @@ pub(crate) struct MatrixDriver { room: Room, } +#[derive(serde::Deserialize)] +struct RedactBody { + redacts: OwnedEventId, +} + impl MatrixDriver { /// Creates a new `MatrixDriver` for a given `room`. pub(crate) fn new(room: Room) -> Self { @@ -116,14 +121,20 @@ impl MatrixDriver { delayed_event_parameters: Option, ) -> Result { let type_str = event_type.to_string(); - Ok(match (state_key, delayed_event_parameters) { - (None, None) => SendEventResponse::from_event_id( + + let redacts = + from_raw_json_value::(&content).ok().map(|b| b.redacts); + Ok(match (state_key, delayed_event_parameters, redacts) { + (None, None, None) => SendEventResponse::from_event_id( self.room.send_raw(&type_str, content).await?.event_id, ), - (Some(key), None) => SendEventResponse::from_event_id( + (None, None, Some(redacts)) => SendEventResponse::from_event_id( + self.room.redact(&redacts, None, None).await?.event_id, + ), + (Some(key), None, _) => SendEventResponse::from_event_id( self.room.send_state_event_raw(&type_str, &key, content).await?.event_id, ), - (None, Some(delayed_event_parameters)) => { + (None, Some(delayed_event_parameters), _) => { let r = delayed_events::delayed_message_event::unstable::Request::new_raw( self.room.room_id().to_owned(), TransactionId::new(), @@ -133,7 +144,7 @@ impl MatrixDriver { ); self.room.client.send(r, None).await.map(|r| r.into())? } - (Some(key), Some(delayed_event_parameters)) => { + (Some(key), Some(delayed_event_parameters), _) => { let r = delayed_events::delayed_state_event::unstable::Request::new_raw( self.room.room_id().to_owned(), key, diff --git a/crates/matrix-sdk/tests/integration/widget.rs b/crates/matrix-sdk/tests/integration/widget.rs index 72d29fcbd04..4d6d3433fef 100644 --- a/crates/matrix-sdk/tests/integration/widget.rs +++ b/crates/matrix-sdk/tests/integration/widget.rs @@ -827,6 +827,55 @@ async fn test_try_update_delayed_event_without_permission_negotiate() { } } +#[async_test] +async fn test_send_redaction() { + let (_, mock_server, driver_handle) = run_test_driver(false).await; + + negotiate_capabilities( + &driver_handle, + json!([ + // "org.matrix.msc4157.send.delayed_event", + "org.matrix.msc2762.send.event:m.room.redaction" + ]), + ) + .await; + + Mock::given(method("PUT")) + .and(path_regex(r"^/_matrix/client/r0/rooms/.*/redact/.*$")) + .respond_with(ResponseTemplate::new(200).set_body_json(json!({ + "event_id":"$redact_event_id" + }))) + .expect(1) + .mount(&mock_server) + .await; + + send_request( + &driver_handle, + "send-redact-message", + "send_event", + json!({ + "type": "m.room.redaction", + "content": { + "redacts": "$1234" + }, + }), + ) + .await; + + // Receive the response + let msg = recv_message(&driver_handle).await; + assert_eq!(msg["api"], "fromWidget"); + assert_eq!(msg["action"], "send_event"); + let redact_event_id = msg["response"]["event_id"].as_str().unwrap(); + let redact_room_id = msg["response"]["room_id"].as_str().unwrap(); + + assert_eq!(redact_event_id, "$redact_event_id"); + assert_eq!(redact_room_id, "!a98sd12bjh:example.org"); + + // Make sure the event-sending endpoint was hit exactly once + mock_server.verify().await; +} + async fn negotiate_capabilities(driver_handle: &WidgetDriverHandle, caps: JsonValue) { { // Receive toWidget capabilities request