mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-04-23 14:55:40 +00:00
refactor: Fix errors in api/server/invite.rs
This commit is contained in:
@@ -8,8 +8,11 @@
|
||||
warn,
|
||||
};
|
||||
use ruma::{
|
||||
CanonicalJsonValue, OwnedUserId, UserId,
|
||||
api::{client::error::ErrorKind, federation::membership::create_invite},
|
||||
CanonicalJsonValue, UserId,
|
||||
api::{
|
||||
error::{ErrorKind, IncompatibleRoomVersionErrorData},
|
||||
federation::membership::{RawStrippedState, create_invite},
|
||||
},
|
||||
events::room::member::{MembershipState, RoomMemberEventContent},
|
||||
serde::JsonObject,
|
||||
};
|
||||
@@ -34,11 +37,15 @@ pub(crate) async fn create_invite_route(
|
||||
|
||||
if !services.server.supported_room_version(&body.room_version) {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::IncompatibleRoomVersion { room_version: body.room_version.clone() },
|
||||
ErrorKind::IncompatibleRoomVersion(IncompatibleRoomVersionErrorData::new(
|
||||
body.room_version.clone(),
|
||||
)),
|
||||
"Server does not support this room version.",
|
||||
));
|
||||
}
|
||||
|
||||
let room_version_rules = body.room_version.rules().unwrap();
|
||||
|
||||
if let Some(server) = body.room_id.server_name() {
|
||||
if services.moderation.is_remote_server_forbidden(server) {
|
||||
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
|
||||
@@ -91,21 +98,24 @@ pub(crate) async fn create_invite_route(
|
||||
}
|
||||
|
||||
// Ensure the sending user isn't a lying bozo
|
||||
let sender_server = signed_event
|
||||
let sender_user = signed_event
|
||||
.get("sender")
|
||||
.try_into()
|
||||
.map(UserId::server_name)
|
||||
.map_err(|e| err!(Request(InvalidParam("Invalid sender property: {e}"))))?;
|
||||
if sender_server != body.origin() {
|
||||
.and_then(|v| v.as_str())
|
||||
.map(UserId::parse)
|
||||
.and_then(Result::ok)
|
||||
.ok_or_else(|| err!(Request(InvalidParam("Invalid sender property"))))?;
|
||||
|
||||
if sender_user.server_name() != body.origin() {
|
||||
return Err!(Request(Forbidden("Sender's server does not match the origin server.",)));
|
||||
}
|
||||
|
||||
// Ensure the target user belongs to this server
|
||||
let recipient_user: OwnedUserId = signed_event
|
||||
let recipient_user = signed_event
|
||||
.get("state_key")
|
||||
.try_into()
|
||||
.map(UserId::to_owned)
|
||||
.map_err(|e| err!(Request(InvalidParam("Invalid state_key property: {e}"))))?;
|
||||
.and_then(|v| v.as_str())
|
||||
.map(UserId::parse)
|
||||
.and_then(Result::ok)
|
||||
.ok_or_else(|| err!(Request(InvalidParam("Invalid state_key property"))))?;
|
||||
|
||||
if !services
|
||||
.globals
|
||||
@@ -123,20 +133,15 @@ pub(crate) async fn create_invite_route(
|
||||
|
||||
services
|
||||
.server_keys
|
||||
.hash_and_sign_event(&mut signed_event, &body.room_version)
|
||||
.hash_and_sign_event(&mut signed_event, &room_version_rules)
|
||||
.map_err(|e| err!(Request(InvalidParam("Failed to sign event: {e}"))))?;
|
||||
|
||||
// Generate event id
|
||||
let event_id = gen_event_id(&signed_event, &body.room_version)?;
|
||||
let event_id = gen_event_id(&signed_event, &room_version_rules)?;
|
||||
|
||||
// Add event_id back
|
||||
signed_event.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.to_string()));
|
||||
|
||||
let sender_user: &UserId = signed_event
|
||||
.get("sender")
|
||||
.try_into()
|
||||
.map_err(|e| err!(Request(InvalidParam("Invalid sender property: {e}"))))?;
|
||||
|
||||
if services.rooms.metadata.is_banned(&body.room_id).await
|
||||
&& !services.users.is_admin(&recipient_user).await
|
||||
{
|
||||
@@ -167,7 +172,7 @@ pub(crate) async fn create_invite_route(
|
||||
let pdu: PduEvent = serde_json::from_value(event.into())
|
||||
.map_err(|e| err!(Request(BadJson("Invalid invite event PDU: {e}"))))?;
|
||||
|
||||
invite_state.push(pdu.to_format());
|
||||
invite_state.push(RawStrippedState::Pdu(pdu.content.clone()));
|
||||
|
||||
// If we are active in the room, the remote server will notify us about the
|
||||
// join/invite through /send. If we are not in the room, we need to manually
|
||||
@@ -185,8 +190,8 @@ pub(crate) async fn create_invite_route(
|
||||
.mark_as_invited(
|
||||
&recipient_user,
|
||||
&body.room_id,
|
||||
sender_user,
|
||||
Some(invite_state),
|
||||
&sender_user,
|
||||
invite_state,
|
||||
body.via.clone(),
|
||||
)
|
||||
.await?;
|
||||
@@ -199,14 +204,15 @@ pub(crate) async fn create_invite_route(
|
||||
|
||||
for appservice in services.appservice.read().await.values() {
|
||||
if appservice.is_user_match(&recipient_user) {
|
||||
let request = ruma::api::appservice::event::push_events::v1::Request {
|
||||
events: vec![pdu.to_format()],
|
||||
txn_id: general_purpose::URL_SAFE_NO_PAD
|
||||
.encode(sha256::hash(pdu.event_id.as_bytes()))
|
||||
.into(),
|
||||
ephemeral: Vec::new(),
|
||||
to_device: Vec::new(),
|
||||
};
|
||||
let transaction_id = general_purpose::URL_SAFE_NO_PAD
|
||||
.encode(sha256::hash(pdu.event_id.as_bytes()))
|
||||
.into();
|
||||
|
||||
let request = ruma::api::appservice::event::push_events::v1::Request::new(
|
||||
transaction_id,
|
||||
vec![pdu.to_format()],
|
||||
);
|
||||
|
||||
services
|
||||
.sending
|
||||
.send_appservice_request(appservice.registration.clone(), request)
|
||||
@@ -224,10 +230,10 @@ pub(crate) async fn create_invite_route(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(create_invite::v2::Response {
|
||||
event: services
|
||||
Ok(create_invite::v2::Response::new(
|
||||
services
|
||||
.sending
|
||||
.convert_to_outgoing_federation_event(signed_event)
|
||||
.await,
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
use futures::StreamExt;
|
||||
use ruma::{
|
||||
OwnedServerName, RoomId, UserId,
|
||||
api::federation::membership::RawStrippedState,
|
||||
events::{
|
||||
AnyStrippedStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType,
|
||||
StateEventType,
|
||||
@@ -118,8 +119,17 @@ pub async fn update_membership(
|
||||
self.mark_as_joined(user_id, room_id);
|
||||
},
|
||||
| MembershipState::Invite => {
|
||||
let last_state = self.services.state.summary_stripped(pdu, room_id).await;
|
||||
self.mark_as_invited(user_id, room_id, pdu.sender(), Some(last_state), None)
|
||||
#[allow(deprecated)]
|
||||
let last_state = self
|
||||
.services
|
||||
.state
|
||||
.summary_stripped(pdu, room_id)
|
||||
.await
|
||||
.into_iter()
|
||||
.map(RawStrippedState::Stripped)
|
||||
.collect();
|
||||
|
||||
self.mark_as_invited(user_id, room_id, pdu.sender(), last_state, None)
|
||||
.await?;
|
||||
},
|
||||
| MembershipState::Leave | MembershipState::Ban => {
|
||||
@@ -332,7 +342,7 @@ pub async fn mark_as_invited(
|
||||
user_id: &UserId,
|
||||
room_id: &RoomId,
|
||||
sender_user: &UserId,
|
||||
last_state: Option<Vec<Raw<AnyStrippedStateEvent>>>,
|
||||
last_state: Vec<RawStrippedState>,
|
||||
invite_via: Option<Vec<OwnedServerName>>,
|
||||
) -> Result<()> {
|
||||
// return an error for blocked invites. ignored invites aren't handled here
|
||||
@@ -356,7 +366,7 @@ pub async fn mark_as_invited(
|
||||
|
||||
self.db
|
||||
.userroomid_invitestate
|
||||
.raw_put(&userroom_id, Json(last_state.unwrap_or_default()));
|
||||
.raw_put(&userroom_id, Json(last_state));
|
||||
self.db
|
||||
.roomuserid_invitecount
|
||||
.raw_aput::<8, _, _>(&roomuser_id, self.services.globals.next_count().unwrap());
|
||||
|
||||
Reference in New Issue
Block a user