mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-10-23 10:12:23 +00:00
feat: Give send_knock the invite treatment
This commit is contained in:
1 parent
f0590e882a
commit
efd07da0d7
3 files changed
+146
-180
No files matched your search
+103
-2
@@ -1,7 +1,10 @@
|
||||
use conduwuit::{Err, Result, is_false};
|
||||
use conduwuit::{Err, Result, err, is_false};
|
||||
use conduwuit_service::Services;
|
||||
use futures::{FutureExt, future::OptionFuture, join};
|
||||
use ruma::{EventId, RoomId, ServerName};
|
||||
use ruma::{
|
||||
CanonicalJsonObject, EventId, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, ServerName,
|
||||
UserId, events::room::member::MembershipState, room_version_rules::RoomVersionRules,
|
||||
};
|
||||
|
||||
pub(super) struct AccessCheck<'a> {
|
||||
pub(super) services: &'a Services,
|
||||
@@ -63,3 +66,101 @@ pub(super) async fn assert(&self) -> Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs validation on a membership event that should be run on any event a
|
||||
/// remote is trying to send via us.
|
||||
///
|
||||
/// ## Checks performed
|
||||
///
|
||||
/// 1. PDU room ID matches request path room ID
|
||||
/// 2. PDU event ID matches request path event ID
|
||||
/// 3. Signature check
|
||||
/// 4. Event type check
|
||||
/// 5. `sender` field presence (and parsing)
|
||||
/// 6. `state_key` field presence (and parsing)
|
||||
/// 7. PDU room format check (PDU check 1)
|
||||
///
|
||||
/// ## Returns
|
||||
///
|
||||
/// A resulting tuple of (PDU JSON, target membership state, sender, recipient).
|
||||
pub(crate) async fn validate_any_membership_event(
|
||||
services: &crate::State,
|
||||
body: &serde_json::value::RawValue,
|
||||
room_version_rules: &RoomVersionRules,
|
||||
create_event_id: OwnedEventId,
|
||||
expected_room_id: OwnedRoomId,
|
||||
expected_event_id: OwnedEventId,
|
||||
) -> Result<(CanonicalJsonObject, MembershipState, OwnedUserId, OwnedUserId)> {
|
||||
let (template_room_id, template_event_id, pdu) = services
|
||||
.rooms
|
||||
.event_handler
|
||||
.parse_incoming_pdu(body)
|
||||
.await
|
||||
.map_err(|e| err!(Request(BadJson("Invalid membership PDU: {e}"))))?;
|
||||
|
||||
if template_room_id != expected_room_id {
|
||||
return Err!(Request(InvalidParam("Membership event does not belong to requested room")));
|
||||
}
|
||||
if template_event_id != expected_event_id {
|
||||
return Err!(Request(InvalidParam(
|
||||
"Membership event ID does not match provided event ID"
|
||||
)));
|
||||
}
|
||||
|
||||
services
|
||||
.server_keys
|
||||
.verify_event(&pdu, room_version_rules)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
err!(Request(InvalidParam("Signature verification failed on membership event: {e}")))
|
||||
})?;
|
||||
|
||||
// Ensure this is a membership event
|
||||
if pdu
|
||||
.get("type")
|
||||
.expect("event must have a type")
|
||||
.as_str()
|
||||
.expect("type must be a string")
|
||||
!= "m.room.member"
|
||||
{
|
||||
return Err!(Request(BadJson(
|
||||
"Not allowed to send non-membership event to this endpoint"
|
||||
)));
|
||||
}
|
||||
let membership = pdu
|
||||
.get("content")
|
||||
.ok_or_else(|| err!(Request(BadJson("Event missing content property"))))?
|
||||
.as_object()
|
||||
.ok_or_else(|| err!(Request(BadJson("Event content is not an object"))))?
|
||||
.get("membership")
|
||||
.ok_or_else(|| err!(Request(BadJson("Event missing membership property"))))?
|
||||
.as_str()
|
||||
.ok_or_else(|| err!(Request(BadJson("Event is not a string"))))?
|
||||
.to_owned();
|
||||
|
||||
let sender_user = pdu
|
||||
.get("sender")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(UserId::parse)
|
||||
.and_then(Result::ok)
|
||||
.ok_or_else(|| err!(Request(InvalidParam("Invalid sender property"))))?;
|
||||
let recipient_user = pdu
|
||||
.get("state_key")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(UserId::parse)
|
||||
.and_then(Result::ok)
|
||||
.ok_or_else(|| err!(Request(InvalidParam("Invalid state_key property"))))?;
|
||||
|
||||
// Do a quick format check. The spec doesn't suggest this, but it's probably
|
||||
// a good idea nonetheless.
|
||||
service::rooms::event_handler::Service::pdu_format_check_1(
|
||||
&pdu,
|
||||
room_version_rules,
|
||||
&create_event_id,
|
||||
)
|
||||
.map_err(|e| {
|
||||
err!(Request(InvalidParam("Membership event violates the room event format: {e}")))
|
||||
})?;
|
||||
|
||||
Ok((pdu, membership.into(), sender_user, recipient_user))
|
||||
}
|
||||
Reference in new issue
Block a user