Compare commits

...

3 Commits

Author SHA1 Message Date
Pascal Engélibert 71b9e22bba Cookies secure & domain 2020-12-18 08:39:29 +01:00
Pascal Engélibert a97c62ae9b Config defaults 2020-12-18 08:26:30 +01:00
Pascal Engélibert 3ab0e0fe4e Title, CommonTemplate 2020-12-17 23:08:31 +01:00
7 changed files with 104 additions and 54 deletions

4
Cargo.lock generated
View File

@ -1626,9 +1626,9 @@ dependencies = [
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.3.0" version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
[[package]] [[package]]
name = "syn" name = "syn"

View File

@ -8,21 +8,50 @@ const CONFIG_FILE: &str = "config.json";
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct Config { pub struct Config {
#[serde(default = "Config::default_admin_passwords")]
pub admin_passwords: Vec<String>, pub admin_passwords: Vec<String>,
#[serde(default = "Config::default_cookies_https_only")]
pub cookies_https_only: bool, pub cookies_https_only: bool,
#[serde(default = "Config::default_cookies_domain")]
pub cookies_domain: Option<String>, pub cookies_domain: Option<String>,
#[serde(default = "Config::default_listen")]
pub listen: SocketAddr, pub listen: SocketAddr,
#[serde(default = "Config::default_root_url")]
pub root_url: String, pub root_url: String,
#[serde(default = "Config::default_title")]
pub title: String,
}
impl Config {
fn default_admin_passwords() -> Vec<String> {
vec![]
}
fn default_cookies_https_only() -> bool {
false
}
fn default_cookies_domain() -> Option<String> {
None
}
fn default_listen() -> SocketAddr {
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 10353)
}
fn default_root_url() -> String {
"/".into()
}
fn default_title() -> String {
"ĞMarché".into()
}
} }
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Self { Self {
admin_passwords: vec![], admin_passwords: Self::default_admin_passwords(),
cookies_https_only: false, cookies_https_only: Self::default_cookies_https_only(),
cookies_domain: None, cookies_domain: Self::default_cookies_domain(),
listen: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 10353), listen: Self::default_listen(),
root_url: String::from("/"), root_url: Self::default_root_url(),
title: Self::default_title(),
} }
} }
} }

View File

