From 70ceb146bf77e95df716b8aad22aaab326750f3c Mon Sep 17 00:00:00 2001 From: tuxmain Date: Fri, 6 Nov 2020 15:23:17 +0100 Subject: [PATCH] Admin --- Cargo.lock | 1 + Cargo.toml | 1 + src/server.rs | 98 +++++++++++++++++++++++++++++++++++++- src/templates.rs | 10 +++- static/style1.css | 1 + templates/admin.html | 36 ++++++++++++++ templates/admin_login.html | 44 +++++++++++++++++ templates/index.html | 2 + 8 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 templates/admin.html create mode 100644 templates/admin_login.html diff --git a/Cargo.lock b/Cargo.lock index 77bebf5..62f2b94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,6 +434,7 @@ dependencies = [ "sled", "structopt", "tokio", + "urlencoding", "warp", ] diff --git a/Cargo.toml b/Cargo.toml index 502b4d9..850a4e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,5 @@ sha2 = "0.9.1" sled = "0.34.4" structopt = "0.3.20" tokio = { version = "0.2.22", features = ["macros", "rt-threaded"] } +urlencoding = "1.1.1" warp = "0.2.5" diff --git a/src/server.rs b/src/server.rs index 8961357..a1543ef 100644 --- a/src/server.rs +++ b/src/server.rs @@ -9,6 +9,7 @@ use std::{ sync::{Arc, RwLock}, }; use warp::Filter; +use warp::Reply; type PasswordHash = [u8; 32]; @@ -56,10 +57,12 @@ pub async fn start_server( .collect::>(), ))); + let config = Arc::new(config); let dbs = Arc::new(dbs); let handle_index = { let cache_ads = cache_ads.clone(); + let templates = templates.clone(); move |errors: &[ErrorTemplate]| { warp::reply::html( templates @@ -77,6 +80,32 @@ pub async fn start_server( } }; + let handle_admin_login = { + let templates = templates.clone(); + move |errors: &[ErrorTemplate]| { + warp::reply::html( + templates + .hb + .render( + "admin_login.html", + &AdminLoginTemplate { lang: "fr", errors }, + ) + .unwrap_or_else(|e| e.to_string()), + ) + } + }; + + let handle_admin = { + move |errors: &[ErrorTemplate]| { + warp::reply::html( + templates + .hb + .render("admin.html", &AdminTemplate { lang: "fr", errors }) + .unwrap_or_else(|e| e.to_string()), + ) + } + }; + let route_static = warp::path("static") .and(warp::get()) .and(warp::fs::dir(opt.dir.0.join(static_files::STATIC_DIR))); @@ -184,7 +213,57 @@ pub async fn start_server( ), )); - warp::serve(route_static.or(route_index)) + let route_admin = warp::path("admin").and( + warp::path::end() + .and( + warp::cookie("admin") + .map({ + let handle_admin = handle_admin.clone(); + let handle_admin_login = handle_admin_login.clone(); + let config = config.clone(); + move |psw: String| { + if !config.admin_passwords.contains(&psw) { + handle_admin_login(&[ErrorTemplate { + text: "Mot de passe administrateur invalide", + }]) + } else { + handle_admin(&[]) + } + } + }) + .or(warp::path::end().map({ + let handle_admin_login = handle_admin_login.clone(); + move || handle_admin_login(&[]) + })), + ) + .or(warp::path("login").and(warp::path::end()).and( + warp::post() + .and(warp::get().map(move || handle_admin(&[]))) + .or(warp::body::form::().map({ + let config = config.clone(); + move |query: AdminLoginQuery| { + if config.admin_passwords.contains(&query.psw) { + warp::reply::with_header( + warp::redirect(warp::http::Uri::from_static("/admin")), + "Set-Cookie", + format!("admin={}; HttpOnly", urlencoding::encode(&query.psw)), + ) + .into_response() + } else { + handle_admin_login(&[ErrorTemplate { + text: "Mot de passe administrateur invalide", + }]) + .into_response() + } + } + })), + )) + .or(warp::path("logout") + .and(warp::path::end()) + .map(|| warp::redirect(warp::http::Uri::from_static("/")))), + ); + + warp::serve(route_static.or(route_index).or(route_admin)) .run(config.listen) .await; } @@ -196,6 +275,18 @@ struct IndexTemplate<'a> { ads: &'a Json, } +#[derive(Serialize)] +struct AdminLoginTemplate<'a> { + lang: &'a str, + errors: &'a [ErrorTemplate<'a>], +} + +#[derive(Serialize)] +struct AdminTemplate<'a> { + lang: &'a str, + errors: &'a [ErrorTemplate<'a>], +} + #[derive(Serialize)] struct ErrorTemplate<'a> { text: &'a str, @@ -217,6 +308,11 @@ struct RmAdQuery { psw: String, } +#[derive(Clone, Debug, Deserialize)] +struct AdminLoginQuery { + psw: String, +} + #[derive(Clone, Debug, Deserialize)] #[serde(tag = "a")] enum Query { diff --git a/src/templates.rs b/src/templates.rs index 7c6eae0..6ca18ae 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -2,8 +2,14 @@ use handlebars::Handlebars; use std::path::Path; const TEMPLATES_DIR: &'static str = "templates"; -static TEMPLATE_FILES: &'static [(&str, &str)] = - &[("index.html", include_str!("../templates/index.html"))]; +static TEMPLATE_FILES: &'static [(&str, &str)] = &[ + ("index.html", include_str!("../templates/index.html")), + ("admin.html", include_str!("../templates/admin.html")), + ( + "admin_login.html", + include_str!("../templates/admin_login.html"), + ), +]; pub struct Templates<'reg> { pub hb: Handlebars<'reg>, diff --git a/static/style1.css b/static/style1.css index 3148854..136261c 100644 --- a/static/style1.css +++ b/static/style1.css @@ -31,6 +31,7 @@ h1, h2, h3, h4 { } #errors { + margin-bottom: 1em; padding: 4px; border: 2px dashed rgba(128, 0, 0, 0.2); border-radius: 3px; diff --git a/templates/admin.html b/templates/admin.html new file mode 100644 index 0000000..e6273a9 --- /dev/null +++ b/templates/admin.html @@ -0,0 +1,36 @@ + + + + + Administration | ĞMarché + + + + +
+ + +

Administration – ĞMarché

+ + {{#if errors}} +
+ Oups, il y a un problème : +
    + {{#each errors}} +
  • {{this.text}}
  • + {{/each}} +
+
+ {{/if}} + +
+ +

Toutes les questions techniques ont leur place sur le forum.

+ +

Code source sous licence GNU AGPL v3. 🦀 Écrit en Rust. Images de Attilax.
+ CopyLeft 2020 Pascal Engélibert

+ +

Accueil

Verrouiller +
+ + diff --git a/templates/admin_login.html b/templates/admin_login.html new file mode 100644 index 0000000..5ec3e2c --- /dev/null +++ b/templates/admin_login.html @@ -0,0 +1,44 @@ + + + + + Administration | ĞMarché + + + + +
+ + +

Administration – ĞMarché

+ +

Authentification

+ + {{#if errors}} +
+ Oups, il y a un problème : +
    + {{#each errors}} +
  • {{this.text}}
  • + {{/each}} +
+
+ {{/if}} + +
+ + + +
+ +
+ +

Toutes les questions techniques ont leur place sur le forum.

+ +

Code source sous licence GNU AGPL v3. 🦀 Écrit en Rust. Images de Attilax.
+ CopyLeft 2020 Pascal Engélibert

+ +

Accueil

+
+ + diff --git a/templates/index.html b/templates/index.html index 1a84448..aa7f10d 100644 --- a/templates/index.html +++ b/templates/index.html @@ -85,6 +85,8 @@

Code source sous licence GNU AGPL v3. 🦀 Écrit en Rust. Images de Attilax.
CopyLeft 2020 Pascal Engélibert

+ +

Administration