palpo_core/federation/directory.rs
1/// Room directory endpoints.
2
3/// `GET /_matrix/federation/*/publicRooms`
4///
5/// Get all the public rooms for the homeserver.
6use std::collections::BTreeMap;
7
8use reqwest::Url;
9use salvo::prelude::*;
10use serde::ser::SerializeStruct;
11use serde::{Deserialize, Serialize, Serializer};
12
13use crate::directory::{PublicRoomFilter, QueryCriteria, RoomNetwork, Server};
14use crate::federation::discovery::ServerSigningKeys;
15use crate::sending::{SendRequest, SendResult};
16use crate::{OwnedServerName, OwnedServerSigningKeyId, UnixMillis};
17
18/// `POST /_matrix/federation/*/publicRooms`
19///
20/// Get a homeserver's public rooms with an optional filter.
21/// `/v1/` ([spec])
22///
23/// [spec]: https://spec.matrix.org/latest/server-server-api/#post_matrixfederationv1publicrooms
24
25// const METADATA: Metadata = metadata! {
26// method: POST,
27// rate_limited: false,
28// authentication: ServerSignatures,
29// history: {
30// 1.0 => "/_matrix/federation/v1/publicRooms",
31// }
32// };
33
34pub fn public_rooms_request(origin: &str, body: PublicRoomsReqBody) -> SendResult<SendRequest> {
35 let url = Url::parse(&format!("{origin}/_matrix/federation/v1/publicRooms"))?;
36 crate::sending::get(url).stuff(body)
37}
38
39/// Request type for the `get_filtered_public_rooms` endpoint.
40
41#[derive(ToSchema, Deserialize, Serialize, Debug)]
42pub struct PublicRoomsReqBody {
43 /// Limit for the number of results to return.
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub limit: Option<usize>,
46
47 /// Pagination token from a previous request.
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub since: Option<String>,
50
51 /// Filter to apply to the results.
52 #[serde(default, skip_serializing_if = "PublicRoomFilter::is_empty")]
53 pub filter: PublicRoomFilter,
54
55 /// Network to fetch the public room lists from.
56 #[serde(flatten, skip_serializing_if = "crate::serde::is_default")]
57 pub room_network: RoomNetwork,
58}
59crate::json_body_modifier!(PublicRoomsReqBody);
60/// `GET /.well-known/matrix/server` ([spec])
61///
62/// Get discovery information about the domain.
63///
64/// [spec]: https://spec.matrix.org/latest/server-server-api/#getwell-knownmatrixserver
65
66// const METADATA: Metadata = metadata! {
67// method: GET,
68// rate_limited: false,
69// authentication: None,
70// history: {
71// 1.0 => "/.well-known/matrix/server",
72// }
73// };
74
75/// Response type for the `discover_homeserver` endpoint.
76
77#[derive(ToSchema, Serialize, Debug)]
78pub struct ServerResBody {
79 /// The server name to delegate server-server communications to, with optional port.
80 #[serde(rename = "m.server")]
81 pub server: OwnedServerName,
82}
83
84impl ServerResBody {
85 /// Creates a new `Response` with the given homeserver.
86 pub fn new(server: OwnedServerName) -> Self {
87 Self { server }
88 }
89}
90
91/// `POST /_matrix/key/*/query`
92///
93/// Query for keys from multiple servers in a batch format. The receiving (notary) server must sign
94/// the keys returned by the queried servers.
95/// `/v2/` ([spec])
96///
97/// [spec]: https://spec.matrix.org/latest/server-server-api/#post_matrixkeyv2query
98
99// const METADATA: Metadata = metadata! {
100// method: POST,
101// rate_limited: false,
102// authentication: None,
103// history: {
104// 1.0 => "/_matrix/key/v2/query",
105// }
106// };
107
108pub fn remote_server_keys_batch_request(origin: &str, body: RemoteServerKeysBatchReqBody) -> SendResult<SendRequest> {
109 let url = Url::parse(&format!("{origin}/_matrix/key/v2/query",))?;
110 crate::sending::post(url).stuff(body)
111}
112
113/// Request type for the `get_remote_server_keys_batch` endpoint.
114
115#[derive(ToSchema, Deserialize, Serialize, Debug)]
116pub struct RemoteServerKeysBatchReqBody {
117 /// The query criteria.
118 ///
119 /// The outer string key on the object is the server name (eg: matrix.org). The inner
120 /// string key is the Key ID to query for the particular server. If no key IDs are given to
121 /// be queried, the notary server should query for all keys. If no servers are given, the
122 /// notary server must return an empty server_keys array in the response.
123 ///
124 /// The notary server may return multiple keys regardless of the Key IDs given.
125 pub server_keys: BTreeMap<OwnedServerName, BTreeMap<OwnedServerSigningKeyId, QueryCriteria>>,
126}
127crate::json_body_modifier!(RemoteServerKeysBatchReqBody);
128
129/// Response type for the `get_remote_server_keys_batch` endpoint.
130#[derive(ToSchema, Serialize, Deserialize, Debug)]
131
132pub struct RemoteServerKeysBatchResBody {
133 /// The queried server's keys, signed by the notary server.
134 pub server_keys: Vec<ServerSigningKeys>,
135}
136impl RemoteServerKeysBatchResBody {
137 /// Creates a new `Response` with the given keys.
138 pub fn new(server_keys: Vec<ServerSigningKeys>) -> Self {
139 Self { server_keys }
140 }
141}
142/// `GET /_matrix/key/*/query/{serverName}`
143///
144/// Query for another server's keys. The receiving (notary) server must sign the keys returned by
145/// the queried server.
146/// `/v2/` ([spec])
147///
148/// [spec]: https://spec.matrix.org/latest/server-server-api/#get_matrixkeyv2queryservername
149
150// const METADATA: Metadata = metadata! {
151// method: GET,
152// rate_limited: false,
153// authentication: None,
154// history: {
155// 1.0 => "/_matrix/key/v2/query/:server_name",
156// }
157// };
158
159pub fn remote_server_keys_request(origin: &str, args: RemoteServerKeysReqArgs) -> SendResult<SendRequest> {
160 let url = Url::parse(&format!(
161 "{origin}/_matrix/key/v2/query/{}?minimum_valid_until_ts={}",
162 args.server_name, args.minimum_valid_until_ts
163 ))?;
164 Ok(crate::sending::get(url))
165}
166
167/// Request type for the `get_remote_server_keys` endpoint.
168#[derive(ToParameters, Deserialize, Debug)]
169pub struct RemoteServerKeysReqArgs {
170 /// The server's DNS name to query
171 #[salvo(parameter(parameter_in = Path))]
172 pub server_name: OwnedServerName,
173
174 /// A millisecond POSIX timestamp in milliseconds indicating when the returned certificates
175 /// will need to be valid until to be useful to the requesting server.
176 ///
177 /// If not supplied, the current time as determined by the receiving server is used.
178 #[salvo(parameter(parameter_in = Query))]
179 #[serde(default = "UnixMillis::now")]
180 pub minimum_valid_until_ts: UnixMillis,
181}
182
183/// Response type for the `get_remote_server_keys` endpoint.
184#[derive(ToSchema, Deserialize, Serialize, Debug)]
185
186pub struct RemoteServerKeysResBody {
187 /// The queried server's keys, signed by the notary server.
188 pub server_keys: Vec<ServerSigningKeys>,
189}
190impl RemoteServerKeysResBody {
191 /// Creates a new `Response` with the given keys.
192 pub fn new(server_keys: Vec<ServerSigningKeys>) -> Self {
193 Self { server_keys }
194 }
195}
196
197/// `GET /_matrix/federation/*/version`
198///
199/// Get the implementation name and version of this homeserver.
200/// `/v1/` ([spec])
201///
202/// [spec]: https://spec.matrix.org/latest/server-server-api/#get_matrixfederationv1version
203
204// const METADATA: Metadata = metadata! {
205// method: GET,
206// rate_limited: false,
207// authentication: None,
208// history: {
209// 1.0 => "/_matrix/federation/v1/version",
210// }
211// };
212
213/// Response type for the `get_server_version` endpoint.
214#[derive(ToSchema, Serialize, Default, Debug)]
215
216pub struct ServerVersionResBody {
217 /// Information about the homeserver implementation
218 #[serde(skip_serializing_if = "Option::is_none")]
219 pub server: Option<Server>,
220}
221
222impl ServerVersionResBody {
223 /// Creates an empty `Response`.
224 pub fn new() -> Self {
225 Default::default()
226 }
227}
228
229/// Endpoint to receive metadata about implemented matrix versions.
230///
231/// Get the supported matrix versions of this homeserver
232/// [GET /_matrix/federation/versions](https://github.com/matrix-org/matrix-spec-proposals/pull/3723)
233// const METADATA: Metadata = metadata! {
234// method: GET,
235// rate_limited: false,
236// authentication: None,
237// history: {
238// unstable => "/_matrix/federation/unstable/org.matrix.msc3723/versions",
239// }
240// };
241
242/// Response type for the `get_server_versions` endpoint.
243#[derive(ToSchema, Serialize, Default, Debug)]
244
245pub struct ServerVersionsResBody {
246 /// A list of Matrix Server API protocol versions supported by the homeserver.
247 pub versions: Vec<String>,
248}
249impl ServerVersionsResBody {
250 /// Creates an empty `Response`.
251 pub fn new() -> Self {
252 Default::default()
253 }
254}
255
256/// `GET /_matrix/key/*/server`
257///
258/// Get the homeserver's published signing keys.
259/// `/v2/` ([spec])
260///
261/// [spec]: https://spec.matrix.org/latest/server-server-api/#get_matrixkeyv2server
262// const METADATA: Metadata = metadata! {
263// method: GET,
264// rate_limited: false,
265// authentication: None,
266// history: {
267// 1.0 => "/_matrix/key/v2/server",
268// }
269// };
270
271pub fn server_keys_request(origin: &str) -> SendResult<SendRequest> {
272 let url = Url::parse(&format!("{origin}/_matrix/key/v2/server",))?;
273 Ok(crate::sending::get(url))
274}
275
276/// Response type for the `get_server_keys` endpoint.
277#[derive(ToSchema, Deserialize, Debug)]
278
279pub struct ServerKeysResBody(
280 /// Queried server key, signed by the notary server.
281 pub ServerSigningKeys,
282);
283
284impl ServerKeysResBody {
285 /// Creates a new `Response` with the given server key.
286 pub fn new(server_key: ServerSigningKeys) -> Self {
287 Self(server_key)
288 }
289}
290
291impl From<ServerSigningKeys> for ServerKeysResBody {
292 fn from(server_key: ServerSigningKeys) -> Self {
293 Self::new(server_key)
294 }
295}
296
297impl Serialize for ServerKeysResBody {
298 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
299 where
300 S: Serializer,
301 {
302 let mut st = serializer.serialize_struct("server_keys_res_body", 2)?;
303
304 st.serialize_field("old_verify_keys", &self.0.old_verify_keys)?;
305 st.serialize_field("server_name", &self.0.server_name)?;
306 st.serialize_field("signatures", &self.0.signatures)?;
307 st.serialize_field("valid_until_ts", &self.0.valid_until_ts)?;
308 st.serialize_field("verify_keys", &self.0.verify_keys)?;
309 st.end()
310 }
311}