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]]
name = "subtle"
version = "2.3.0"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd"
checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
[[package]]
name = "syn"

View File

@ -8,21 +8,50 @@ const CONFIG_FILE: &str = "config.json";
#[derive(Deserialize, Serialize)]
pub struct Config {
#[serde(default = "Config::default_admin_passwords")]
pub admin_passwords: Vec<String>,
#[serde(default = "Config::default_cookies_https_only")]
pub cookies_https_only: bool,
#[serde(default = "Config::default_cookies_domain")]
pub cookies_domain: Option<String>,
#[serde(default = "Config::default_listen")]
pub listen: SocketAddr,
#[serde(default = "Config::default_root_url")]
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 {
fn default() -> Self {
Self {
admin_passwords: vec![],
cookies_https_only: false,
cookies_domain: None,
listen: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 10353),
root_url: String::from("/"),
admin_passwords: Self::default_admin_passwords(),
cookies_https_only: Self::default_cookies_https_only(),
cookies_domain: Self::default_cookies_domain(),
listen: Self::default_listen(),
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 sha2::{Digest, Sha512Trunc256};
@ -8,8 +8,8 @@ use std::{
};
pub async fn start_server(
config: config::Config,
dbs: db::Dbs,
config: Config,
dbs: Dbs,
templates: Templates<'static>,
opt: cli::MainOpt,
) {
@ -105,9 +105,9 @@ pub async fn start_server(
async fn serve_index<'a>(
req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: db::Dbs,
dbs: Dbs,
errors: &[ErrorTemplate<'a>],
new_ad_form_refill: Option<NewAdQuery>,
) -> tide::Result<tide::Response> {
@ -120,9 +120,12 @@ async fn serve_index<'a>(
.render(
"index.html",
&IndexTemplate {
lang: "fr",
root_url: &config.root_url,
errors,
common: CommonTemplate {
lang: "fr",
root_url: &config.root_url,
title: &config.title,
errors,
},
ads: &to_json(
dbs.ads
.iter()
@ -147,9 +150,9 @@ async fn serve_index<'a>(
async fn serve_admin<'a>(
req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: db::Dbs,
dbs: Dbs,
errors: &[ErrorTemplate<'a>],
) -> tide::Result<tide::Response> {
let selected_ad = req.param("ad").ok();
@ -161,9 +164,12 @@ async fn serve_admin<'a>(
.render(
"admin.html",
&AdminTemplate {
lang: "fr",
root_url: &config.root_url,
errors,
common: CommonTemplate {
lang: "fr",
root_url: &config.root_url,
title: &config.title,
errors,
},
ads: &to_json(
dbs.ads
.iter()
@ -187,7 +193,7 @@ async fn serve_admin<'a>(
async fn serve_admin_login<'a>(
_req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
errors: &[ErrorTemplate<'a>],
) -> tide::Result<tide::Response> {
@ -199,9 +205,12 @@ async fn serve_admin_login<'a>(
.render(
"admin_login.html",
&AdminLoginTemplate {
lang: "fr",
root_url: &config.root_url,
errors,
common: CommonTemplate {
lang: "fr",
root_url: &config.root_url,
title: &config.title,
errors,
},
},
)
.unwrap_or_else(|e| e.to_string()),
@ -211,9 +220,9 @@ async fn serve_admin_login<'a>(
async fn handle_post_index(
mut req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: db::Dbs,
dbs: Dbs,
) -> tide::Result<tide::Response> {
match req.body_form::<Query>().await? {
Query::NewAdQuery(query) => {
@ -227,9 +236,9 @@ async fn handle_post_index(
async fn handle_new_ad(
req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: db::Dbs,
dbs: Dbs,
query: NewAdQuery,
) -> tide::Result<tide::Response> {
let mut hasher = Sha512Trunc256::new();
@ -279,9 +288,9 @@ async fn handle_new_ad(
async fn handle_rm_ad(
req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: db::Dbs,
dbs: Dbs,
query: RmAdQuery,
) -> tide::Result<tide::Response> {
let mut hasher = Sha512Trunc256::new();
@ -330,9 +339,9 @@ async fn handle_rm_ad(
async fn handle_admin(
req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: db::Dbs,
dbs: Dbs,
) -> tide::Result<tide::Response> {
if let Some(psw) = req.cookie("admin") {
if config.admin_passwords.contains(&String::from(psw.value())) {
@ -355,9 +364,9 @@ async fn handle_admin(
async fn handle_post_admin(
mut req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: db::Dbs,
dbs: Dbs,
) -> tide::Result<tide::Response> {
if let Some(psw) = req.cookie("admin") {
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);
cookie.set_http_only(Some(true));
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
})
@ -414,11 +429,14 @@ async fn handle_post_admin(
async fn handle_admin_logout(
req: tide::Request<()>,
config: Arc<config::Config>,
config: Arc<Config>,
) -> tide::Result<tide::Response> {
let mut r: tide::Response = tide::Redirect::new("/").into();
if let Some(mut cookie) = req.cookie("admin") {
cookie.set_path(config.root_url.clone());
if let Some(domain) = &config.cookies_domain {
cookie.set_domain(domain.clone());
}
r.remove_cookie(cookie);
}
Ok(r)

View File

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

View File

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

View File

@ -2,18 +2,18 @@
<html lang="{{lang}}">
<head>
<meta charset="utf-8"/>
<title>Administration | ĞMarché</title>
<title>Administration | {{title}}</title>
<link rel="stylesheet" href="{{root_url}}static/style1.css"/>
<link rel="shortcut icon" href="{{root_url}}static/icon.png"/>
</head>
<body>
<div class="center page">
<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>
<main>
<h1>Administration &#8211; ĞMarché</h1>
<h1>Administration &#8211; {{title}}</h1>
<h2>Authentification</h2>

View File

@ -2,7 +2,7 @@
<html lang="{{lang}}">
<head>
<meta charset="utf-8"/>
<title>ĞMarché</title>
<title>{{title}}</title>
<link rel="stylesheet" href="{{root_url}}static/style1.css"/>
<link rel="shortcut icon" href="{{root_url}}static/icon.png"/>
<script type="text/javascript" src="{{root_url}}static/script1.js"></script>
@ -10,11 +10,11 @@
<body>
<div class="center page">
<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>
<main>
<h1>ĞMarché</h1>
<h1>{{title}}</h1>
{{#if errors}}
<div id="errors">
@ -27,9 +27,7 @@
</div>
{{/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>&#9888; <strong>Merci de ne pas encore utiliser ce site pour de vrais événements&#8239;!</strong></p>
<p>Ceci est une démo du nouveau site ĞMarché en développement.</p>
{{#if ads}}
<span>Cliquez sur une annonce pour afficher le détail.</span>