routes.rs
101 lignes · 3987 octets
//! Default federation UI router. //! //! Mounts every public, authenticated and admin endpoint shipped by //! this crate. Mirrors the previous `cfg(feature = "fediverse")` blocks //! that lived in `rustwarden-ui` so wiring stays a one-liner: //! `builder.merge_routes(rustwarden_fediverse_ui::default_routes())`. use axum::Router; use axum::extract::DefaultBodyLimit; use axum::routing::{get, post}; use sea_orm::DatabaseConnection; use tower::limit::ConcurrencyLimitLayer; use crate::handlers::{admin, user_auth}; /// Maximum concurrent SSE connections to `/login/fediverse/sse/{id}` /// (ANSSI FUI-DOS-1). The endpoint is unauthenticated and holds a DB /// connection for up to 5 minutes per challenge — capping concurrency /// prevents pool exhaustion by a single attacker. const SSE_MAX_CONCURRENT: usize = 100; /// Maximum body size accepted on `POST /login/fediverse` (ANSSI /// FUI-NET-1). 8 KiB is far above any legitimate login form payload /// (handle field ~100 bytes + CSRF token ~64 bytes + a few hidden /// inputs) and bounds the DoS surface on this unauthenticated route. const LOGIN_FORM_BODY_LIMIT_BYTES: usize = 8 * 1024; /// Returns the default federation UI routes (public, authenticated and /// admin) wired against `DatabaseConnection` state. pub fn default_routes() -> Router<DatabaseConnection> { Router::new() // Federation admin hub (entry point for the six sub-sections). .route("/admin/fediverse", get(admin::get_hub)) .route("/admin/fediverse/teams", get(admin::get_teams_for_invites)) // Public routes (RFC 0023 Slice B). .route("/login/fediverse/error", get(user_auth::error)) .route( "/login/fediverse", get(user_auth::login_form) .post(user_auth::login_initiate) .layer(DefaultBodyLimit::max(LOGIN_FORM_BODY_LIMIT_BYTES)), ) .route( "/login/fediverse/waiting/{challenge_id}", get(user_auth::waiting), ) .route( "/login/fediverse/sse/{challenge_id}", get(user_auth::sse_status).layer(ConcurrencyLimitLayer::new(SSE_MAX_CONCURRENT)), ) // Authenticated routes (consent, invite, connected apps). .route( "/fediverse/consent/{challenge_id}", get(user_auth::consent_form).post(user_auth::consent_submit), ) .route("/profile/connected_apps", get(user_auth::connected_apps)) .route( "/fediverse/invite/{invite_id}", get(user_auth::invite_landing_form).post(user_auth::invite_landing_submit), ) // Admin routes (RFC 0021 Slice A). .route( "/admin/fediverse/settings", get(admin::get_settings).post(admin::update_settings), ) .route("/admin/fediverse/trust_list", get(admin::get_trust_list)) .route( "/admin/fediverse/trust_list/add", post(admin::add_trust_entry), ) .route( "/admin/fediverse/trust_list/delete", post(admin::delete_trust_entry), ) .route("/admin/fediverse/queue", get(admin::get_queue)) .route( "/admin/fediverse/sessions_remote", get(admin::get_sessions_remote), ) .route( "/admin/fediverse/sessions_remote/revoke", post(admin::revoke_remote_session), ) .route( "/admin/fediverse/sessions_remote/kill_domain", post(admin::kill_domain), ) .route("/admin/fediverse/nodeinfo", get(admin::get_nodeinfo)) .route( "/admin/fediverse/invites/{team_id}", get(admin::get_team_invites), ) .route( "/admin/fediverse/invites/{team_id}/add", post(admin::create_team_invite), ) .route( "/admin/fediverse/invites/{team_id}/revoke", post(admin::revoke_team_invite), ) }
GitRust