use std::sync::Arc; use anyhow::Result; use libpt::log::tracing; use minijinja::context; use warp::reject::Rejection; use warp::reply::Reply; use warp::reply::Response; use warp::Filter; use crate::challenge::ChallengeDesc; use crate::vault::VaultRef; use super::errors::TemplateError; use super::Service; fn with_serv( serv: Arc, ) -> impl Filter,), Error = std::convert::Infallible> + Clone { warp::any().map(move || serv.clone()) } impl<'tp> Service<'tp> { pub fn admin_routes( this: Arc, ) -> impl Filter + Clone + 'tp { let serv = this.clone(); warp::path!("admin" / "challenge" / usize) .map(move |id: usize| serv.challenges[id - 1].clone()) .and(with_serv(this.clone())) .and_then(details) .with(warp::trace(|info| { // Create a span using tracing macros tracing::info_span!( "admin", method = %info.method(), path = %info.path(), ) })) .or(warp::path!("admin").and(with_serv(this.clone()).and_then(index))) } } async fn details( data: (ChallengeDesc, VaultRef), serv: Arc>, ) -> Result, warp::Rejection> { let challenge = data.0; let vault = data.1; let contestants = vault.contestants().await.into_iter().collect::>(); let winners = vault.winners().await.into_iter().collect::>(); let r = Response::new( serv.env .get_template("admin:details") .map_err(TemplateError::from)? .render(context!( title => "Wooly-Vault Admin Interface", author => env!("CARGO_PKG_AUTHORS"), year => "2024", challenge_idx => challenge.id(), challenge_title => challenge.title(), challenge_description => challenge.description(), challenge_hints => challenge.hints(), challenge_solution => challenge.solution(), contestants => vault.contestants().await.iter().collect::>(), winners => vault.winners().await.iter().collect::>(), contestants => contestants, winners => winners, contestants_amount => contestants.len(), winners_amount => winners.len(), )) .map_err(TemplateError::from)? .into(), ); Ok(Box::new(r)) } async fn index(serv: Arc>) -> Result, warp::Rejection> { let challenges = serv .challenges .iter() .map(|v| v.0.to_owned()) .collect::>(); let r = Response::new( serv.env .get_template("admin:index") .map_err(TemplateError::from)? .render(context!( title => "Wooly-Vault Admin Interface", author => env!("CARGO_PKG_AUTHORS"), year => "2024", challenges => challenges, challenges_amount => challenges.len(), )) .map_err(TemplateError::from)? .into(), ); Ok(Box::new(r)) }