1mod args;
2mod auth;
3mod client_ip;
4mod handler;
5mod request;
6mod response;
7pub mod state;
8
9use std::str::FromStr;
10
11use axum::{
12 Router,
13 response::{IntoResponse, Redirect},
14 routing::{any, get, post},
15};
16pub use client_ip::ConfiguredIpSource;
17use http::{Uri, uri};
18use tuwunel_core::{Server, err};
19
20use self::handler::RouterExt;
21pub(super) use self::{
22 args::Args as Ruma, auth::auth_uiaa, client_ip::ClientIp, response::RumaResponse,
23 state::State,
24};
25use crate::{client, oidc, server};
26
27pub fn build(router: Router<State>, server: &Server) -> Router<State> {
28 let config = &server.config;
29 let mut router = router
30 .ruma_route(&client::get_profile_field_route)
31 .ruma_route(&client::set_profile_field_route)
32 .ruma_route(&client::delete_profile_field_route)
33 .ruma_route(&client::appservice_ping)
34 .ruma_route(&client::get_supported_versions_route)
35 .ruma_route(&client::get_register_available_route)
36 .ruma_route(&client::register_route)
37 .ruma_route(&client::get_login_types_route)
38 .ruma_route(&client::login_route)
39 .ruma_route(&client::login_token_route)
40 .ruma_route(&client::refresh_token_route)
41 .ruma_route(&client::sso_login_route)
42 .ruma_route(&client::sso_login_with_provider_route)
43 .ruma_route(&client::sso_callback_route)
44 .ruma_route(&client::sso_fallback_route)
45 .ruma_route(&client::whoami_route)
46 .ruma_route(&client::logout_route)
47 .ruma_route(&client::logout_all_route)
48 .ruma_route(&client::change_password_route)
49 .ruma_route(&client::deactivate_route)
50 .ruma_route(&client::third_party_route)
51 .ruma_route(&client::request_3pid_management_token_via_email_route)
52 .ruma_route(&client::request_3pid_management_token_via_msisdn_route)
53 .ruma_route(&client::check_registration_token_validity)
54 .ruma_route(&client::get_notifications_route)
55 .ruma_route(&client::get_capabilities_route)
56 .ruma_route(&client::get_pushrules_all_route)
57 .ruma_route(&client::get_pushrules_global_route)
58 .ruma_route(&client::set_pushrule_route)
59 .ruma_route(&client::get_pushrule_route)
60 .ruma_route(&client::set_pushrule_enabled_route)
61 .ruma_route(&client::get_pushrule_enabled_route)
62 .ruma_route(&client::get_pushrule_actions_route)
63 .ruma_route(&client::set_pushrule_actions_route)
64 .ruma_route(&client::delete_pushrule_route)
65 .ruma_route(&client::get_room_event_route)
66 .ruma_route(&client::get_room_aliases_route)
67 .ruma_route(&client::get_filter_route)
68 .ruma_route(&client::create_filter_route)
69 .ruma_route(&client::create_openid_token_route)
70 .ruma_route(&client::set_global_account_data_route)
71 .ruma_route(&client::set_room_account_data_route)
72 .ruma_route(&client::get_global_account_data_route)
73 .ruma_route(&client::get_room_account_data_route)
74 .ruma_route(&client::delete_global_account_data_route)
75 .ruma_route(&client::delete_room_account_data_route)
76 .ruma_route(&client::set_displayname_route)
77 .ruma_route(&client::get_displayname_route)
78 .ruma_route(&client::set_avatar_url_route)
79 .ruma_route(&client::get_avatar_url_route)
80 .ruma_route(&client::get_profile_route)
81 .ruma_route(&client::set_presence_route)
82 .ruma_route(&client::get_presence_route)
83 .ruma_route(&client::upload_keys_route)
84 .ruma_route(&client::get_keys_route)
85 .ruma_route(&client::claim_keys_route)
86 .ruma_route(&client::create_backup_version_route)
87 .ruma_route(&client::update_backup_version_route)
88 .ruma_route(&client::delete_backup_version_route)
89 .ruma_route(&client::get_latest_backup_info_route)
90 .ruma_route(&client::get_backup_info_route)
91 .ruma_route(&client::add_backup_keys_route)
92 .ruma_route(&client::add_backup_keys_for_room_route)
93 .ruma_route(&client::add_backup_keys_for_session_route)
94 .ruma_route(&client::delete_backup_keys_for_room_route)
95 .ruma_route(&client::delete_backup_keys_for_session_route)
96 .ruma_route(&client::delete_backup_keys_route)
97 .ruma_route(&client::get_backup_keys_for_room_route)
98 .ruma_route(&client::get_backup_keys_for_session_route)
99 .ruma_route(&client::get_backup_keys_route)
100 .ruma_route(&client::set_read_marker_route)
101 .ruma_route(&client::create_receipt_route)
102 .ruma_route(&client::create_typing_event_route)
103 .ruma_route(&client::create_room_route)
104 .ruma_route(&client::redact_event_route)
105 .ruma_route(&client::report_event_route)
106 .ruma_route(&client::report_room_route)
107 .ruma_route(&client::report_user_route)
108 .ruma_route(&client::is_user_suspended_route)
109 .ruma_route(&client::suspend_user_route)
110 .ruma_route(&client::is_user_locked_route)
111 .ruma_route(&client::lock_user_route)
112 .ruma_route(&client::create_alias_route)
113 .ruma_route(&client::delete_alias_route)
114 .ruma_route(&client::get_alias_route)
115 .ruma_route(&client::join_room_by_id_route)
116 .ruma_route(&client::join_room_by_id_or_alias_route)
117 .ruma_route(&client::joined_members_route)
118 .ruma_route(&client::knock_room_route)
119 .ruma_route(&client::leave_room_route)
120 .ruma_route(&client::forget_room_route)
121 .ruma_route(&client::joined_rooms_route)
122 .ruma_route(&client::kick_user_route)
123 .ruma_route(&client::ban_user_route)
124 .ruma_route(&client::unban_user_route)
125 .ruma_route(&client::invite_user_route)
126 .ruma_route(&client::set_room_visibility_route)
127 .ruma_route(&client::get_room_visibility_route)
128 .ruma_route(&client::get_public_rooms_route)
129 .ruma_route(&client::get_public_rooms_filtered_route)
130 .ruma_route(&client::search_users_route)
131 .ruma_route(&client::get_member_events_route)
132 .ruma_route(&client::get_protocols_route)
133 .ruma_route(&client::send_message_event_route)
134 .ruma_route(&client::send_state_event_for_key_route)
135 .ruma_route(&client::get_state_events_route)
136 .ruma_route(&client::get_state_events_for_key_route)
137 .route(
140 "/_matrix/client/r0/rooms/{room_id}/state/{event_type}",
141 get(client::get_state_events_for_empty_key_route)
142 .put(client::send_state_event_for_empty_key_route),
143 )
144 .route(
145 "/_matrix/client/v3/rooms/{room_id}/state/{event_type}",
146 get(client::get_state_events_for_empty_key_route)
147 .put(client::send_state_event_for_empty_key_route),
148 )
149 .route(
151 "/_matrix/client/r0/rooms/{room_id}/state/{event_type}/",
152 get(client::get_state_events_for_empty_key_route)
153 .put(client::send_state_event_for_empty_key_route),
154 )
155 .route(
156 "/_matrix/client/v3/rooms/{room_id}/state/{event_type}/",
157 get(client::get_state_events_for_empty_key_route)
158 .put(client::send_state_event_for_empty_key_route),
159 )
160 .ruma_route(&client::events_route)
161 .ruma_route(&client::sync_events_route)
162 .ruma_route(&client::sync_events_v5_route)
163 .ruma_route(&client::get_context_route)
164 .ruma_route(&client::get_event_by_timestamp_route)
165 .ruma_route(&client::get_message_events_route)
166 .ruma_route(&client::search_events_route)
167 .ruma_route(&client::turn_server_route)
168 .ruma_route(&client::send_event_to_device_route)
169 .ruma_route(&client::create_content_route)
170 .ruma_route(&client::create_mxc_uri_route)
171 .ruma_route(&client::create_content_async_route)
172 .ruma_route(&client::get_content_thumbnail_route)
173 .ruma_route(&client::get_content_route)
174 .ruma_route(&client::get_content_as_filename_route)
175 .ruma_route(&client::get_media_preview_route)
176 .ruma_route(&client::get_media_config_route)
177 .ruma_route(&client::get_devices_route)
178 .ruma_route(&client::get_device_route)
179 .ruma_route(&client::update_device_route)
180 .ruma_route(&client::delete_device_route)
181 .ruma_route(&client::delete_devices_route)
182 .ruma_route(&client::put_dehydrated_device_route)
183 .ruma_route(&client::delete_dehydrated_device_route)
184 .ruma_route(&client::get_dehydrated_device_route)
185 .ruma_route(&client::get_dehydrated_events_route)
186 .ruma_route(&client::get_tags_route)
187 .ruma_route(&client::update_tag_route)
188 .ruma_route(&client::delete_tag_route)
189 .ruma_route(&client::upload_signing_keys_route)
190 .ruma_route(&client::upload_signatures_route)
191 .ruma_route(&client::get_key_changes_route)
192 .ruma_route(&client::get_pushers_route)
193 .ruma_route(&client::set_pushers_route)
194 .ruma_route(&client::upgrade_room_route)
195 .ruma_route(&client::get_threads_route)
196 .ruma_route(&client::get_relating_events_with_rel_type_and_event_type_route)
197 .ruma_route(&client::get_relating_events_with_rel_type_route)
198 .ruma_route(&client::get_relating_events_route)
199 .ruma_route(&client::get_transports_route)
200 .ruma_route(&client::get_hierarchy_route)
201 .ruma_route(&client::get_mutual_rooms_route)
202 .ruma_route(&client::get_room_summary)
203 .route(
204 "/_matrix/client/unstable/im.nheko.summary/rooms/{room_id_or_alias}/summary",
205 get(client::get_room_summary_legacy)
206 )
207 .ruma_route(&client::room_initial_sync_route)
208 .route("/_tuwunel/server_version", get(client::tuwunel_server_version))
209 .route("/_tuwunel/oidc/registration", post(oidc::registration_route))
211 .route("/_tuwunel/oidc/authorize", get(oidc::authorize_route))
212 .route("/_tuwunel/oidc/_complete", get(oidc::complete_route))
213 .route("/_tuwunel/oidc/token", post(oidc::token_route))
214 .route("/_tuwunel/oidc/revoke", post(oidc::revoke_route))
215 .route("/_tuwunel/oidc/jwks", get(oidc::jwks_route))
216 .route("/_tuwunel/oidc/userinfo",
217 get(oidc::userinfo_route)
218 .post(oidc::userinfo_route)
219 )
220 .route("/_tuwunel/oidc/account.js", get(oidc::account_js_route))
221 .route("/_tuwunel/oidc/account.css", get(oidc::account_css_route))
222 .route(
223 "/_tuwunel/oidc/account_callback",
224 get(oidc::get_account_callback_route)
225 .post(oidc::post_account_callback_route),
226 )
227 .route("/_tuwunel/oidc/account", get(oidc::get_account_route))
228 .route("/_matrix/client/v1/auth_issuer", get(oidc::auth_issuer_route))
229 .route("/_matrix/client/v1/auth_metadata", get(oidc::openid_configuration_route))
230 .route(
231 "/_matrix/client/unstable/org.matrix.msc2965/auth_issuer",
232 get(oidc::auth_issuer_route)
233 )
234 .route(
235 "/_matrix/client/unstable/org.matrix.msc2965/auth_metadata",
236 get(oidc::openid_configuration_route)
237 )
238 .route("/.well-known/openid-configuration", get(oidc::openid_configuration_route))
239 .ruma_route(&client::well_known_support)
240 .ruma_route(&client::well_known_client);
241
242 router = router
244 .ruma_route(&server::well_known_server)
245 .ruma_route(&server::get_openid_userinfo_route);
246
247 if config.allow_federation {
248 router = router
249 .ruma_route(&server::get_server_version_route)
250 .route("/_matrix/key/v2/server", get(server::get_server_keys_route))
251 .route(
252 "/_matrix/key/v2/server/{key_id}",
253 get(server::get_server_keys_deprecated_route),
254 )
255 .ruma_route(&server::get_public_rooms_route)
256 .ruma_route(&server::get_public_rooms_filtered_route)
257 .ruma_route(&server::send_transaction_message_route)
258 .ruma_route(&server::get_event_route)
259 .ruma_route(&server::get_event_by_timestamp_route)
260 .ruma_route(&server::get_backfill_route)
261 .ruma_route(&server::get_missing_events_route)
262 .ruma_route(&server::get_event_authorization_route)
263 .ruma_route(&server::get_room_state_route)
264 .ruma_route(&server::get_room_state_ids_route)
265 .ruma_route(&server::create_leave_event_template_route)
266 .ruma_route(&server::create_knock_event_template_route)
267 .ruma_route(&server::create_leave_event_v2_route)
268 .ruma_route(&server::create_knock_event_v1_route)
269 .ruma_route(&server::create_join_event_template_route)
270 .ruma_route(&server::create_join_event_v2_route)
271 .ruma_route(&server::create_invite_route)
272 .ruma_route(&server::get_devices_route)
273 .ruma_route(&server::get_room_information_route)
274 .ruma_route(&server::get_profile_information_route)
275 .ruma_route(&server::get_keys_route)
276 .ruma_route(&server::claim_keys_route)
277 .ruma_route(&server::get_hierarchy_route)
278 .ruma_route(&server::get_content_route)
279 .ruma_route(&server::get_content_thumbnail_route)
280 .route("/_matrix/federation/v1/query/edutypes", get(server::get_edu_types_route))
281 .route("/_tuwunel/local_user_count", get(client::tuwunel_local_user_count));
282 } else {
283 router = router
284 .route("/_matrix/federation/{*path}", any(federation_disabled))
285 .route("/_matrix/key/{*path}", any(federation_disabled))
286 .route("/_tuwunel/local_user_count", any(federation_disabled));
287 }
288
289 if config.allow_legacy_media {
290 router = router
291 .ruma_route(&client::get_media_config_legacy_route)
292 .ruma_route(&client::get_media_preview_legacy_route)
293 .ruma_route(&client::get_content_legacy_route)
294 .ruma_route(&client::get_content_as_filename_legacy_route)
295 .ruma_route(&client::get_content_thumbnail_legacy_route);
296 } else {
297 router = router
298 .route("/_matrix/media/v3/config", any(legacy_media_disabled))
299 .route("/_matrix/media/v3/download/{*path}", any(legacy_media_disabled))
300 .route("/_matrix/media/v3/thumbnail/{*path}", any(legacy_media_disabled))
301 .route("/_matrix/media/v3/preview_url", any(redirect_legacy_preview));
302 }
303
304 router
305}
306
307async fn redirect_legacy_preview(uri: Uri) -> impl IntoResponse {
308 let path = "/_matrix/client/v1/media/preview_url";
309 let query = uri.query().unwrap_or_default();
310
311 let path_and_query = format!("{path}?{query}");
312 let path_and_query = uri::PathAndQuery::from_str(&path_and_query)
313 .expect("Failed to build PathAndQuery for media preview redirect URI");
314
315 let uri = uri::Builder::new()
316 .path_and_query(path_and_query)
317 .build()
318 .expect("Failed to build URI for redirect")
319 .to_string();
320
321 Redirect::temporary(&uri)
322}
323
324async fn legacy_media_disabled() -> impl IntoResponse {
325 err!(Request(Forbidden("Unauthenticated media is disabled.")))
326}
327
328async fn federation_disabled() -> impl IntoResponse {
329 err!(Request(Forbidden("Federation is disabled.")))
330}