1mod args;
2mod auth;
3mod client_ip;
4mod handler;
5mod request;
6mod response;
7pub mod state;
8
9use axum::{
10 Router,
11 response::IntoResponse,
12 routing::{any, get, post},
13};
14pub use client_ip::{ConfiguredIpSource, TrustedPeerSubnets};
15use const_str::{concat, join, replace};
16use http::{HeaderValue, header};
17use tower_http::set_header::SetResponseHeaderLayer;
18use tuwunel_core::{Server, err};
19
20use self::handler::RouterExt;
21pub(super) use self::{
22 args::{Args as Ruma, ArgsAdmin as RumaAdmin},
23 auth::auth_uiaa,
24 client_ip::ClientIp,
25 response::RumaResponse,
26 state::State,
27};
28use crate::{
30 client, oidc,
31 oidc::{complete_route as oidc_complete, post_complete_route as oidc_post_complete},
32 server,
33};
34
35pub fn build(router: Router<State>, server: &Server) -> Router<State> {
36 let config = &server.config;
37 let mas_active = client::mas_active(config);
38 let router = register_client_auth_routes(router);
39 let router = register_mas_routes(router);
40 let router = register_client_profile_and_data_routes(router);
41 let router = register_client_keys_and_backup_routes(router);
42 let router = register_client_room_routes(router);
43 let router = register_client_state_and_sync_routes(router);
44 let router = register_client_media_and_device_routes(
45 router,
46 config.media_deny_framing,
47 config.media_deny_inline_styles,
48 );
49
50 let router = register_client_misc_routes(router);
51 let router = register_synapse_admin_users_routes(router, mas_active);
52 let router = register_synapse_admin_devices_routes(router, mas_active);
53 let router = register_synapse_admin_rooms_routes(router);
54 let router = register_synapse_admin_media_routes(router);
55 let router = register_synapse_admin_federation_routes(router);
56 let router = register_synapse_admin_misc_routes(router);
57 let router = register_oidc_routes(router);
58 let router = register_rendezvous_routes(router);
59 let router = register_server_misc_routes(router);
60 let router = register_federation_routes(router, config.allow_federation);
61
62 register_legacy_media_routes(
63 router,
64 config.allow_legacy_media,
65 config.media_deny_framing,
66 config.media_deny_inline_styles,
67 )
68}
69
70fn register_client_auth_routes(router: Router<State>) -> Router<State> {
71 router
72 .ruma_route(&client::get_supported_versions_route)
73 .ruma_route(&client::get_register_available_route)
74 .ruma_route(&client::register_route)
75 .ruma_route(&client::get_login_types_route)
76 .ruma_route(&client::login_route)
77 .ruma_route(&client::login_token_route)
78 .ruma_route(&client::refresh_token_route)
79 .ruma_route(&client::sso_login_route)
80 .ruma_route(&client::sso_login_with_provider_route)
81 .ruma_route(&client::sso_callback_route)
82 .ruma_route(&client::sso_fallback_route)
83 .ruma_route(&client::whoami_route)
84 .ruma_route(&client::logout_route)
85 .ruma_route(&client::logout_all_route)
86 .ruma_route(&client::change_password_route)
87 .ruma_route(&client::deactivate_route)
88 .ruma_route(&client::third_party_route)
89 .ruma_route(&client::add_3pid_route)
90 .ruma_route(&client::delete_3pid_route)
91 .ruma_route(&client::request_3pid_management_token_via_email_route)
92 .ruma_route(&client::request_3pid_management_token_via_msisdn_route)
93 .ruma_route(&client::request_registration_token_via_email_route)
94 .ruma_route(&client::request_password_change_token_via_email_route)
95 .ruma_route(&client::check_registration_token_validity)
96 .ruma_route(&client::create_openid_token_route)
97 .ruma_route(&client::is_user_suspended_route)
98 .ruma_route(&client::suspend_user_route)
99 .ruma_route(&client::is_user_locked_route)
100 .ruma_route(&client::lock_user_route)
101 .route("/_tuwunel/sso/complete.js", get(client::sso_complete_js_route))
102 .route("/_tuwunel/sso/sso.css", get(client::sso_css_route))
103}
104
105fn register_mas_routes(router: Router<State>) -> Router<State> {
106 router
107 .ruma_route(&client::mas::query_user_route)
108 .ruma_route(&client::mas::provision_user_route)
109 .ruma_route(&client::mas::is_localpart_available_route)
110 .ruma_route(&client::mas::delete_user_route)
111 .ruma_route(&client::mas::reactivate_user_route)
112 .ruma_route(&client::mas::set_displayname_route)
113 .ruma_route(&client::mas::unset_displayname_route)
114 .ruma_route(&client::mas::allow_cross_signing_reset_route)
115 .ruma_route(&client::mas::upsert_device_route)
116 .ruma_route(&client::mas::delete_device_route)
117 .ruma_route(&client::mas::update_device_display_name_route)
118 .ruma_route(&client::mas::sync_devices_route)
119}
120
121fn register_synapse_admin_users_routes(router: Router<State>, mas_active: bool) -> Router<State> {
122 let router = router
123 .ruma_route(&client::users::admin_list_users_v2_route)
124 .ruma_route(&client::users::admin_list_users_v3_route)
125 .ruma_route(&client::users::admin_get_details_route)
126 .ruma_route(&client::users::admin_create_or_modify_route)
127 .ruma_route(&client::users::admin_deactivate_account_route)
128 .ruma_route(&client::users::admin_list_joined_rooms_route)
129 .ruma_route(&client::users::admin_memberships_route)
130 .ruma_route(&client::users::admin_pushers_route)
131 .ruma_route(&client::users::admin_account_data_route)
132 .ruma_route(&client::users::admin_suspend_route)
133 .ruma_route(&client::users::admin_username_available_route)
134 .ruma_route(&client::users::admin_lookup_threepid_route)
135 .ruma_route(&client::users::admin_allow_cross_signing_replacement_route)
136 .ruma_route(&client::users::admin_redact_user_route)
137 .ruma_route(&client::users::admin_redact_status_route)
138 .route("/_synapse/admin/v1/whois/{user_id}", get(client::users::admin_whois_route))
141 .route("/_matrix/client/v3/admin/whois/{user_id}", get(client::users::admin_whois_route))
142 .route("/_matrix/client/r0/admin/whois/{user_id}", get(client::users::admin_whois_route))
143 .route(
144 "/_matrix/client/unstable/admin/whois/{user_id}",
145 get(client::users::admin_whois_route),
146 );
147
148 if mas_active {
152 router
153 } else {
154 router
155 .ruma_route(&client::admin_register_nonce_route)
156 .ruma_route(&client::admin_register_route)
157 .ruma_route(&client::users::admin_reset_password_route)
158 .ruma_route(&client::users::admin_is_user_admin_route)
159 .ruma_route(&client::users::admin_login_as_route)
160 }
161}
162
163fn register_synapse_admin_devices_routes(
164 router: Router<State>,
165 mas_active: bool,
166) -> Router<State> {
167 let router = router
168 .ruma_route(&client::devices::admin_list_devices_route)
169 .ruma_route(&client::devices::admin_create_device_route)
170 .ruma_route(&client::devices::admin_get_device_route)
171 .ruma_route(&client::devices::admin_update_device_route)
172 .ruma_route(&client::devices::admin_delete_device_route)
173 .ruma_route(&client::devices::admin_delete_devices_route);
174
175 if mas_active {
178 router
179 } else {
180 router
181 .ruma_route(&client::tokens::admin_list_tokens_route)
182 .ruma_route(&client::tokens::admin_create_token_route)
183 .ruma_route(&client::tokens::admin_get_token_route)
184 .ruma_route(&client::tokens::admin_update_token_route)
185 .ruma_route(&client::tokens::admin_delete_token_route)
186 }
187}
188
189fn register_synapse_admin_rooms_routes(router: Router<State>) -> Router<State> {
190 router
191 .ruma_route(&client::rooms::admin_list_rooms_route)
192 .ruma_route(&client::rooms::admin_room_details_route)
193 .ruma_route(&client::rooms::admin_room_members_route)
194 .ruma_route(&client::rooms::admin_join_room_route)
195 .ruma_route(&client::rooms::admin_get_room_block_route)
196 .ruma_route(&client::rooms::admin_set_room_block_route)
197 .ruma_route(&client::rooms::admin_make_room_admin_route)
198 .ruma_route(&client::rooms::admin_delete_room_v1_route)
199 .ruma_route(&client::rooms::admin_delete_room_v2_route)
200 .ruma_route(&client::rooms::admin_delete_status_by_id_route)
201 .ruma_route(&client::rooms::admin_delete_status_by_room_route)
202 .ruma_route(&client::rooms::admin_get_forward_extremities_route)
203 .ruma_route(&client::rooms::admin_delete_forward_extremities_route)
204 .ruma_route(&client::rooms::admin_purge_history_route)
205 .ruma_route(&client::rooms::admin_purge_history_by_event_route)
206 .ruma_route(&client::rooms::admin_purge_history_status_route)
207 .ruma_route(&client::rooms::admin_room_state_route)
208 .ruma_route(&client::rooms::admin_room_messages_route)
209 .ruma_route(&client::rooms::admin_room_context_route)
210 .ruma_route(&client::rooms::admin_room_timestamp_to_event_route)
211 .ruma_route(&client::rooms::admin_room_hierarchy_route)
212}
213
214fn register_synapse_admin_media_routes(router: Router<State>) -> Router<State> {
215 router
216 .ruma_route(&client::admin::media::admin_query_media_route)
217 .ruma_route(&client::admin::media::admin_delete_media_route)
218 .ruma_route(&client::admin::media::admin_list_user_media_route)
219 .ruma_route(&client::admin::media::admin_list_room_media_route)
220 .ruma_route(&client::admin::media::admin_delete_user_media_route)
221 .ruma_route(&client::admin::media::admin_purge_media_cache_route)
222 .ruma_route(&client::admin::media::admin_user_media_statistics_route)
223 .route(
224 "/_synapse/admin/v1/media/delete",
225 post(client::admin::media::admin_delete_media_by_date_size_route),
226 )
227 .route(
229 "/_synapse/admin/v1/media/{server_name}/delete",
230 post(client::admin::media::admin_delete_media_by_date_size_route),
231 )
232}
233
234fn register_synapse_admin_federation_routes(router: Router<State>) -> Router<State> {
235 router
236 .ruma_route(&client::admin::federation::admin_list_destinations_route)
237 .ruma_route(&client::admin::federation::admin_destination_details_route)
238 .ruma_route(&client::admin::federation::admin_destination_rooms_route)
239 .ruma_route(&client::admin::federation::admin_reset_connection_route)
240}
241
242fn register_synapse_admin_misc_routes(router: Router<State>) -> Router<State> {
243 router
244 .ruma_route(&client::misc::admin_server_version_route)
245 .ruma_route(&client::misc::admin_fetch_event_route)
246 .ruma_route(&client::misc::admin_scheduled_tasks_route)
247 .ruma_route(&client::misc::admin_send_server_notice_route)
248 .ruma_route(&client::misc::admin_send_server_notice_txn_route)
249}
250
251fn register_client_profile_and_data_routes(router: Router<State>) -> Router<State> {
252 router
253 .ruma_route(&client::get_profile_field_route)
254 .ruma_route(&client::set_profile_field_route)
255 .ruma_route(&client::delete_profile_field_route)
256 .ruma_route(&client::get_profile_route)
257 .ruma_route(&client::set_presence_route)
258 .ruma_route(&client::get_presence_route)
259 .ruma_route(&client::get_filter_route)
260 .ruma_route(&client::create_filter_route)
261 .ruma_route(&client::set_global_account_data_route)
262 .ruma_route(&client::set_room_account_data_route)
263 .ruma_route(&client::get_global_account_data_route)
264 .ruma_route(&client::get_room_account_data_route)
265 .ruma_route(&client::delete_global_account_data_route)
266 .ruma_route(&client::delete_room_account_data_route)
267 .ruma_route(&client::get_tags_route)
268 .ruma_route(&client::update_tag_route)
269 .ruma_route(&client::delete_tag_route)
270 .ruma_route(&client::get_pushrules_all_route)
271 .ruma_route(&client::get_pushrules_global_route)
272 .ruma_route(&client::set_pushrule_route)
273 .ruma_route(&client::get_pushrule_route)
274 .ruma_route(&client::set_pushrule_enabled_route)
275 .ruma_route(&client::get_pushrule_enabled_route)
276 .ruma_route(&client::get_pushrule_actions_route)
277 .ruma_route(&client::set_pushrule_actions_route)
278 .ruma_route(&client::delete_pushrule_route)
279 .ruma_route(&client::get_pushers_route)
280 .ruma_route(&client::set_pushers_route)
281 .ruma_route(&client::get_notifications_route)
282 .ruma_route(&client::get_capabilities_route)
283}
284
285fn register_client_keys_and_backup_routes(router: Router<State>) -> Router<State> {
286 router
287 .ruma_route(&client::upload_keys_route)
288 .ruma_route(&client::get_keys_route)
289 .ruma_route(&client::claim_keys_route)
290 .ruma_route(&client::upload_signing_keys_route)
291 .ruma_route(&client::upload_signatures_route)
292 .ruma_route(&client::get_key_changes_route)
293 .ruma_route(&client::create_backup_version_route)
294 .ruma_route(&client::update_backup_version_route)
295 .ruma_route(&client::delete_backup_version_route)
296 .ruma_route(&client::get_latest_backup_info_route)
297 .ruma_route(&client::get_backup_info_route)
298 .ruma_route(&client::add_backup_keys_route)
299 .ruma_route(&client::add_backup_keys_for_room_route)
300 .ruma_route(&client::add_backup_keys_for_session_route)
301 .ruma_route(&client::delete_backup_keys_for_room_route)
302 .ruma_route(&client::delete_backup_keys_for_session_route)
303 .ruma_route(&client::delete_backup_keys_route)
304 .ruma_route(&client::get_backup_keys_for_room_route)
305 .ruma_route(&client::get_backup_keys_for_session_route)
306 .ruma_route(&client::get_backup_keys_route)
307}
308
309fn register_client_room_routes(router: Router<State>) -> Router<State> {
310 router
311 .ruma_route(&client::appservice_ping)
312 .ruma_route(&client::set_read_marker_route)
313 .ruma_route(&client::create_receipt_route)
314 .ruma_route(&client::create_typing_event_route)
315 .ruma_route(&client::create_room_route)
316 .ruma_route(&client::redact_event_route)
317 .ruma_route(&client::report_event_route)
318 .ruma_route(&client::report_room_route)
319 .ruma_route(&client::report_user_route)
320 .ruma_route(&client::create_alias_route)
321 .ruma_route(&client::delete_alias_route)
322 .ruma_route(&client::get_alias_route)
323 .ruma_route(&client::join_room_by_id_route)
324 .ruma_route(&client::join_room_by_id_or_alias_route)
325 .ruma_route(&client::joined_members_route)
326 .ruma_route(&client::knock_room_route)
327 .ruma_route(&client::leave_room_route)
328 .ruma_route(&client::forget_room_route)
329 .ruma_route(&client::joined_rooms_route)
330 .ruma_route(&client::kick_user_route)
331 .ruma_route(&client::ban_user_route)
332 .ruma_route(&client::unban_user_route)
333 .ruma_route(&client::invite_user_route)
334 .ruma_route(&client::set_room_visibility_route)
335 .ruma_route(&client::get_room_visibility_route)
336 .ruma_route(&client::get_public_rooms_route)
337 .ruma_route(&client::get_public_rooms_filtered_route)
338 .ruma_route(&client::search_users_route)
339 .ruma_route(&client::get_member_events_route)
340 .ruma_route(&client::get_protocols_route)
341 .ruma_route(&client::get_protocol_route)
342 .ruma_route(&client::get_user_for_protocol_route)
343 .ruma_route(&client::get_location_for_protocol_route)
344 .ruma_route(&client::get_user_for_user_id_route)
345 .ruma_route(&client::get_location_for_room_alias_route)
346 .ruma_route(&client::upgrade_room_route)
347 .ruma_route(&client::get_mutual_rooms_route)
348 .ruma_route(&client::get_room_summary)
349 .route(
350 "/_matrix/client/unstable/im.nheko.summary/rooms/{room_id_or_alias}/summary",
351 get(client::get_room_summary_legacy),
352 )
353 .ruma_route(&client::room_initial_sync_route)
354 .ruma_route(&client::get_room_event_route)
355 .ruma_route(&client::get_room_aliases_route)
356}
357
358fn register_client_state_and_sync_routes(router: Router<State>) -> Router<State> {
359 router
360 .ruma_route(&client::send_message_event_route)
361 .ruma_route(&client::send_state_event_for_key_route)
362 .ruma_route(&client::get_state_events_route)
363 .ruma_route(&client::get_state_events_for_key_route)
364 .route(
368 "/_matrix/client/r0/rooms/{room_id}/state/{event_type}",
369 get(client::get_state_events_for_empty_key_route)
370 .put(client::send_state_event_for_empty_key_route),
371 )
372 .route(
373 "/_matrix/client/v3/rooms/{room_id}/state/{event_type}",
374 get(client::get_state_events_for_empty_key_route)
375 .put(client::send_state_event_for_empty_key_route),
376 )
377 .route(
379 "/_matrix/client/r0/rooms/{room_id}/state/{event_type}/",
380 get(client::get_state_events_for_empty_key_route)
381 .put(client::send_state_event_for_empty_key_route),
382 )
383 .route(
384 "/_matrix/client/v3/rooms/{room_id}/state/{event_type}/",
385 get(client::get_state_events_for_empty_key_route)
386 .put(client::send_state_event_for_empty_key_route),
387 )
388 .ruma_route(&client::events_route)
389 .ruma_route(&client::sync_events_route)
390 .ruma_route(&client::sync_events_v5_route)
391 .ruma_route(&client::get_context_route)
392 .ruma_route(&client::get_event_by_timestamp_route)
393 .ruma_route(&client::get_message_events_route)
394 .ruma_route(&client::search_events_route)
395 .ruma_route(&client::get_threads_route)
396 .ruma_route(&client::get_relating_events_with_rel_type_and_event_type_route)
397 .ruma_route(&client::get_relating_events_with_rel_type_route)
398 .ruma_route(&client::get_relating_events_route)
399 .ruma_route(&client::get_hierarchy_route)
400}
401
402fn register_client_media_and_device_routes(
403 router: Router<State>,
404 media_deny_framing: bool,
405 media_deny_inline_styles: bool,
406) -> Router<State> {
407 let media_content_router = Router::new()
408 .ruma_route(&client::get_content_thumbnail_route)
409 .ruma_route(&client::get_content_route)
410 .ruma_route(&client::get_content_as_filename_route);
411
412 let media_content_router =
413 media_content_headers(media_content_router, media_deny_framing, media_deny_inline_styles);
414
415 router
416 .ruma_route(&client::create_content_route)
417 .ruma_route(&client::create_mxc_uri_route)
418 .ruma_route(&client::create_content_async_route)
419 .ruma_route(&client::get_media_preview_route)
420 .ruma_route(&client::get_media_config_route)
421 .ruma_route(&client::get_devices_route)
422 .ruma_route(&client::get_device_route)
423 .ruma_route(&client::update_device_route)
424 .ruma_route(&client::delete_device_route)
425 .ruma_route(&client::delete_devices_route)
426 .ruma_route(&client::put_dehydrated_device_route)
427 .ruma_route(&client::delete_dehydrated_device_route)
428 .ruma_route(&client::get_dehydrated_device_route)
429 .ruma_route(&client::get_dehydrated_events_route)
430 .ruma_route(&client::send_event_to_device_route)
431 .merge(media_content_router)
432}
433
434fn register_client_misc_routes(router: Router<State>) -> Router<State> {
435 router
436 .ruma_route(&client::turn_server_route)
437 .ruma_route(&client::get_transports_route)
438 .ruma_route(&client::well_known_support)
439 .ruma_route(&client::well_known_client)
440 .ruma_route(&client::tuwunel_remote_version)
441 .route("/_tuwunel/server_version", get(client::tuwunel_server_version))
442 .route(
443 "/_tuwunel/3pid/email/validate",
444 get(client::get_email_validate_route).post(client::post_email_validate_route),
445 )
446}
447
448fn register_oidc_routes(router: Router<State>) -> Router<State> {
449 router
451 .route("/_tuwunel/oidc/registration", post(oidc::registration_route))
452 .route("/_tuwunel/oidc/authorize", get(oidc::authorize_route))
453 .route("/_tuwunel/oidc/_complete", get(oidc_complete).post(oidc_post_complete))
454 .route(
455 "/_tuwunel/oidc/native",
456 get(oidc::native_get_route).post(oidc::native_submit_route),
457 )
458 .route("/_tuwunel/oidc/token", post(oidc::token_route))
459 .route("/_tuwunel/oidc/device_authorization", post(oidc::device_authorization_route))
460 .route("/_tuwunel/oidc/device", get(oidc::get_device_route))
461 .route(
462 "/_tuwunel/oidc/device_callback",
463 get(oidc::get_device_callback_route).post(oidc::post_device_callback_route),
464 )
465 .route("/_tuwunel/oidc/revoke", post(oidc::revoke_route))
466 .route("/_tuwunel/oidc/jwks", get(oidc::jwks_route))
467 .route("/_tuwunel/oidc/userinfo", get(oidc::userinfo_route).post(oidc::userinfo_route))
468 .route("/_tuwunel/oidc/account.js", get(oidc::account_js_route))
469 .route("/_tuwunel/oidc/account.css", get(oidc::account_css_route))
470 .route(
471 "/_tuwunel/oidc/account_callback",
472 get(oidc::get_account_callback_route).post(oidc::post_account_callback_route),
473 )
474 .route("/_tuwunel/oidc/account", get(oidc::get_account_route))
475 .route("/_matrix/client/v1/auth_issuer", get(oidc::auth_issuer_route))
476 .route("/_matrix/client/v1/auth_metadata", get(oidc::openid_configuration_route))
477 .route(
478 "/_matrix/client/unstable/org.matrix.msc2965/auth_issuer",
479 get(oidc::auth_issuer_route),
480 )
481 .route(
482 "/_matrix/client/unstable/org.matrix.msc2965/auth_metadata",
483 get(oidc::openid_configuration_route),
484 )
485 .route("/.well-known/openid-configuration", get(oidc::openid_configuration_route))
486}
487
488fn register_rendezvous_routes(router: Router<State>) -> Router<State> {
489 let router = router
490 .ruma_route(&client::discover_msc4388_route)
491 .ruma_route(&client::create_msc4388_route)
492 .ruma_route(&client::get_msc4388_route)
493 .ruma_route(&client::put_msc4388_route)
494 .ruma_route(&client::delete_msc4388_route);
495
496 let session_routes = get(client::get_rendezvous_route)
497 .put(client::put_rendezvous_route)
498 .delete(client::delete_rendezvous_route);
499
500 router
501 .route(
502 "/_matrix/client/unstable/org.matrix.msc4108/rendezvous",
503 post(client::create_rendezvous_route),
504 )
505 .route("/_matrix/client/unstable/org.matrix.msc4108/rendezvous/{id}", session_routes)
506}
507
508fn register_server_misc_routes(router: Router<State>) -> Router<State> {
509 router
511 .ruma_route(&server::well_known_server)
512 .ruma_route(&server::get_openid_userinfo_route)
513}
514
515fn register_federation_routes(router: Router<State>, allow_federation: bool) -> Router<State> {
516 if allow_federation {
517 router
518 .ruma_route(&server::get_server_version_route)
519 .route("/_matrix/key/v2/server", get(server::get_server_keys_route))
520 .ruma_route(&server::get_public_rooms_route)
521 .ruma_route(&server::get_public_rooms_filtered_route)
522 .ruma_route(&server::send_transaction_message_route)
523 .ruma_route(&server::get_event_route)
524 .ruma_route(&server::get_event_by_timestamp_route)
525 .ruma_route(&server::get_backfill_route)
526 .ruma_route(&server::get_missing_events_route)
527 .ruma_route(&server::get_event_authorization_route)
528 .ruma_route(&server::get_room_state_route)
529 .ruma_route(&server::get_room_state_ids_route)
530 .ruma_route(&server::create_leave_event_template_route)
531 .ruma_route(&server::create_knock_event_template_route)
532 .ruma_route(&server::create_leave_event_v2_route)
533 .ruma_route(&server::create_knock_event_v1_route)
534 .ruma_route(&server::create_join_event_template_route)
535 .ruma_route(&server::create_join_event_v2_route)
536 .ruma_route(&server::create_invite_route)
537 .ruma_route(&server::get_devices_route)
538 .ruma_route(&server::get_room_information_route)
539 .ruma_route(&server::get_profile_information_route)
540 .ruma_route(&server::get_keys_route)
541 .ruma_route(&server::claim_keys_route)
542 .ruma_route(&server::get_hierarchy_route)
543 .ruma_route(&server::get_content_route)
544 .ruma_route(&server::get_content_thumbnail_route)
545 .route("/_tuwunel/local_user_count", get(client::tuwunel_local_user_count))
546 } else {
547 router
548 .route("/_matrix/federation/{*path}", any(federation_disabled))
549 .route("/_matrix/key/{*path}", any(federation_disabled))
550 .route("/_tuwunel/local_user_count", any(federation_disabled))
551 }
552}
553
554fn register_legacy_media_routes(
555 router: Router<State>,
556 allow_legacy_media: bool,
557 media_deny_framing: bool,
558 media_deny_inline_styles: bool,
559) -> Router<State> {
560 if allow_legacy_media {
561 let media_content_router = Router::new()
562 .route(
563 "/_matrix/media/r0/download/{server_name}/{media_id}",
564 get(client::get_content_legacy_route),
565 )
566 .route(
567 "/_matrix/media/v3/download/{server_name}/{media_id}",
568 get(client::get_content_legacy_route),
569 )
570 .route(
571 "/_matrix/media/r0/download/{server_name}/{media_id}/{filename}",
572 get(client::get_content_as_filename_legacy_route),
573 )
574 .route(
575 "/_matrix/media/v3/download/{server_name}/{media_id}/{filename}",
576 get(client::get_content_as_filename_legacy_route),
577 )
578 .route(
579 "/_matrix/media/r0/thumbnail/{server_name}/{media_id}",
580 get(client::get_content_thumbnail_legacy_route),
581 )
582 .route(
583 "/_matrix/media/v3/thumbnail/{server_name}/{media_id}",
584 get(client::get_content_thumbnail_legacy_route),
585 );
586
587 let media_content_router = media_content_headers(
588 media_content_router,
589 media_deny_framing,
590 media_deny_inline_styles,
591 );
592
593 router
594 .ruma_route(&client::get_media_config_legacy_route)
595 .ruma_route(&client::get_media_preview_legacy_route)
596 .merge(media_content_router)
597 } else {
598 router
599 .route("/_matrix/media/v3/config", any(legacy_media_disabled))
600 .route("/_matrix/media/v3/download/{*path}", any(legacy_media_disabled))
601 .route("/_matrix/media/v3/thumbnail/{*path}", any(legacy_media_disabled))
602 .route("/_matrix/media/v3/preview_url", any(legacy_media_disabled))
603 }
604}
605
606fn media_content_headers(
607 router: Router<State>,
608 deny_framing: bool,
609 deny_inline_styles: bool,
610) -> Router<State> {
611 const MEDIA_CSP: &[&str] = &[
613 "sandbox",
614 "default-src 'none'",
615 "script-src 'none'",
616 "font-src 'none'",
617 "frame-ancestors 'none'",
618 "form-action 'none'",
619 "base-uri 'none'",
620 ];
621
622 const POLICY: &str = join!(MEDIA_CSP, ";");
623 const FRAMING_POLICY: &str = replace!(POLICY, "frame-ancestors 'none';", "");
624 const STYLED_POLICY: &str = concat!(POLICY, ";style-src 'unsafe-inline'");
625 const FRAMING_STYLED_POLICY: &str = concat!(FRAMING_POLICY, ";style-src 'unsafe-inline'");
626
627 let policy = match (deny_framing, deny_inline_styles) {
628 | (false, false) => FRAMING_STYLED_POLICY,
629 | (false, true) => FRAMING_POLICY,
630 | (true, false) => STYLED_POLICY,
631 | (true, true) => POLICY,
632 };
633
634 router.route_layer(SetResponseHeaderLayer::overriding(
635 header::CONTENT_SECURITY_POLICY,
636 HeaderValue::from_static(policy),
637 ))
638}
639
640async fn legacy_media_disabled() -> impl IntoResponse {
641 err!(Request(Forbidden("Unauthenticated media is disabled.")))
642}
643
644async fn federation_disabled() -> impl IntoResponse {
645 err!(Request(Forbidden("Federation is disabled.")))
646}