feat(meta): webinterface is now kinda useful and fancy
cargo devel CI / cargo CI (push) Successful in 1m53s Details

This commit is contained in:
Christoph J. Scherr 2024-09-08 04:08:38 +02:00
parent 14042bc21b
commit fb10ca1464
6 changed files with 65 additions and 168 deletions

View File

@ -122,89 +122,26 @@
<hr class="mb-5"> <hr class="mb-5">
<div class="row g-5 mb-5">
<h2 class="text-body-emphasis">Challenge {{ challenge_idx}} &mdash; {{ challenge_title }}</h2>
<p class="mt-1 mb-3">{{ challenge_description }}</p>
<div class="col mt-1">
<h3>Hints</h3>
<button class="btn btn-primary my-2" type="button" data-bs-toggle="collapse" data-bs-target="#hints"
aria-expanded="false" aria-controls="collapseExample">
Show hints
</button>
<div class="collapse" id="hints">
<ul class="list-unstyled ps-0">
{% for hint in challenge_hints %}
<li>
<p>
<svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" />
</svg>
{{hint}}
</p>
</li>
{% endfor %}
</ul>
</div>
</div>
<div class="col mt-1">
<h3>Solution</h3>
<button class="btn btn-primary my-2" type="button" data-bs-toggle="collapse" data-bs-target="#solution"
aria-expanded="false" aria-controls="collapseExample">
Show solution
</button>
<div class="collapse" id="solution">
<p>
<svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" />
</svg>
{{challenge_solution}}
</p>
</div>
</div>
</div>
<hr class="mb-5">
<div class="row g-5"> <div class="row g-5">
<div class="col-md-6"> <div class="col-md-6">
<h2 class="text-body-emphasis">Contestants</h2> <h2 class="text-body-emphasis">Challenges</h2>
<p> <p>
There are cuttently {{ contestants_amount }} contestants. There are cuttently {{ challenges_amount }} active challenges.
These contestants currently have had at least one connection to
the challenge:
</p> </p>
<ul class="list-unstyled ps-0"> <ul class="list-unstyled ps-0">
{% for contestant in contestants %} {% for challenge in challenges %}
<li> <li>
<a class="icon-link mb-1" href="https://whatismyipaddress.com/ip/{{ contestant.ip }}"> <a class="icon-link mb-1" href="challenge/{{ challenge.id }}">
<svg class="bi" width="16" height="16"> <svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" /> <use xlink:href="#arrow-right-circle" />
</svg> </svg>
{{ contestant.ip }} {{ challenge.id }} &mdash; {{ challenge.title }}
</a> </a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<div class="col-md-6">
<h2 class="text-body-emphasis">Winners</h2>
<p>
There are cuttently {{ winners_amount }} winners. These contestants currently have been sent the secret:
</p>
<ul class="list-unstyled ps-0">
{% for winner in winners %}
<li>
<a class="icon-link mb-1" href="https://whatismyipaddress.com/ip/{{ winner.ip }}">
<svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" />
</svg>
{{ winner.ip }}
</a>
</li>
{% endfor %}
</ul>
</div>
</div> </div>
</main> </main>
<footer class="pt-5 my-5 text-body-secondary border-top"> <footer class="pt-5 my-5 text-body-secondary border-top">

View File

@ -112,12 +112,13 @@
</header> </header>
<main> <main>
<h1 class="text-body-emphasis">{{title}} Admin Interface</h1> <h1 class="text-body-emphasis">{{title}} User Interface</h1>
<p class="fs-5 col-md-8"> <p class="fs-5 col-md-8">
You have reached the {{title}} Admin Interface. This site can be used by You have reached the {{title}} User
the host of the challenge to see the challenge progress, solution, and Interface. This site can be used by the
hints for that challenge. This site is <b>NOT</b> part of the contestants see the challenges and their
challenge. progress and hints for that challenge. This
site is <b>NOT</b> part of the challenge.
</p> </p>
<hr class="mb-5"> <hr class="mb-5">
@ -146,21 +147,6 @@
</ul> </ul>
</div> </div>
</div> </div>
<div class="col mt-1">
<h3>Solution</h3>
<button class="btn btn-primary my-2" type="button" data-bs-toggle="collapse"
data-bs-target="#solution" aria-expanded="false" aria-controls="collapseExample">
Show solution
</button>
<div class="collapse" id="solution">
<p>
<svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" />
</svg>
{{challenge_solution}}
</p>
</div>
</div>
</div> </div>
<hr class="mb-5"> <hr class="mb-5">

View File

@ -114,98 +114,35 @@
<main> <main>
<h1 class="text-body-emphasis">{{title}} Admin Interface</h1> <h1 class="text-body-emphasis">{{title}} Admin Interface</h1>
<p class="fs-5 col-md-8"> <p class="fs-5 col-md-8">
You have reached the {{title}} Admin Interface. This site can be used by You have reached the {{title}} User
the host of the challenge to see the challenge progress, solution, and Interface. This site can be used by the
hints for that challenge. This site is <b>NOT</b> part of the contestants see the challenges and their
challenge. progress and hints for that challenge. This
site is <b>NOT</b> part of the challenge.
</p> </p>
<hr class="mb-5"> <hr class="mb-5">
<div class="row g-5 mb-5">
<h2 class="text-body-emphasis">Challenge {{ challenge_idx}} &mdash; {{ challenge_title }}</h2>
<p class="mt-1 mb-3">{{ challenge_description }}</p>
<div class="col mt-1">
<h3>Hints</h3>
<button class="btn btn-primary my-2" type="button" data-bs-toggle="collapse" data-bs-target="#hints"
aria-expanded="false" aria-controls="collapseExample">
Show hints
</button>
<div class="collapse" id="hints">
<ul class="list-unstyled ps-0">
{% for hint in challenge_hints %}
<li>
<p>
<svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" />
</svg>
{{hint}}
</p>
</li>
{% endfor %}
</ul>
</div>
</div>
<div class="col mt-1">
<h3>Solution</h3>
<button class="btn btn-primary my-2" type="button" data-bs-toggle="collapse"
data-bs-target="#solution" aria-expanded="false" aria-controls="collapseExample">
Show solution
</button>
<div class="collapse" id="solution">
<p>
<svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" />
</svg>
{{challenge_solution}}
</p>
</div>
</div>
</div>
<hr class="mb-5">
<div class="row g-5"> <div class="row g-5">
<div class="col-md-6"> <div class="col-md-6">
<h2 class="text-body-emphasis">Contestants</h2> <h2 class="text-body-emphasis">Challenges</h2>
<p> <p>
There are cuttently {{ contestants_amount }} contestants. There are cuttently {{ challenges_amount }} active challenges.
These contestants currently have had at least one connection to
the challenge:
</p> </p>
<ul class="list-unstyled ps-0"> <ul class="list-unstyled ps-0">
{% for contestant in contestants %} {% for challenge in challenges %}
<li> <li>
<a class="icon-link mb-1" href="https://whatismyipaddress.com/ip/{{ contestant.ip }}"> <a class="icon-link mb-1" href="challenge/{{ challenge.id }}">
<svg class="bi" width="16" height="16"> <svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" /> <use xlink:href="#arrow-right-circle" />
</svg> </svg>
{{ contestant.ip }} {{ challenge.id }} &mdash; {{ challenge.title }}
</a> </a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<div class="col-md-6">
<h2 class="text-body-emphasis">Winners</h2>
<p>
There are cuttently {{ winners_amount }} winners. These contestants currently have been sent the
secret:
</p>
<ul class="list-unstyled ps-0">
{% for winner in winners %}
<li>
<a class="icon-link mb-1" href="https://whatismyipaddress.com/ip/{{ winner.ip }}">
<svg class="bi" width="16" height="16">
<use xlink:href="#arrow-right-circle" />
</svg>
{{ winner.ip }}
</a>
</li>
{% endfor %}
</ul>
</div>
</div> </div>
</main> </main>
<footer class="pt-5 my-5 text-body-secondary border-top"> <footer class="pt-5 my-5 text-body-secondary border-top">

View File

