split send from messages; refactor client/messages; add filters to client/context
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
6c9ecb031a
commit
7a09ac81e0
5 changed files with 403 additions and 438 deletions
92
src/api/client/send.rs
Normal file
92
src/api/client/send.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use axum::extract::State;
|
||||
use conduit::{err, Err};
|
||||
use ruma::{api::client::message::send_message_event, events::MessageLikeEventType};
|
||||
use serde_json::from_str;
|
||||
|
||||
use crate::{service::pdu::PduBuilder, utils, Result, Ruma};
|
||||
|
||||
/// # `PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}`
|
||||
///
|
||||
/// Send a message event into the room.
|
||||
///
|
||||
/// - Is a NOOP if the txn id was already used before and returns the same event
|
||||
/// id again
|
||||
/// - The only requirement for the content is that it has to be valid json
|
||||
/// - Tries to send the event into the room, auth rules will determine if it is
|
||||
/// allowed
|
||||
pub(crate) async fn send_message_event_route(
|
||||
State(services): State<crate::State>, body: Ruma<send_message_event::v3::Request>,
|
||||
) -> Result<send_message_event::v3::Response> {
|
||||
let sender_user = body.sender_user();
|
||||
let sender_device = body.sender_device.as_deref();
|
||||
let appservice_info = body.appservice_info.as_ref();
|
||||
|
||||
// Forbid m.room.encrypted if encryption is disabled
|
||||
if MessageLikeEventType::RoomEncrypted == body.event_type && !services.globals.allow_encryption() {
|
||||
return Err!(Request(Forbidden("Encryption has been disabled")));
|
||||
}
|
||||
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
|
||||
if body.event_type == MessageLikeEventType::CallInvite
|
||||
&& services.rooms.directory.is_public_room(&body.room_id).await
|
||||
{
|
||||
return Err!(Request(Forbidden("Room call invites are not allowed in public rooms")));
|
||||
}
|
||||
|
||||
// Check if this is a new transaction id
|
||||
if let Ok(response) = services
|
||||
.transaction_ids
|
||||
.existing_txnid(sender_user, sender_device, &body.txn_id)
|
||||
.await
|
||||
{
|
||||
// The client might have sent a txnid of the /sendToDevice endpoint
|
||||
// This txnid has no response associated with it
|
||||
if response.is_empty() {
|
||||
return Err!(Request(InvalidParam(
|
||||
"Tried to use txn id already used for an incompatible endpoint."
|
||||
)));
|
||||
}
|
||||
|
||||
return Ok(send_message_event::v3::Response {
|
||||
event_id: utils::string_from_bytes(&response)
|
||||
.map(TryInto::try_into)
|
||||
.map_err(|e| err!(Database("Invalid event_id in txnid data: {e:?}")))??,
|
||||
});
|
||||
}
|
||||
|
||||
let mut unsigned = BTreeMap::new();
|
||||
unsigned.insert("transaction_id".to_owned(), body.txn_id.to_string().into());
|
||||
|
||||
let content =
|
||||
from_str(body.body.body.json().get()).map_err(|e| err!(Request(BadJson("Invalid JSON body: {e}"))))?;
|
||||
|
||||
let event_id = services
|
||||
.rooms
|
||||
.timeline
|
||||
.build_and_append_pdu(
|
||||
PduBuilder {
|
||||
event_type: body.event_type.clone().into(),
|
||||
content,
|
||||
unsigned: Some(unsigned),
|
||||
timestamp: appservice_info.and(body.timestamp),
|
||||
..Default::default()
|
||||
},
|
||||
sender_user,
|
||||
&body.room_id,
|
||||
&state_lock,
|
||||
)
|
||||
.await?;
|
||||
|
||||
services
|
||||
.transaction_ids
|
||||
.add_txnid(sender_user, sender_device, &body.txn_id, event_id.as_bytes());
|
||||
|
||||
drop(state_lock);
|
||||
|
||||
Ok(send_message_event::v3::Response {
|
||||
event_id: event_id.into(),
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue