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},
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::{authentication::ServerSignatures, thirdparty::bind_callback};
29
30    metadata! {
31        method: PUT,
32        rate_limited: false,
33        authentication: ServerSignatures,
34        path: "/_matrix/federation/v1/exchange_third_party_invite/{room_id}",
35    }
36
37    /// Request type for the `exchange_invite` endpoint.
38    #[request]
39    pub struct Request {
40        /// The room ID to exchange the third-party invite in.
41        #[ruma_api(path)]
42        pub room_id: OwnedRoomId,
43
44        /// The event type.
45        ///
46        /// Must be [`StateEventType::RoomMember`].
47        #[serde(rename = "type")]
48        pub kind: StateEventType,
49
50        /// The user ID of the user who sent the original invite event.
51        pub sender: OwnedUserId,
52
53        /// The user ID of the invited user.
54        pub state_key: OwnedUserId,
55
56        /// The content of the invite event.
57        ///
58        /// It must have a `membership` of `invite` and the `third_party_invite` field must be set.
59        pub content: Raw<RoomMemberEventContent>,
60    }
61
62    /// Response type for the `exchange_invite` endpoint.
63    #[response]
64    #[derive(Default)]
65    pub struct Response {}
66
67    impl Request {
68        /// Creates a new `Request` for a third-party invite exchange.
69        pub fn new(
70            room_id: OwnedRoomId,
71            sender: OwnedUserId,
72            state_key: OwnedUserId,
73            content: Raw<RoomMemberEventContent>,
74        ) -> Self {
75            Self { room_id, kind: StateEventType::RoomMember, sender, state_key, content }
76        }
77
78        /// Creates a new `Request` for a third-party invite exchange from a `ThirdPartyInvite`.
79        ///
80        /// Returns an error if the serialization of the event content fails.
81        pub fn with_third_party_invite(
82            room_id: OwnedRoomId,
83            sender: OwnedUserId,
84            state_key: OwnedUserId,
85            third_party_invite: ThirdPartyInvite,
86        ) -> Result<Self, serde_json::Error> {
87            let mut content = RoomMemberEventContent::new(MembershipState::Invite);
88            content.third_party_invite = Some(third_party_invite);
89            let content = Raw::new(&content)?;
90
91            Ok(Self::new(room_id, sender, state_key, content))
92        }
93
94        /// Creates a new `Request` for a third-party invite exchange from a `ThirdPartyInvite` in
95        /// the [`bind_callback::v1::Request`] and the matching
96        /// [`RoomThirdPartyInviteEventContent`].
97        ///
98        /// Returns an error if the serialization of the event content fails.
99        pub fn with_bind_callback_request_and_event(
100            bind_callback_invite: bind_callback::v1::ThirdPartyInvite,
101            room_third_party_invite_event: &RoomThirdPartyInviteEventContent,
102        ) -> Result<Self, serde_json::Error> {
103            let third_party_invite = ThirdPartyInvite::new(
104                room_third_party_invite_event.display_name.clone(),
105                bind_callback_invite.signed,
106            );
107
108            Self::with_third_party_invite(
109                bind_callback_invite.room_id,
110                bind_callback_invite.sender,
111                bind_callback_invite.mxid,
112                third_party_invite,
113            )
114        }
115    }
116
117    impl Response {
118        /// Creates a new `Response`.
119        pub fn new() -> Self {
120            Self {}
121        }
122    }
123}