@ -1,4 +1,4 @@
use super::{cli, config, db, queries::*, static_files, templates::*, utils::*}; use super::{cli, config::*, db::*, queries::*, static_files, templates::*, utils::*};
use handlebars::to_json; use handlebars::to_json;
use sha2::{Digest, Sha512Trunc256}; use sha2::{Digest, Sha512Trunc256};
@ -8,8 +8,8 @@ use std::{
}; };
pub async fn start_server( pub async fn start_server(
config: config::Config, config: Config,
dbs: db::Dbs, dbs: Dbs,
templates: Templates<'static>, templates: Templates<'static>,
opt: cli::MainOpt, opt: cli::MainOpt,
) { ) {
@ -105,9 +105,9 @@ pub async fn start_server(
async fn serve_index<'a>( async fn serve_index<'a>(
req: tide::Request<()>, req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
templates: Arc<Templates<'static>>, templates: Arc<Templates<'static>>,
dbs: db::Dbs, dbs: Dbs,
errors: &[ErrorTemplate<'a>], errors: &[ErrorTemplate<'a>],
new_ad_form_refill: Option<NewAdQuery>, new_ad_form_refill: Option<NewAdQuery>,
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
@ -120,9 +120,12 @@ async fn serve_index<'a>(
.render( .render(
"index.html", "index.html",
&IndexTemplate { &IndexTemplate {
lang: "fr", common: CommonTemplate {
root_url: &config.root_url, lang: "fr",
errors, root_url: &config.root_url,
title: &config.title,
errors,
},
ads: &to_json( ads: &to_json(
dbs.ads dbs.ads
.iter() .iter()
@ -147,9 +150,9 @@ async fn serve_index<'a>(
async fn serve_admin<'a>( async fn serve_admin<'a>(
req: tide::Request<()>, req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
templates: Arc<Templates<'static>>, templates: Arc<Templates<'static>>,
dbs: db::Dbs, dbs: Dbs,
errors: &[ErrorTemplate<'a>], errors: &[ErrorTemplate<'a>],
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
let selected_ad = req.param("ad").ok(); let selected_ad = req.param("ad").ok();
@ -161,9 +164,12 @@ async fn serve_admin<'a>(
.render( .render(
"admin.html", "admin.html",
&AdminTemplate { &AdminTemplate {
lang: "fr", common: CommonTemplate {
root_url: &config.root_url, lang: "fr",
errors, root_url: &config.root_url,
title: &config.title,
errors,
},
ads: &to_json( ads: &to_json(
dbs.ads dbs.ads
.iter() .iter()
@ -187,7 +193,7 @@ async fn serve_admin<'a>(
async fn serve_admin_login<'a>( async fn serve_admin_login<'a>(
_req: tide::Request<()>, _req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
templates: Arc<Templates<'static>>, templates: Arc<Templates<'static>>,
errors: &[ErrorTemplate<'a>], errors: &[ErrorTemplate<'a>],
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
@ -199,9 +205,12 @@ async fn serve_admin_login<'a>(
.render( .render(
"admin_login.html", "admin_login.html",
&AdminLoginTemplate { &AdminLoginTemplate {
lang: "fr", common: CommonTemplate {
root_url: &config.root_url, lang: "fr",
errors, root_url: &config.root_url,
title: &config.title,
errors,
},
}, },
) )
.unwrap_or_else(|e| e.to_string()), .unwrap_or_else(|e| e.to_string()),
@ -211,9 +220,9 @@ async fn serve_admin_login<'a>(
async fn handle_post_index( async fn handle_post_index(
mut req: tide::Request<()>, mut req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
templates: Arc<Templates<'static>>, templates: Arc<Templates<'static>>,
dbs: db::Dbs, dbs: Dbs,
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
match req.body_form::<Query>().await? { match req.body_form::<Query>().await? {
Query::NewAdQuery(query) => { Query::NewAdQuery(query) => {
@ -227,9 +236,9 @@ async fn handle_post_index(
async fn handle_new_ad( async fn handle_new_ad(
req: tide::Request<()>, req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
templates: Arc<Templates<'static>>, templates: Arc<Templates<'static>>,
dbs: db::Dbs, dbs: Dbs,
query: NewAdQuery, query: NewAdQuery,
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
let mut hasher = Sha512Trunc256::new(); let mut hasher = Sha512Trunc256::new();
@ -279,9 +288,9 @@ async fn handle_new_ad(
async fn handle_rm_ad( async fn handle_rm_ad(
req: tide::Request<()>, req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
templates: Arc<Templates<'static>>, templates: Arc<Templates<'static>>,
dbs: db::Dbs, dbs: Dbs,
query: RmAdQuery, query: RmAdQuery,
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
let mut hasher = Sha512Trunc256::new(); let mut hasher = Sha512Trunc256::new();
@ -330,9 +339,9 @@ async fn handle_rm_ad(
async fn handle_admin( async fn handle_admin(
req: tide::Request<()>, req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
templates: Arc<Templates<'static>>, templates: Arc<Templates<'static>>,
dbs: db::Dbs, dbs: Dbs,
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
if let Some(psw) = req.cookie("admin") { if let Some(psw) = req.cookie("admin") {
if config.admin_passwords.contains(&String::from(psw.value())) { if config.admin_passwords.contains(&String::from(psw.value())) {
@ -355,9 +364,9 @@ async fn handle_admin(
async fn handle_post_admin( async fn handle_post_admin(
mut req: tide::Request<()>, mut req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
templates: Arc<Templates<'static>>, templates: Arc<Templates<'static>>,
dbs: db::Dbs, dbs: Dbs,
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
if let Some(psw) = req.cookie("admin") { if let Some(psw) = req.cookie("admin") {
if config.admin_passwords.contains(&String::from(psw.value())) { if config.admin_passwords.contains(&String::from(psw.value())) {
@ -393,6 +402,12 @@ async fn handle_post_admin(
let mut cookie = tide::http::Cookie::new("admin", query.psw); let mut cookie = tide::http::Cookie::new("admin", query.psw);
cookie.set_http_only(Some(true)); cookie.set_http_only(Some(true));
cookie.set_path(config.root_url.clone()); cookie.set_path(config.root_url.clone());
if let Some(domain) = &config.cookies_domain {
cookie.set_domain(domain.clone());
}
if config.cookies_https_only {
cookie.set_secure(Some(true));
}
r.insert_cookie(cookie); r.insert_cookie(cookie);
r r
}) })
@ -414,11 +429,14 @@ async fn handle_post_admin(
async fn handle_admin_logout( async fn handle_admin_logout(
req: tide::Request<()>, req: tide::Request<()>,
config: Arc<config::Config>, config: Arc<Config>,
) -> tide::Result<tide::Response> { ) -> tide::Result<tide::Response> {
let mut r: tide::Response = tide::Redirect::new("/").into(); let mut r: tide::Response = tide::Redirect::new("/").into();
if let Some(mut cookie) = req.cookie("admin") { if let Some(mut cookie) = req.cookie("admin") {
cookie.set_path(config.root_url.clone()); cookie.set_path(config.root_url.clone());
if let Some(domain) = &config.cookies_domain {
cookie.set_domain(domain.clone());
}
r.remove_cookie(cookie); r.remove_cookie(cookie);
} }
Ok(r) Ok(r)

View File

@ -47,26 +47,31 @@ pub fn load_templates<'reg>(dir: &Path) -> Templates<'reg> {
} }
#[derive(Serialize)] #[derive(Serialize)]
pub struct IndexTemplate<'a> { pub struct CommonTemplate<'a> {
pub lang: &'a str, pub lang: &'a str,
pub root_url: &'a str, pub root_url: &'a str,
pub title: &'a str,
pub errors: &'a [ErrorTemplate<'a>], pub errors: &'a [ErrorTemplate<'a>],
}
#[derive(Serialize)]
pub struct IndexTemplate<'a> {
#[serde(flatten)]
pub common: CommonTemplate<'a>,
pub ads: &'a Json, pub ads: &'a Json,
pub new_ad_form_refill: Option<NewAdQuery>, pub new_ad_form_refill: Option<NewAdQuery>,
} }
#[derive(Serialize)] #[derive(Serialize)]
pub struct AdminLoginTemplate<'a> { pub struct AdminLoginTemplate<'a> {
pub lang: &'a str, #[serde(flatten)]
pub root_url: &'a str, pub common: CommonTemplate<'a>,
pub errors: &'a [ErrorTemplate<'a>],
} }
#[derive(Serialize)] #[derive(Serialize)]
pub struct AdminTemplate<'a> { pub struct AdminTemplate<'a> {
pub lang: &'a str, #[serde(flatten)]
pub root_url: &'a str, pub common: CommonTemplate<'a>,
pub errors: &'a [ErrorTemplate<'a>],
pub ads: &'a Json, pub ads: &'a Json,
} }

View File

@ -2,7 +2,7 @@
<html lang="{{lang}}"> <html lang="{{lang}}">
<head> <head>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<title>Administration | ĞMarché</title> <title>Administration | {{title}}</title>
<link rel="stylesheet" href="{{root_url}}static/style1.css"/> <link rel="stylesheet" href="{{root_url}}static/style1.css"/>
<link rel="shortcut icon" href="{{root_url}}static/icon.png"/> <link rel="shortcut icon" href="{{root_url}}static/icon.png"/>
<script type="text/javascript" src="{{root_url}}static/script1.js"></script> <script type="text/javascript" src="{{root_url}}static/script1.js"></script>
@ -10,11 +10,11 @@
<body> <body>
<div class="center page"> <div class="center page">
<header> <header>
<a href="{{root_url}}"><img id="banner" alt="Bannière ĞMarché" src="{{root_url}}static/banner.jpg"/></a> <a href="{{root_url}}"><img id="banner" alt="Bannière {{title}}" src="{{root_url}}static/banner.jpg"/></a>
</header> </header>
<main> <main>
<h1>Administration &#8211; ĞMarché</h1> <h1>Administration &#8211; {{title}}</h1>
{{#if errors}} {{#if errors}}
<div id="errors"> <div id="errors">

View File

@ -2,18 +2,18 @@
<html lang="{{lang}}"> <html lang="{{lang}}">
<head> <head>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<title>Administration | ĞMarché</title> <title>Administration | {{title}}</title>
<link rel="stylesheet" href="{{root_url}}static/style1.css"/> <link rel="stylesheet" href="{{root_url}}static/style1.css"/>
<link rel="shortcut icon" href="{{root_url}}static/icon.png"/> <link rel="shortcut icon" href="{{root_url}}static/icon.png"/>
</head> </head>
<body> <body>
<div class="center page"> <div class="center page">
<header> <header>
<a href="{{root_url}}"><img id="banner" alt="Bannière ĞMarché" src="{{root_url}}static/banner.jpg"/></a> <a href="{{root_url}}"><img id="banner" alt="Bannière {{title}}" src="{{root_url}}static/banner.jpg"/></a>
</header> </header>
<main> <main>
<h1>Administration &#8211; ĞMarché</h1> <h1>Administration &#8211; {{title}}</h1>
<h2>Authentification</h2> <h2>Authentification</h2>

View File

@ -2,7 +2,7 @@
<html lang="{{lang}}"> <html lang="{{lang}}">
<head> <head>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<title>ĞMarché</title> <title>{{title}}</title>
<link rel="stylesheet" href="{{root_url}}static/style1.css"/> <link rel="stylesheet" href="{{root_url}}static/style1.css"/>
<link rel="shortcut icon" href="{{root_url}}static/icon.png"/> <link rel="shortcut icon" href="{{root_url}}static/icon.png"/>
<script type="text/javascript" src="{{root_url}}static/script1.js"></script> <script type="text/javascript" src="{{root_url}}static/script1.js"></script>
@ -10,11 +10,11 @@
<body> <body>
<div class="center page"> <div class="center page">
<header> <header>
<a href="{{root_url}}"><img id="banner" alt="Bannière ĞMarché" src="{{root_url}}static/banner.jpg"/></a> <a href="{{root_url}}"><img id="banner" alt="Bannière {{title}}" src="{{root_url}}static/banner.jpg"/></a>
</header> </header>
<main> <main>
<h1>ĞMarché</h1> <h1>{{title}}</h1>
{{#if errors}} {{#if errors}}
<div id="errors"> <div id="errors">
@ -27,9 +27,7 @@
</div> </div>
{{/if}} {{/if}}
<p>Ceci est une démo du nouveau site ĞMarché en développement. C'est <del>très</del> moche et il n'y a pas tellement de fonctionnalités mais ça avance. ;)</p> <p>Ceci est une démo du nouveau site ĞMarché en développement.</p>
<p>&#9888; <strong>Merci de ne pas encore utiliser ce site pour de vrais événements&#8239;!</strong></p>
{{#if ads}} {{#if ads}}
<span>Cliquez sur une annonce pour afficher le détail.</span> <span>Cliquez sur une annonce pour afficher le détail.</span>