use std::sync::Arc;
use axum::{Json, Router, extract::State, http::Method, routing::get};
use http::header::AUTHORIZATION;
use openidconnect::{ClientId, ClientSecret, IssuerUrl};
use pib_service_api_types::config::api::ApiConfig;
use serde::{Deserialize, Serialize};
use tower_http::{
auth::AsyncRequireAuthorizationLayer,
cors::{AllowOrigin, CorsLayer},
};
use crate::{OidcAuth, ServiceState};
mod body;
mod me;
pub(super) fn router(service_state: ServiceState) -> Router {
let cors = CorsLayer::new()
.allow_methods([
Method::GET,
Method::POST,
Method::PUT,
Method::DELETE,
Method::PATCH,
])
.allow_headers([AUTHORIZATION])
.allow_origin(AllowOrigin::mirror_request());
let issuer_url = IssuerUrl::new(service_state.oidc.issuer.clone()).unwrap();
let client_id = service_state.oidc.client_id.clone();
let client_secret = service_state.oidc.client_secret.clone();
let inventory_provider = service_state.inventory_provider.clone();
let oidc = OidcAuth::new(
issuer_url,
ClientId::new(client_id),
ClientSecret::new(client_secret),
inventory_provider,
);
let public = Router::new()
.route("/", get(index))
.route("/config", get(config));
let private = Router::new()
.route(
"/me/profile",
get(me::profile::get).patch(me::profile::patch),
)
.route("/body", get(body::get))
.route("/body/{body_id}", get(body::by_body_id::get))
.route(
"/body/{body_id}/meeting",
get(body::by_body_id::meeting::get).post(body::by_body_id::meeting::post),
)
.route(
"/body/{body_id}/meeting/{meeting_id}",
get(body::by_body_id::meeting::by_meeting_id::get),
)
.layer(AsyncRequireAuthorizationLayer::new(oidc));
Router::new()
.merge(public)
.merge(private)
.layer(cors)
.with_state(Arc::new(service_state))
}
async fn config(State(service_state): State<Arc<ServiceState>>) -> Json<ApiConfig> {
Json(ApiConfig {
oidc: service_state.oidc.clone(),
})
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct Index {}
async fn index() -> Json<Index> {
Json(Index {})
}