use std::time::{ Duration, Instant, }; use askama::Template; use axum::response::{ IntoResponse, }; use axum::extract::State; use openidconnect::{ reqwest::async_http_client, TokenIntrospectionResponse, }; use crate::util::askama::HtmlTemplate; use crate::AppState; use crate::error::openid::AuthError; use crate::util::openid::AccessToken; #[derive(Template)] #[template(path = "user_home.html")] struct UserHomeTemplate { active: bool, username: String, duration: Duration, } pub async fn home( State(app_state): State<AppState>, AccessToken(token): AccessToken, ) -> Result<impl IntoResponse, AuthError> { let now = Instant::now(); let response = app_state.oidc_client .introspect(&token)? .request_async(async_http_client) .await .map_err(|e| e.to_string())?; match response.active() { true => { let username = response.username().unwrap().to_string(); Ok(HtmlTemplate(UserHomeTemplate { active: true, username, duration: now.elapsed(), })) }, false => Err(AuthError::TokenNotActive(token)), } }