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}