From e06094f23ca861ea5ae4864d11fa8ce8b7d7aa2c Mon Sep 17 00:00:00 2001 From: rtkay123 Date: Mon, 2 Feb 2026 13:05:49 +0200 Subject: feat: oauth route --- src/server/mod.rs | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 5 deletions(-) (limited to 'src/server/mod.rs') diff --git a/src/server/mod.rs b/src/server/mod.rs index 803135f..3301035 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,10 +1,125 @@ -use axum::Router; - -use crate::{config::Config, server::state::AppState}; - +pub mod driver; +pub mod error; +mod middleware; +pub mod routes; pub mod shutdown; pub mod state; +use std::time::Duration; + +use activitypub_federation::config::{FederationConfig, FederationMiddleware}; +use axum::{ + Router, + http::{HeaderName, StatusCode}, +}; +use tower_http::{ + cors::{self, CorsLayer}, + request_id::PropagateRequestIdLayer, + timeout::TimeoutLayer, + trace::TraceLayer, +}; +use tracing::{error, info_span}; +use utoipa::OpenApi; +use utoipa_axum::router::OpenApiRouter; + +use crate::{ + config::Config, + server::{ + middleware::request_id::{REQUEST_ID_HEADER, add_request_id}, + routes::auth::OAuthDoc, + state::{AppState, federation}, + }, +}; + +#[derive(OpenApi)] +#[openapi( + tags( + (name = routes::HEALTH, description = "Check API health"), + ), +)] +pub struct ApiDoc; + pub async fn router(config: &Config, state: AppState) -> anyhow::Result> { - todo!() + let state = federation::add_federation(state, config).await?; + + let mut doc = ApiDoc::openapi(); + doc.merge(OAuthDoc::openapi()); + + let (router, _api) = OpenApiRouter::with_openapi(doc) + .routes(utoipa_axum::routes!(routes::health_check)) + .routes(utoipa_axum::routes!(routes::auth::auth)) + .split_for_parts(); + + #[cfg(feature = "swagger")] + let router = router.merge( + utoipa_swagger_ui::SwaggerUi::new("/swagger-ui") + .url("/api-docs/swaggerdoc.json", _api.clone()), + ); + + #[cfg(feature = "redoc")] + let router = { + use utoipa_redoc::Servable as _; + router.merge(utoipa_redoc::Redoc::with_url("/redoc", _api.clone())) + }; + + #[cfg(feature = "scalar")] + let router = { + use utoipa_scalar::Servable as _; + router.merge(utoipa_scalar::Scalar::with_url("/scalar", _api.clone())) + }; + + #[cfg(feature = "rapidoc")] + let router = router.merge( + utoipa_rapidoc::RapiDoc::with_openapi("/api-docs/rapidoc.json", _api).path("/rapidoc"), + ); + + let router = router + .layer( + TraceLayer::new_for_http().make_span_with(|request: &axum::http::Request<_>| { + if let Some(request_id) = request.headers().get(REQUEST_ID_HEADER) { + info_span!( + "http_request", + request_id = ?request_id, + ) + } else { + error!("could not extract request_id"); + info_span!("http_request") + } + }), + ) + .layer(TimeoutLayer::with_status_code( + StatusCode::REQUEST_TIMEOUT, + Duration::from_secs(config.server.request_timeout), + )) + .layer(FederationMiddleware::new(state)) + // send headers from request to response headers + .layer(PropagateRequestIdLayer::new(HeaderName::from_static( + REQUEST_ID_HEADER, + ))) + .layer(axum::middleware::from_fn(add_request_id)) + .layer( + CorsLayer::new() + .allow_origin(cors::Any) + .allow_headers(cors::Any) + .allow_methods(cors::Any), + ); + + Ok(router) +} + +#[cfg(test)] +pub mod bootstrap { + use async_trait::async_trait; + + use crate::server::driver::SellershutDriver; + + #[derive(Debug, Default)] + pub struct TestDriver {} + + #[async_trait] + impl SellershutDriver for TestDriver { + async fn hello(&self) { + todo!() + } + } } -- cgit v1.2.3