diff --git a/README.md b/README.md index a47f137..3af6efb 100644 --- a/README.md +++ b/README.md @@ -20,3 +20,4 @@ L'option `-d ` permet de changer le dossier de données/config (par exemple gmarche -d mon/autre/dossier/ start|init +Pour lancer l'instance dans un sous-dossier de l'URL (i.e. `http://example.tld/gmarche`), changez `root_url` dans la config. La valeur doit toujours commencer et terminer par un `/`. diff --git a/src/config.rs b/src/config.rs index 68ed484..14aee02 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,6 +12,7 @@ pub struct Config { pub cookies_https_only: bool, pub cookies_domain: Option, pub listen: SocketAddr, + pub root_url: String, } impl Default for Config { @@ -21,6 +22,7 @@ impl Default for Config { cookies_https_only: false, cookies_domain: None, listen: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 10353), + root_url: String::from("/"), } } } diff --git a/src/server.rs b/src/server.rs index 7b36142..4ed19b5 100644 --- a/src/server.rs +++ b/src/server.rs @@ -17,25 +17,48 @@ pub async fn start_server( let config = Arc::new(config); let mut app = tide::new(); - app.at("/static") + app.at(&format!("{}static", config.root_url)) .serve_dir(opt.dir.0.join(static_files::STATIC_DIR)) .unwrap(); - app.at("/").get({ + app.at(&config.root_url).get({ + let config = config.clone(); let templates = templates.clone(); let dbs = dbs.clone(); - move |req: tide::Request<()>| serve_index(req, templates.clone(), dbs.clone(), &[], None) + move |req: tide::Request<()>| { + serve_index( + req, + config.clone(), + templates.clone(), + dbs.clone(), + &[], + None, + ) + } }); - app.at("/").post({ + app.at(&config.root_url).post({ + let config = config.clone(); let templates = templates.clone(); let dbs = dbs.clone(); - move |req: tide::Request<()>| handle_post_index(req, templates.clone(), dbs.clone()) + move |req: tide::Request<()>| { + handle_post_index(req, config.clone(), templates.clone(), dbs.clone()) + } }); - app.at("/ad/:ad").get({ + app.at(&format!("{}ad/:ad", config.root_url)).get({ + let config = config.clone(); let templates = templates.clone(); let dbs = dbs.clone(); - move |req: tide::Request<()>| serve_index(req, templates.clone(), dbs.clone(), &[], None) + move |req: tide::Request<()>| { + serve_index( + req, + config.clone(), + templates.clone(), + dbs.clone(), + &[], + None, + ) + } }); - app.at("/admin").get({ + app.at(&format!("{}admin", config.root_url)).get({ let config = config.clone(); let templates = templates.clone(); let dbs = dbs.clone(); @@ -43,18 +66,22 @@ pub async fn start_server( handle_admin(req, config.clone(), templates.clone(), dbs.clone()) } }); - app.at("/admin").post({ + app.at(&format!("{}admin", config.root_url)).post({ let config = config.clone(); move |req: tide::Request<()>| { handle_post_admin(req, config.clone(), templates.clone(), dbs.clone()) } }); - app.at("/admin/logout").get(handle_admin_logout); + app.at(&format!("{}admin/logout", config.root_url)).get({ + let config = config.clone(); + move |req: tide::Request<()>| handle_admin_logout(req, config.clone()) + }); app.listen(config.listen).await.unwrap(); } async fn serve_index<'a>( req: tide::Request<()>, + config: Arc, templates: Arc>, dbs: db::Dbs, errors: &[ErrorTemplate<'a>], @@ -70,6 +97,7 @@ async fn serve_index<'a>( "index.html", &IndexTemplate { lang: "fr", + root_url: &config.root_url, errors, ads: &to_json( dbs.ads @@ -95,6 +123,7 @@ async fn serve_index<'a>( async fn serve_admin<'a>( req: tide::Request<()>, + config: Arc, templates: Arc>, dbs: db::Dbs, errors: &[ErrorTemplate<'a>], @@ -109,6 +138,7 @@ async fn serve_admin<'a>( "admin.html", &AdminTemplate { lang: "fr", + root_url: &config.root_url, errors, ads: &to_json( dbs.ads @@ -133,6 +163,7 @@ async fn serve_admin<'a>( async fn serve_admin_login<'a>( _req: tide::Request<()>, + config: Arc, templates: Arc>, errors: &[ErrorTemplate<'a>], ) -> tide::Result { @@ -143,7 +174,11 @@ async fn serve_admin_login<'a>( .hb .render( "admin_login.html", - &AdminLoginTemplate { lang: "fr", errors }, + &AdminLoginTemplate { + lang: "fr", + root_url: &config.root_url, + errors, + }, ) .unwrap_or_else(|e| e.to_string()), ) @@ -152,17 +187,23 @@ async fn serve_admin_login<'a>( async fn handle_post_index( mut req: tide::Request<()>, + config: Arc, templates: Arc>, dbs: db::Dbs, ) -> tide::Result { match req.body_form::().await? { - Query::NewAdQuery(query) => handle_new_ad(req, templates.clone(), dbs.clone(), query).await, - Query::RmAdQuery(query) => handle_rm_ad(req, templates.clone(), dbs.clone(), query).await, + Query::NewAdQuery(query) => { + handle_new_ad(req, config.clone(), templates.clone(), dbs.clone(), query).await + } + Query::RmAdQuery(query) => { + handle_rm_ad(req, config.clone(), templates.clone(), dbs.clone(), query).await + } } } async fn handle_new_ad( req: tide::Request<()>, + config: Arc, templates: Arc>, dbs: db::Dbs, query: NewAdQuery, @@ -180,6 +221,7 @@ async fn handle_new_ad( Ok(pubkey) => pubkey, Err(e) => return serve_index( req, + config, templates, dbs, &[ErrorTemplate { @@ -208,11 +250,12 @@ async fn handle_new_ad( ) .unwrap(); dbs.ads.flush().unwrap(); - Ok(tide::Redirect::new("/").into()) + Ok(tide::Redirect::new(&config.root_url).into()) } async fn handle_rm_ad( req: tide::Request<()>, + config: Arc, templates: Arc>, dbs: db::Dbs, query: RmAdQuery, @@ -244,6 +287,7 @@ async fn handle_rm_ad( } else { return serve_index( req, + config, templates, dbs, &[ErrorTemplate { @@ -257,7 +301,7 @@ async fn handle_rm_ad( } } } - Ok(tide::Redirect::new("/").into()) + Ok(tide::Redirect::new(&config.root_url).into()) } async fn handle_admin( @@ -268,10 +312,11 @@ async fn handle_admin( ) -> tide::Result { if let Some(psw) = req.cookie("admin") { if config.admin_passwords.contains(&String::from(psw.value())) { - serve_admin(req, templates, dbs, &[]).await + serve_admin(req, config, templates, dbs, &[]).await } else { serve_admin_login( req, + config, templates, &[ErrorTemplate { text: "Mot de passe administrateur invalide", @@ -280,7 +325,7 @@ async fn handle_admin( .await } } else { - serve_admin_login(req, templates, &[]).await + serve_admin_login(req, config, templates, &[]).await } } @@ -301,13 +346,14 @@ async fn handle_post_admin( dbs.ads.flush().unwrap(); } } - Ok(tide::Redirect::new("/admin").into()) + Ok(tide::Redirect::new(&format!("{}admin", config.root_url)).into()) } - _ => serve_admin(req, templates, dbs, &[]).await, + _ => serve_admin(req, config, templates, dbs, &[]).await, } } else { serve_admin_login( req, + config, templates, &[ErrorTemplate { text: "Mot de passe administrateur invalide", @@ -317,16 +363,19 @@ async fn handle_post_admin( } } else if let AdminQuery::LoginQuery(query) = req.body_form::().await? { if config.admin_passwords.contains(&query.psw) { - serve_admin(req, templates, dbs, &[]).await.map(|mut r| { - let mut cookie = tide::http::Cookie::new("admin", query.psw); - cookie.set_http_only(Some(true)); - cookie.set_path("/"); - r.insert_cookie(cookie); - r - }) + serve_admin(req, config.clone(), templates, dbs, &[]) + .await + .map(|mut r| { + let mut cookie = tide::http::Cookie::new("admin", query.psw); + cookie.set_http_only(Some(true)); + cookie.set_path(config.root_url.clone()); + r.insert_cookie(cookie); + r + }) } else { serve_admin_login( req, + config, templates, &[ErrorTemplate { text: "Mot de passe administrateur invalide", @@ -335,14 +384,17 @@ async fn handle_post_admin( .await } } else { - serve_admin_login(req, templates, &[]).await + serve_admin_login(req, config, templates, &[]).await } } -async fn handle_admin_logout(req: tide::Request<()>) -> tide::Result { +async fn handle_admin_logout( + req: tide::Request<()>, + config: Arc, +) -> tide::Result { let mut r: tide::Response = tide::Redirect::new("/").into(); if let Some(mut cookie) = req.cookie("admin") { - cookie.set_path("/"); + cookie.set_path(config.root_url.clone()); r.remove_cookie(cookie); } Ok(r) diff --git a/src/templates.rs b/src/templates.rs index 28c7746..375664f 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -49,6 +49,7 @@ pub fn load_templates<'reg>(dir: &Path) -> Templates<'reg> { #[derive(Serialize)] pub struct IndexTemplate<'a> { pub lang: &'a str, + pub root_url: &'a str, pub errors: &'a [ErrorTemplate<'a>], pub ads: &'a Json, pub new_ad_form_refill: Option, @@ -57,12 +58,14 @@ pub struct IndexTemplate<'a> { #[derive(Serialize)] pub struct AdminLoginTemplate<'a> { pub lang: &'a str, + pub root_url: &'a str, pub errors: &'a [ErrorTemplate<'a>], } #[derive(Serialize)] pub struct AdminTemplate<'a> { pub lang: &'a str, + pub root_url: &'a str, pub errors: &'a [ErrorTemplate<'a>], pub ads: &'a Json, } diff --git a/templates/admin.html b/templates/admin.html index c8a1b77..3ba2874 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -3,14 +3,14 @@ Administration | ĞMarché - - - + + +
- +
@@ -38,7 +38,7 @@ {{#each ads}} - {{this.ad.title}} + {{this.ad.title}} {{this.ad.quantity}} {{this.ad.author}} @@ -73,7 +73,7 @@ CopyLeft 2020 Pascal Engélibert
Image de fond : Claudia Peters, FreeImages.com

-

AccueilVerrouiller

+

AccueilVerrouiller

diff --git a/templates/admin_login.html b/templates/admin_login.html index 293d85b..7273ae7 100644 --- a/templates/admin_login.html +++ b/templates/admin_login.html @@ -3,13 +3,13 @@ Administration | ĞMarché - - + +
- +
@@ -28,7 +28,7 @@
{{/if}} -
+ @@ -45,7 +45,7 @@ CopyLeft 2020 Pascal Engélibert
Image de fond : Claudia Peters, FreeImages.com

-

Accueil

+

Accueil

diff --git a/templates/index.html b/templates/index.html index 079c980..8ddd5f6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3,14 +3,14 @@ ĞMarché - - - + + +
- +
@@ -42,7 +42,7 @@ {{#each ads}} - {{this.ad.title}} + {{this.ad.title}} {{this.ad.quantity}} {{this.ad.author}} @@ -69,7 +69,7 @@

Il n'y a pas encore d'annonce ici.

{{/if}} - Marché + Marché @@ -102,7 +102,7 @@ CopyLeft 2020 Pascal Engélibert
Image de fond : Claudia Peters, FreeImages.com

-

Administration

+

Administration