From 4714c6b2a77693daad27294aa856e5a32489ba7b Mon Sep 17 00:00:00 2001 From: PlexSheep Date: Sun, 8 Sep 2024 03:57:42 +0200 Subject: [PATCH] feat(meta): separate between user and and admin pages --- data/www/{admin.html => admin/details.html} | 0 data/www/admin/index.html | 220 +++++++++++++++++++ data/www/details.html | 221 ++++++++++++++++++++ data/www/index.html | 221 ++++++++++++++++++++ src/meta/admin.rs | 47 +++-- src/meta/mod.rs | 13 +- src/meta/user.rs | 82 ++++++++ 7 files changed, 787 insertions(+), 17 deletions(-) rename data/www/{admin.html => admin/details.html} (100%) create mode 100644 data/www/admin/index.html create mode 100644 data/www/details.html create mode 100644 data/www/index.html create mode 100644 src/meta/user.rs diff --git a/data/www/admin.html b/data/www/admin/details.html similarity index 100% rename from data/www/admin.html rename to data/www/admin/details.html diff --git a/data/www/admin/index.html b/data/www/admin/index.html new file mode 100644 index 0000000..5292743 --- /dev/null +++ b/data/www/admin/index.html @@ -0,0 +1,220 @@ + + + + + + + + + + {{title}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bootstrap + + + + + + + + + +
+
+ + + + + {{title}} + +
+ +
+

{{title}} Admin Interface

+

+ You have reached the {{title}} Admin Interface. This site can be used by + the host of the challenge to see the challenge progress, solution, and + hints for that challenge. This site is NOT part of the + challenge. +

+ +
+ +
+

Challenge {{ challenge_idx}} — {{ challenge_title }}

+

{{ challenge_description }}

+
+

Hints

+ +
+
    + {% for hint in challenge_hints %} +
  • +

    + + + + {{hint}} +

    +
  • + {% endfor %} +
+
+
+
+

Solution

+ +
+

+ + + + {{challenge_solution}} +

+
+
+
+ +
+ +
+
+

Contestants

+

+ There are cuttently {{ contestants_amount }} contestants. + These contestants currently have had at least one connection to + the challenge: +

+ +
+ +
+

Winners

+

+ There are cuttently {{ winners_amount }} winners. These contestants currently have been sent the secret: +

+ +
+
+
+
+ Created by {{ author }} © {{year}} +
+
+ + + + + diff --git a/data/www/details.html b/data/www/details.html new file mode 100644 index 0000000..7c45c16 --- /dev/null +++ b/data/www/details.html @@ -0,0 +1,221 @@ + + + + + + + + + + {{title}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bootstrap + + + + + + + + + +
+
+ + + + + {{title}} + +
+ +
+

{{title}} Admin Interface

+

+ You have reached the {{title}} Admin Interface. This site can be used by + the host of the challenge to see the challenge progress, solution, and + hints for that challenge. This site is NOT part of the + challenge. +

+ +
+ +
+

Challenge {{ challenge_idx}} — {{ challenge_title }}

+

{{ challenge_description }}

+
+

Hints

+ +
+
    + {% for hint in challenge_hints %} +
  • +

    + + + + {{hint}} +

    +
  • + {% endfor %} +
+
+
+
+

Solution

+ +
+

+ + + + {{challenge_solution}} +

+
+
+
+ +
+ +
+
+

Contestants

+

+ There are cuttently {{ contestants_amount }} contestants. + These contestants currently have had at least one connection to + the challenge: +

+ +
+ +
+

Winners

+

+ There are cuttently {{ winners_amount }} winners. These contestants currently have been sent the + secret: +

+ +
+
+
+
+ Created by {{ author }} © {{year}} +
+
+ + + + + diff --git a/data/www/index.html b/data/www/index.html new file mode 100644 index 0000000..7c45c16 --- /dev/null +++ b/data/www/index.html @@ -0,0 +1,221 @@ + + + + + + + + + + {{title}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bootstrap + + + + + + + + + +
+
+ + + + + {{title}} + +
+ +
+

{{title}} Admin Interface

+

+ You have reached the {{title}} Admin Interface. This site can be used by + the host of the challenge to see the challenge progress, solution, and + hints for that challenge. This site is NOT part of the + challenge. +

+ +
+ +
+

Challenge {{ challenge_idx}} — {{ challenge_title }}

+

{{ challenge_description }}

+
+

Hints

+ +
+
    + {% for hint in challenge_hints %} +
  • +

    + + + + {{hint}} +

    +
  • + {% endfor %} +
+
+
+
+

Solution

+ +
+

+ + + + {{challenge_solution}} +

+
+
+
+ +
+ +
+
+

Contestants

+

+ There are cuttently {{ contestants_amount }} contestants. + These contestants currently have had at least one connection to + the challenge: +

+ +
+ +
+

Winners

+

+ There are cuttently {{ winners_amount }} winners. These contestants currently have been sent the + secret: +

+ +
+
+
+
+ Created by {{ author }} © {{year}} +
+
+ + + + + diff --git a/src/meta/admin.rs b/src/meta/admin.rs index f8b6a21..5badfe5 100644 --- a/src/meta/admin.rs +++ b/src/meta/admin.rs @@ -8,17 +8,27 @@ 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::end() - .map(move || serv.clone()) - .and_then(overview) + 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!( @@ -27,33 +37,33 @@ impl<'tp> Service<'tp> { path = %info.path(), ) })) + .or(warp::path!("admin").and(with_serv(this.clone()).and_then(index))) } } -async fn overview(serv: Arc>) -> Result, warp::Rejection> { - let challenge = serv.challenges[0].clone(); - let contestants = serv - .vault - .contestants() - .await - .into_iter() - .collect::>(); - let winners = serv.vault.winners().await.into_iter().collect::>(); +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("index") + .get_template("admin:index") .map_err(TemplateError::from)? .render(context!( title => "Wooly-Vault", author => env!("CARGO_PKG_AUTHORS"), year => "2024", - challenge_idx => serv.config.challenge, + challenge_idx => challenge.id(), challenge_title => challenge.title(), challenge_description => challenge.description(), challenge_hints => challenge.hints(), challenge_solution => challenge.solution(), - contestants => serv.vault.contestants().await.iter().collect::>(), - winners => serv.vault.winners().await.iter().collect::>(), + contestants => vault.contestants().await.iter().collect::>(), + winners => vault.winners().await.iter().collect::>(), contestants => contestants, winners => winners, contestants_amount => contestants.len(), @@ -65,3 +75,8 @@ async fn overview(serv: Arc>) -> Result, warp:: Ok(Box::new(r)) } + +async fn index(serv: Arc>) -> Result, warp::Rejection> { + let r = Response::new("todo".into()); + Ok(Box::new(r)) +} diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 69f00c3..97e5c83 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -18,6 +18,7 @@ use self::errors::handle_rejection; pub mod admin; pub mod errors; +pub mod user; #[derive(Clone)] pub struct Service<'tp> { @@ -28,7 +29,16 @@ pub struct Service<'tp> { impl<'tp> Service<'tp> { fn build(config: Config, challenges: Vec<(ChallengeDesc, VaultRef)>) -> Result> { let mut env = Environment::new(); - env.add_template("index", include_str!("../../data/www/admin.html"))?; + env.add_template( + "admin:index", + include_str!("../../data/www/admin/index.html"), + )?; + env.add_template( + "admin:details", + include_str!("../../data/www/admin/details.html"), + )?; + env.add_template("index", include_str!("../../data/www/index.html"))?; + env.add_template("details", include_str!("../../data/www/details.html"))?; Ok(Self { config, env, @@ -43,6 +53,7 @@ pub async fn serve(challenges: Vec<(ChallengeDesc, VaultRef)>, config: Config) - let routes = Service::admin_routes(service.clone()) .or(Service::ressources_routes()) + .or(Service::user_routes(service.clone())) .recover(handle_rejection) .with(warp::trace(|info| { // Create a span using tracing macros diff --git a/src/meta/user.rs b/src/meta/user.rs new file mode 100644 index 0000000..19143b4 --- /dev/null +++ b/src/meta/user.rs @@ -0,0 +1,82 @@ +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 user_routes( + this: Arc, + ) -> impl Filter + Clone + 'tp { + let serv = this.clone(); + warp::path!("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::end().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("index") + .map_err(TemplateError::from)? + .render(context!( + title => "Wooly-Vault", + 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 r = Response::new("todo".into()); + Ok(Box::new(r)) +}