use crate::api::{handle_get, handle_patch, handle_post, userinfo}; use crate::config::load_config; use crate::middleware::AppState; use crate::repository::RedisRepository; use crate::util::initialize_logging; use axum::routing::{get, patch, post}; use axum::{Extension, Router}; use axum_keycloak_auth::instance::{KeycloakAuthInstance, KeycloakConfig}; use axum_keycloak_auth::layer::KeycloakAuthLayer; use axum_keycloak_auth::{PassthroughMode, Url}; use log::info; use std::sync::Arc; mod api; mod auth; mod config; mod gsd; mod middleware; mod repository; mod util; mod model; #[tokio::main] async fn main() -> Result<(), Box> { let config = load_config()?; initialize_logging(&config); info!("Redirect URI: {}", config.keycloak.redirect_url); info!("Logging initialized"); info!("Starting Holzleitner Delivery Backend"); let redis_url = config.redis_url.clone(); let host_url = config.get_host_url().clone(); info!("Initializing redis server"); let state = Arc::new(AppState { config: config.clone(), repository: RedisRepository::try_new(redis_url).await?, gsd_service: (&config).into(), oauth_client: auth::create_oauth_client(&config), frontend_url: config.frontend_url.clone(), }); info!("Starting axum server"); let keycloak_instance: Arc = Arc::new(KeycloakAuthInstance::new( KeycloakConfig::builder() .server(Url::parse(config.keycloak.base_url.as_str()).unwrap()) .realm(config.keycloak.realm) .build(), )); let auth_router = auth::router(state.clone()); let proxy_router = Router::new() .route("/{*wildcard}", post(handle_post)) .route("/{*wildcard}", get(handle_get)) .route("/{*wildcard}", patch(handle_patch)) .route("/userinfo", get(userinfo)) .route_layer(Extension(state.clone())) .route_layer(axum::middleware::from_fn_with_state( state.clone(), middleware::gsd_decorate_header, )) .route_layer( KeycloakAuthLayer::::builder() .instance(keycloak_instance.clone()) .passthrough_mode(PassthroughMode::Block) .persist_raw_claims(false) .expected_audiences(vec![String::from("account")]) //.required_roles(vec![]) .build(), ) .route_layer(axum::middleware::from_fn_with_state( state.clone(), middleware::session_auth_middleware, )) .with_state(state); let app = Router::new().merge(proxy_router).merge(auth_router); info!("Listening on {}", host_url); let listener = tokio::net::TcpListener::bind(host_url.clone()) .await .unwrap(); axum::serve(listener, app).await.unwrap(); Ok(()) }