@ -5,6 +5,7 @@
use async_trait::async_trait; use async_trait::async_trait;
use libpt::log::{error, info}; use libpt::log::{error, info};
use serde::{Deserialize, Serialize};
use crate::config::Config; use crate::config::Config;
use crate::vault::VaultRef; use crate::vault::VaultRef;
@ -13,7 +14,7 @@ pub mod c1;
pub mod c2; pub mod c2;
pub mod c3; pub mod c3;
#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub struct ChallengeDesc { pub struct ChallengeDesc {
id: usize, id: usize,
title: String, title: String,

View File

@ -26,7 +26,7 @@ impl<'tp> Service<'tp> {
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone + 'tp { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone + 'tp {
let serv = this.clone(); let serv = this.clone();
warp::path!("admin" / "challenge" / usize) warp::path!("admin" / "challenge" / usize)
.map(move |id: usize| serv.challenges[id + 1].clone()) .map(move |id: usize| serv.challenges[id - 1].clone())
.and(with_serv(this.clone())) .and(with_serv(this.clone()))
.and_then(details) .and_then(details)
.with(warp::trace(|info| { .with(warp::trace(|info| {
@ -51,7 +51,7 @@ async fn details(
let winners = vault.winners().await.into_iter().collect::<Vec<_>>(); let winners = vault.winners().await.into_iter().collect::<Vec<_>>();
let r = Response::new( let r = Response::new(
serv.env serv.env
.get_template("admin:index") .get_template("admin:details")
.map_err(TemplateError::from)? .map_err(TemplateError::from)?
.render(context!( .render(context!(
title => "Wooly-Vault", title => "Wooly-Vault",
@ -77,6 +77,24 @@ async fn details(
} }
async fn index(serv: Arc<Service<'_>>) -> Result<Box<dyn warp::Reply>, warp::Rejection> { async fn index(serv: Arc<Service<'_>>) -> Result<Box<dyn warp::Reply>, warp::Rejection> {
let r = Response::new("todo".into()); let challenges = serv
.challenges
.iter()
.map(|v| v.0.to_owned())
.collect::<Vec<_>>();
let r = Response::new(
serv.env
.get_template("admin:index")
.map_err(TemplateError::from)?
.render(context!(
title => "Wooly-Vault",
author => env!("CARGO_PKG_AUTHORS"),
year => "2024",
challenges => challenges,
challenges_amount => challenges.len(),
))
.map_err(TemplateError::from)?
.into(),
);
Ok(Box::new(r)) Ok(Box::new(r))
} }

View File

@ -26,7 +26,7 @@ impl<'tp> Service<'tp> {
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone + 'tp { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone + 'tp {
let serv = this.clone(); let serv = this.clone();
warp::path!("challenge" / usize) warp::path!("challenge" / usize)
.map(move |id: usize| serv.challenges[id + 1].clone()) .map(move |id: usize| serv.challenges[id - 1].clone())
.and(with_serv(this.clone())) .and(with_serv(this.clone()))
.and_then(details) .and_then(details)
.with(warp::trace(|info| { .with(warp::trace(|info| {
@ -51,7 +51,7 @@ async fn details(
let winners = vault.winners().await.into_iter().collect::<Vec<_>>(); let winners = vault.winners().await.into_iter().collect::<Vec<_>>();
let r = Response::new( let r = Response::new(
serv.env serv.env
.get_template("index") .get_template("details")
.map_err(TemplateError::from)? .map_err(TemplateError::from)?
.render(context!( .render(context!(
title => "Wooly-Vault", title => "Wooly-Vault",
@ -77,6 +77,24 @@ async fn details(
} }
async fn index(serv: Arc<Service<'_>>) -> Result<Box<dyn warp::Reply>, warp::Rejection> { async fn index(serv: Arc<Service<'_>>) -> Result<Box<dyn warp::Reply>, warp::Rejection> {
let r = Response::new("todo".into()); let challenges = serv
.challenges
.iter()
.map(|v| v.0.to_owned())
.collect::<Vec<_>>();
let r = Response::new(
serv.env
.get_template("admin:index")
.map_err(TemplateError::from)?
.render(context!(
title => "Wooly-Vault",
author => env!("CARGO_PKG_AUTHORS"),
year => "2024",
challenges => challenges,
challenges_amount => challenges.len(),
))
.map_err(TemplateError::from)?
.into(),
);
Ok(Box::new(r)) Ok(Box::new(r))
} }