ruma_federation_api/thirdparty/exchange_invite.rs
1//! `PUT /_matrix/federation/*/exchange_third_party_invite/{roomId}`
2//!
3//! The receiving server will verify the partial `m.room.member` event given in the request body.
4//! If valid, the receiving server will issue an invite as per the [Inviting to a room] section
5//! before returning a response to this request.
6//!
7//! [Inviting to a room]: https://spec.matrix.org/latest/server-server-api/#inviting-to-a-room
8
9pub mod v1 {
10 //! `/v1/` ([spec])
11 //!
12 //! [spec]: https://spec.matrix.org/latest/server-server-api/#put_matrixfederationv1exchange_third_party_inviteroomid
13
14 use ruma_common::{
15 api::{request, response, Metadata},
16 metadata,
17 serde::Raw,
18 OwnedRoomId, OwnedUserId,
19 };
20 use ruma_events::{
21 room::{
22 member::{MembershipState, RoomMemberEventContent, ThirdPartyInvite},
23 third_party_invite::RoomThirdPartyInviteEventContent,
24 },
25 StateEventType,
26 };
27
28 use crate::thirdparty::bind_callback;
29
30 const METADATA: Metadata = metadata! {
31 method: PUT,
32 rate_limited: false,
33 authentication: AccessToken,
34 history: {
35 1.0 => "/_matrix/federation/v1/exchange_third_party_invite/{room_id}",
36 }
37 };
38
39 /// Request type for the `exchange_invite` endpoint.
40 #[request]
41 pub struct Request {
42 /// The room ID to exchange the third-party invite in.
43 #[ruma_api(path)]
44 pub room_id: OwnedRoomId,
45
46 /// The event type.
47 ///
48 /// Must be [`StateEventType::RoomMember`].
49 #[serde(rename = "type")]
50 pub kind: StateEventType,
51
52 /// The user ID of the user who sent the original invite event.
53 pub sender: OwnedUserId,
54
55 /// The user ID of the invited user.
56 pub state_key: OwnedUserId,
57
58 /// The content of the invite event.
59 ///
60 /// It must have a `membership` of `invite` and the `third_party_invite` field must be set.
61 pub content: Raw<RoomMemberEventContent>,
62 }
63
64 /// Response type for the `exchange_invite` endpoint.
65 #[response]
66 #[derive(Default)]
67 pub struct Response {}
68
69 impl Request {
70 /// Creates a new `Request` for a third-party invite exchange.
71 pub fn new(
72 room_id: OwnedRoomId,
73 sender: OwnedUserId,
74 state_key: OwnedUserId,
75 content: Raw<RoomMemberEventContent>,
76 ) -> Self {
77 Self { room_id, kind: StateEventType::RoomMember, sender, state_key, content }
78 }
79
80 /// Creates a new `Request` for a third-party invite exchange from a `ThirdPartyInvite`.
81 ///
82 /// Returns an error if the serialization of the event content fails.
83 pub fn with_third_party_invite(
84 room_id: OwnedRoomId,
85 sender: OwnedUserId,
86 state_key: OwnedUserId,
87 third_party_invite: ThirdPartyInvite,
88 ) -> Result<Self, serde_json::Error> {
89 let mut content = RoomMemberEventContent::new(MembershipState::Invite);
90 content.third_party_invite = Some(third_party_invite);
91 let content = Raw::new(&content)?;
92
93 Ok(Self::new(room_id, sender, state_key, content))
94 }
95
96 /// Creates a new `Request` for a third-party invite exchange from a `ThirdPartyInvite` in
97 /// the [`bind_callback::v1::Request`] and the matching
98 /// [`RoomThirdPartyInviteEventContent`].
99 ///
100 /// Returns an error if the serialization of the event content fails.
101 pub fn with_bind_callback_request_and_event(
102 bind_callback_invite: bind_callback::v1::ThirdPartyInvite,
103 room_third_party_invite_event: &RoomThirdPartyInviteEventContent,
104 ) -> Result<Self, serde_json::Error> {
105 let third_party_invite = ThirdPartyInvite::new(
106 room_third_party_invite_event.display_name.clone(),
107 bind_callback_invite.signed,
108 );
109
110 Self::with_third_party_invite(
111 bind_callback_invite.room_id,
112 bind_callback_invite.sender,
113 bind_callback_invite.mxid,
114 third_party_invite,
115 )
116 }
117 }
118
119 impl Response {
120 /// Creates a new `Response`.
121 pub fn new() -> Self {
122 Self {}
123 }
124 }
125}