gmarche-rs/src/server.rs

799 lines
20 KiB
Rust
Raw Normal View History

2020-12-17 23:08:31 +01:00
use super::{cli, config::*, db::*, queries::*, static_files, templates::*, utils::*};
2020-10-26 23:43:18 +01:00
2022-02-25 15:41:50 +01:00
use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
Argon2,
2020-10-26 23:43:18 +01:00
};
2022-02-25 15:41:50 +01:00
use handlebars::to_json;
use std::{convert::TryFrom, sync::Arc};
2020-10-26 23:43:18 +01:00
pub async fn start_server(
2020-12-17 23:08:31 +01:00
config: Config,
dbs: Dbs,
2020-12-17 10:05:26 +01:00
templates: Templates<'static>,
2020-10-26 23:43:18 +01:00
opt: cli::MainOpt,
) {
2020-12-21 16:13:23 +01:00
tide::log::start();
2020-10-26 23:43:18 +01:00
let templates = Arc::new(templates);
2020-11-06 15:23:17 +01:00
let config = Arc::new(config);
2020-12-17 10:05:26 +01:00
let mut app = tide::new();
2020-12-17 17:13:11 +01:00
app.at(&format!("{}static", config.root_url))
2020-12-17 10:05:26 +01:00
.serve_dir(opt.dir.0.join(static_files::STATIC_DIR))
.unwrap();
2020-12-17 17:13:11 +01:00
app.at(&config.root_url).get({
let config = config.clone();
2020-11-06 15:23:17 +01:00
let templates = templates.clone();
2020-12-17 10:05:26 +01:00
let dbs = dbs.clone();
2020-12-17 17:13:11 +01:00
move |req: tide::Request<()>| {
serve_index(
req,
config.clone(),
templates.clone(),
dbs.clone(),
&[],
None,
)
}
2020-12-17 10:05:26 +01:00
});
2020-12-17 17:13:11 +01:00
app.at(&config.root_url).post({
let config = config.clone();
2020-11-06 15:23:17 +01:00
let templates = templates.clone();
2020-12-08 22:45:29 +01:00
let dbs = dbs.clone();
2020-12-17 17:13:11 +01:00
move |req: tide::Request<()>| {
handle_post_index(req, config.clone(), templates.clone(), dbs.clone())
}
2020-12-17 10:05:26 +01:00
});
2022-02-25 15:41:50 +01:00
app.at(&format!("{}g/:group", config.root_url)).get({
let config = config.clone();
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
serve_group(
req,
config.clone(),
templates.clone(),
dbs.clone(),
&[],
None,
)
}
});
app.at(&format!("{}g/:group/:ad", config.root_url)).get({
let config = config.clone();
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
serve_group(
req,
config.clone(),
templates.clone(),
dbs.clone(),
&[],
None,
)
}
});
app.at(&format!("{}admin/g/:group", config.root_url)).get({
let config = config.clone();
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
handle_admin_group(req, config.clone(), templates.clone(), dbs.clone())
}
});
2020-12-17 17:52:07 +01:00
app.at(&format!("{}ad/:ad", config.root_url)).post({
let config = config.clone();
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
handle_post_index(req, config.clone(), templates.clone(), dbs.clone())
}
});
2020-12-17 17:13:11 +01:00
app.at(&format!("{}ad/:ad", config.root_url)).get({
let config = config.clone();
2020-12-17 10:05:26 +01:00
let templates = templates.clone();
2020-12-08 10:56:32 +01:00
let dbs = dbs.clone();
2020-12-17 17:13:11 +01:00
move |req: tide::Request<()>| {
serve_index(
req,
config.clone(),
templates.clone(),
dbs.clone(),
&[],
None,
)
}
2020-12-17 10:05:26 +01:00
});
2020-12-17 17:13:11 +01:00
app.at(&format!("{}admin", config.root_url)).get({
2020-12-17 10:05:26 +01:00
let config = config.clone();
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
handle_admin(req, config.clone(), templates.clone(), dbs.clone())
}
2020-12-17 10:05:26 +01:00
});
2022-02-27 23:35:30 +01:00
app.at(&format!("{}admin/g/", config.root_url)).get({
let config = config.clone();
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
handle_admin(req, config.clone(), templates.clone(), dbs.clone())
}
});
2020-12-17 17:52:07 +01:00
app.at(&format!("{}admin/ad/:ad", config.root_url)).get({
let config = config.clone();
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
handle_admin(req, config.clone(), templates.clone(), dbs.clone())
}
});
2020-12-17 17:13:11 +01:00
app.at(&format!("{}admin", config.root_url)).post({
2020-12-17 10:05:26 +01:00
let config = config.clone();
2020-12-17 17:52:07 +01:00
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
handle_post_admin(req, config.clone(), templates.clone(), dbs.clone())
}
});
2022-02-28 19:02:02 +01:00
app.at(&format!("{}admin/g/:group", config.root_url)).post({
let config = config.clone();
let templates = templates.clone();
let dbs = dbs.clone();
move |req: tide::Request<()>| {
handle_post_admin(req, config.clone(), templates.clone(), dbs.clone())
}
});
2020-12-17 17:52:07 +01:00
app.at(&format!("{}admin/ad/:ad", config.root_url)).post({
let config = config.clone();
2020-12-17 10:05:26 +01:00
move |req: tide::Request<()>| {
handle_post_admin(req, config.clone(), templates.clone(), dbs.clone())
}
});
2020-12-17 17:13:11 +01:00
app.at(&format!("{}admin/logout", config.root_url)).get({
let config = config.clone();
move |req: tide::Request<()>| handle_admin_logout(req, config.clone())
});
2020-12-17 10:05:26 +01:00
app.listen(config.listen).await.unwrap();
}
2020-12-17 10:05:26 +01:00
async fn serve_index<'a>(
req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 10:05:26 +01:00
templates: Arc<Templates<'static>>,
2020-12-17 23:08:31 +01:00
dbs: Dbs,
2020-12-17 10:05:26 +01:00
errors: &[ErrorTemplate<'a>],
new_ad_form_refill: Option<NewAdQuery>,
) -> tide::Result<tide::Response> {
let selected_ad = req.param("ad").ok();
Ok(tide::Response::builder(200)
.content_type(tide::http::mime::HTML)
.body(
templates
.hb
.render(
"index.html",
&IndexTemplate {
2022-02-26 11:27:39 +01:00
common: CommonTemplate::new(&config, errors),
2020-12-17 10:05:26 +01:00
ads: &to_json(
2022-02-25 15:41:50 +01:00
dbs.ad_by_group
.scan_prefix(ROOT_GROUP_ID)
2020-12-08 10:56:32 +01:00
.filter_map(|x| {
2022-02-25 15:41:50 +01:00
let (k, ad) = x.ok()?;
let ad_id =
hex::encode(AdId::try_from(&k.as_ref()[16..32]).ok()?);
2020-12-08 10:56:32 +01:00
Some(AdWithId {
ad: bincode::deserialize::<Ad>(&ad).ok()?,
2020-12-17 10:05:26 +01:00
selected: selected_ad.map_or(false, |i| i == ad_id),
id: ad_id,
2020-12-08 10:56:32 +01:00
})
})
.collect::<Vec<AdWithId>>(),
2020-12-17 10:05:26 +01:00
),
2022-02-25 15:41:50 +01:00
groups: &to_json(
dbs.group_by_group
.scan_prefix(ROOT_GROUP_ID)
.keys()
.filter_map(|k| GroupId::try_from(&k.ok()?.as_ref()[16..32]).ok())
.filter_map(|subgroup_id| {
bincode::deserialize(&dbs.group.get(subgroup_id).ok()??).ok()
})
.collect::<Vec<Group>>(),
),
2020-12-17 10:05:26 +01:00
new_ad_form_refill,
},
2020-12-08 10:56:32 +01:00
)
2020-12-17 10:05:26 +01:00
.unwrap_or_else(|e| e.to_string()),
)
.build())
2020-10-26 23:43:18 +01:00
}
2020-11-02 11:41:55 +01:00
2022-02-25 15:41:50 +01:00
async fn serve_group<'a>(
req: tide::Request<()>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: Dbs,
errors: &[ErrorTemplate<'a>],
new_ad_form_refill: Option<NewAdQuery>,
) -> tide::Result<tide::Response> {
if let Ok(group_name) = req.param("group") {
if let Some(group_id) = dbs.group_by_name.get(group_name).unwrap() {
2022-02-26 11:27:39 +01:00
if let Some(group) = dbs.group.get(&group_id).unwrap() {
if let Ok(group) = bincode::deserialize::<Group>(&group) {
let selected_ad = req.param("ad").ok();
2022-02-25 15:41:50 +01:00
2022-02-26 11:27:39 +01:00
return Ok(tide::Response::builder(200)
.content_type(tide::http::mime::HTML)
.body(
templates
.hb
.render(
"group.html",
&GroupTemplate {
common: CommonTemplate::new(&config, errors),
ads: &to_json(
dbs.ad_by_group
.scan_prefix(group_id.clone())
.filter_map(|x| {
let (k, ad) = x.ok()?;
let ad_id = hex::encode(
AdId::try_from(&k.as_ref()[16..32]).ok()?,
);
Some(AdWithId {
ad: bincode::deserialize::<Ad>(&ad).ok()?,
selected: selected_ad
.map_or(false, |i| i == ad_id),
id: ad_id,
})
})
.collect::<Vec<AdWithId>>(),
),
2022-02-27 23:35:30 +01:00
parent_group_name: &dbs
.group
.get(&group.parent)
.unwrap()
.map_or_else(String::new, |parent_group| {
bincode::deserialize::<Group>(&parent_group)
.map_or_else(
|_| String::new(),
|parent_group| parent_group.name,
)
}),
2022-02-26 11:27:39 +01:00
group: &to_json(group),
groups: &to_json(
dbs.group_by_group
.scan_prefix(group_id)
.keys()
.filter_map(|k| {
GroupId::try_from(&k.ok()?.as_ref()[16..32])
.ok()
})
.filter_map(|subgroup_id| {
bincode::deserialize(
&dbs.group.get(subgroup_id).ok()??,
)
.ok()
})
.collect::<Vec<Group>>(),
),
new_ad_form_refill,
},
)
.unwrap_or_else(|e| e.to_string()),
2022-02-25 15:41:50 +01:00
)
2022-02-26 11:27:39 +01:00
.build());
}
}
2022-02-25 15:41:50 +01:00
}
2022-02-26 11:27:39 +01:00
serve_index(
req,
config,
templates,
dbs,
&[ErrorTemplate {
text: "Le groupe demandé n'existe pas.",
}],
None,
)
.await
2022-02-25 15:41:50 +01:00
} else {
serve_index(req, config, templates, dbs, &[], None).await
}
}
async fn serve_admin_group<'a>(
req: tide::Request<()>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: Dbs,
errors: &[ErrorTemplate<'a>],
new_group_form_refill: Option<AdminNewGroupQuery>,
) -> tide::Result<tide::Response> {
if let Ok(group_name) = req.param("group") {
if let Some(group_id) = dbs.group_by_name.get(group_name).unwrap() {
if let Some(group) = dbs.group.get(&group_id).unwrap() {
if let Ok(group) = bincode::deserialize::<Group>(&group) {
let selected_ad = req.param("ad").ok();
return Ok(tide::Response::builder(200)
.content_type(tide::http::mime::HTML)
.body(
templates
.hb
.render(
"admin_group.html",
&AdminGroupTemplate {
2022-02-26 11:27:39 +01:00
common: CommonTemplate::new(&config, errors),
2022-02-25 15:41:50 +01:00
ads: &to_json(
dbs.ad_by_group
.scan_prefix(group_id.clone())
.filter_map(|x| {
let (k, ad) = x.ok()?;
let ad_id = hex::encode(
AdId::try_from(&k.as_ref()[16..32]).ok()?,
);
Some(AdWithId {
ad: bincode::deserialize::<Ad>(&ad).ok()?,
selected: selected_ad
.map_or(false, |i| i == ad_id),
id: ad_id,
})
})
.collect::<Vec<AdWithId>>(),
),
2022-02-27 23:35:30 +01:00
parent_group_name: &dbs
.group
.get(&group.parent)
.unwrap()
.map_or_else(String::new, |parent_group| {
bincode::deserialize::<Group>(&parent_group)
.map_or_else(
|_| String::new(),
|parent_group| parent_group.name,
)
}),
2022-02-25 15:41:50 +01:00
group: &to_json(group),
groups: &to_json(
dbs.group_by_group
.scan_prefix(group_id)
.keys()
.filter_map(|k| {
GroupId::try_from(&k.ok()?.as_ref()[16..32])
.ok()
})
.filter_map(|subgroup_id| {
bincode::deserialize(
&dbs.group.get(subgroup_id).ok()??,
)
.ok()
})
.collect::<Vec<Group>>(),
),
new_group_form_refill,
},
)
.unwrap_or_else(|e| e.to_string()),
)
.build());
}
}
}
serve_admin(
req,
config,
templates,
dbs,
&[ErrorTemplate {
text: "Le groupe demandé n'existe pas.",
}],
)
.await
} else {
serve_admin(req, config, templates, dbs, &[]).await
}
}
2020-12-17 10:05:26 +01:00
async fn serve_admin<'a>(
req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 10:05:26 +01:00
templates: Arc<Templates<'static>>,
2020-12-17 23:08:31 +01:00
dbs: Dbs,
2020-12-17 10:05:26 +01:00
errors: &[ErrorTemplate<'a>],
) -> tide::Result<tide::Response> {
let selected_ad = req.param("ad").ok();
Ok(tide::Response::builder(200)
.content_type(tide::http::mime::HTML)
.body(
templates
.hb
.render(
"admin.html",
&AdminTemplate {
2022-02-26 11:27:39 +01:00
common: CommonTemplate::new(&config, errors),
2020-12-17 10:05:26 +01:00
ads: &to_json(
2022-02-25 15:41:50 +01:00
dbs.ad_by_group
.scan_prefix(ROOT_GROUP_ID)
2020-12-17 10:05:26 +01:00
.filter_map(|x| {
2022-02-25 15:41:50 +01:00
let (k, ad) = x.ok()?;
let ad_id =
hex::encode(AdId::try_from(&k.as_ref()[16..32]).ok()?);
2020-12-17 10:05:26 +01:00
Some(AdWithId {
ad: bincode::deserialize::<Ad>(&ad).ok()?,
selected: selected_ad.map_or(false, |i| i == ad_id),
id: ad_id,
})
})
.collect::<Vec<AdWithId>>(),
),
2022-02-25 15:41:50 +01:00
groups: &to_json(
dbs.group_by_group
.scan_prefix(ROOT_GROUP_ID)
.keys()
.filter_map(|k| GroupId::try_from(&k.ok()?.as_ref()[16..32]).ok())
.filter_map(|subgroup_id| {
bincode::deserialize(&dbs.group.get(subgroup_id).ok()??).ok()
})
.collect::<Vec<Group>>(),
),
2020-12-17 10:05:26 +01:00
},
)
.unwrap_or_else(|e| e.to_string()),
)
.build())
2020-11-06 15:23:17 +01:00
}
2020-12-17 10:05:26 +01:00
async fn serve_admin_login<'a>(
_req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 10:05:26 +01:00
templates: Arc<Templates<'static>>,
errors: &[ErrorTemplate<'a>],
) -> tide::Result<tide::Response> {
Ok(tide::Response::builder(200)
.content_type(tide::http::mime::HTML)
.body(
templates
.hb
.render(
"admin_login.html",
2020-12-17 17:13:11 +01:00
&AdminLoginTemplate {
2022-02-26 11:27:39 +01:00
common: CommonTemplate::new(&config, errors),
2020-12-17 17:13:11 +01:00
},
2020-12-17 10:05:26 +01:00
)
.unwrap_or_else(|e| e.to_string()),
)
.build())
2020-11-02 11:41:55 +01:00
}
2020-12-17 10:05:26 +01:00
async fn handle_post_index(
mut req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 10:05:26 +01:00
templates: Arc<Templates<'static>>,
2020-12-17 23:08:31 +01:00
dbs: Dbs,
2020-12-17 10:05:26 +01:00
) -> tide::Result<tide::Response> {
2022-02-25 15:41:50 +01:00
match req.body_form::<IndexQuery>().await? {
IndexQuery::NewAd(query) => {
2020-12-17 17:13:11 +01:00
handle_new_ad(req, config.clone(), templates.clone(), dbs.clone(), query).await
}
2022-02-25 15:41:50 +01:00
IndexQuery::RmAd(query) => {
2020-12-17 17:13:11 +01:00
handle_rm_ad(req, config.clone(), templates.clone(), dbs.clone(), query).await
}
2020-12-17 10:05:26 +01:00
}
2020-10-26 23:43:18 +01:00
}
2020-12-17 10:05:26 +01:00
async fn handle_new_ad(
req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 10:05:26 +01:00
templates: Arc<Templates<'static>>,
2020-12-17 23:08:31 +01:00
dbs: Dbs,
2020-12-17 10:05:26 +01:00
query: NewAdQuery,
) -> tide::Result<tide::Response> {
2022-02-25 15:41:50 +01:00
dbs.ad
2020-12-17 10:05:26 +01:00
.insert(
AdId::random(),
bincode::serialize(&Ad {
pubkey: if query.pubkey.is_empty() {
None
} else {
Some(match format_pubkey(&query.pubkey) {
Ok(pubkey) => pubkey,
2022-02-26 11:27:39 +01:00
Err(e) => {
return serve_index(
req,
config,
templates,
dbs,
&[ErrorTemplate {
text: match e {
PubkeyDecodeError::BadChecksum => {
"La somme de contrôle de la clé publique est \
incorrecte."
}
PubkeyDecodeError::BadFormat => {
"Le format de la clé publique est incorrect."
}
},
}],
Some(query),
)
.await
}
2020-12-17 10:05:26 +01:00
})
},
author: query.author,
2022-02-25 15:41:50 +01:00
password: Argon2::default()
.hash_password(query.psw.as_bytes(), &SaltString::generate(&mut OsRng))
.unwrap()
.to_string(),
2020-12-17 10:05:26 +01:00
price: query.price,
quantity: query.quantity,
time: 0,
title: query.title,
})
.unwrap(),
)
.unwrap();
2022-02-25 15:41:50 +01:00
dbs.ad.flush_async().await.unwrap();
2020-12-17 17:13:11 +01:00
Ok(tide::Redirect::new(&config.root_url).into())
}
2020-12-17 10:05:26 +01:00
async fn handle_rm_ad(
req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 10:05:26 +01:00
templates: Arc<Templates<'static>>,
2020-12-17 23:08:31 +01:00
dbs: Dbs,
2020-12-17 10:05:26 +01:00
query: RmAdQuery,
) -> tide::Result<tide::Response> {
if let Ok(ad_id) = hex::decode(query.ad) {
if let Ok(ad_id) = AdId::try_from(ad_id.as_ref()) {
2022-02-25 15:41:50 +01:00
if let Some(raw) = dbs.ad.get(&ad_id).unwrap() {
2020-12-17 10:05:26 +01:00
if let Ok(ad) = bincode::deserialize::<Ad>(&raw) {
2022-02-25 15:41:50 +01:00
if let Ok(password) = PasswordHash::new(&ad.password) {
if Argon2::default()
.verify_password(query.psw.as_bytes(), &password)
.is_ok()
{
dbs.ad.remove(&ad_id).unwrap();
2020-12-08 10:56:32 +01:00
2022-02-25 15:41:50 +01:00
dbs.ad.flush_async().await.unwrap();
} else {
return serve_index(
req,
config,
templates,
dbs,
&[ErrorTemplate {
text: "Le mot de passe de l'annonce est incorrect.",
}],
None,
)
.await;
}
2020-12-17 10:05:26 +01:00
}
}
}
}
}
2020-12-17 17:13:11 +01:00
Ok(tide::Redirect::new(&config.root_url).into())
2020-11-06 15:23:17 +01:00
}
2020-12-17 10:05:26 +01:00
async fn handle_admin(
req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 10:05:26 +01:00
templates: Arc<Templates<'static>>,
2020-12-17 23:08:31 +01:00
dbs: Dbs,
2020-12-17 10:05:26 +01:00
) -> tide::Result<tide::Response> {
if let Some(psw) = req.cookie("admin") {
if config.admin_passwords.contains(&String::from(psw.value())) {
2020-12-17 17:13:11 +01:00
serve_admin(req, config, templates, dbs, &[]).await
2020-12-17 10:05:26 +01:00
} else {
serve_admin_login(
req,
2020-12-17 17:13:11 +01:00
config,
2020-12-17 10:05:26 +01:00
templates,
&[ErrorTemplate {
text: "Mot de passe administrateur invalide",
}],
)
.await
}
} else {
2020-12-17 17:13:11 +01:00
serve_admin_login(req, config, templates, &[]).await
2020-12-17 10:05:26 +01:00
}
}
2022-02-25 15:41:50 +01:00
async fn handle_admin_group(
req: tide::Request<()>,
config: Arc<Config>,
templates: Arc<Templates<'static>>,
dbs: Dbs,
) -> tide::Result<tide::Response> {
if let Some(psw) = req.cookie("admin") {
if config.admin_passwords.contains(&String::from(psw.value())) {
serve_admin_group(req, config, templates, dbs, &[], None).await
} else {
serve_admin_login(
req,
config,
templates,
&[ErrorTemplate {
text: "Mot de passe administrateur invalide",
}],
)
.await
}
} else {
serve_admin_login(req, config, templates, &[]).await
}
}
2020-12-17 10:05:26 +01:00
async fn handle_post_admin(
mut req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 10:05:26 +01:00
templates: Arc<Templates<'static>>,
2020-12-17 23:08:31 +01:00
dbs: Dbs,
2020-12-17 10:05:26 +01:00
) -> tide::Result<tide::Response> {
if let Some(psw) = req.cookie("admin") {
if config.admin_passwords.contains(&String::from(psw.value())) {
match req.body_form::<AdminQuery>().await? {
2022-02-25 15:41:50 +01:00
AdminQuery::RmAd(query) => {
2020-12-17 10:05:26 +01:00
if let Ok(ad_id) = hex::decode(query.ad) {
if let Ok(ad_id) = AdId::try_from(ad_id.as_ref()) {
2022-02-25 15:41:50 +01:00
dbs.ad.remove(&ad_id).unwrap();
2020-12-08 10:56:32 +01:00
2022-02-25 15:41:50 +01:00
dbs.ad.flush_async().await.unwrap();
}
}
Ok(tide::Redirect::new(&format!("{}admin", config.root_url)).into())
}
AdminQuery::NewGroup(query) => {
if let Some(Ok(parent_group_id)) = if query.parent.is_empty() {
Some(Ok(ROOT_GROUP_ID))
} else {
dbs.group_by_name
.get(&query.parent)
.unwrap()
.map(|o| GroupId::try_from(o.as_ref()))
} {
if !dbs.group_by_name.contains_key(&query.name).unwrap() {
let group_id = rand::random::<GroupId>();
dbs.group
.insert(
group_id,
bincode::serialize(&Group {
parent: parent_group_id,
name: query.name.clone(),
title: query.title,
})
.unwrap(),
)
.unwrap();
dbs.group_by_name
.insert(query.name.clone(), &group_id)
.unwrap();
dbs.group_by_group
.insert([parent_group_id, group_id].concat(), &[])
.unwrap();
return Ok(tide::Redirect::new(&format!(
"{}admin/g/{}",
config.root_url, query.name
))
.into());
2020-12-17 10:05:26 +01:00
}
2022-02-25 15:41:50 +01:00
return Ok(tide::Redirect::new(&format!(
"{}admin/g/{}",
config.root_url, query.parent
))
.into());
2020-12-17 10:05:26 +01:00
}
2020-12-17 17:13:11 +01:00
Ok(tide::Redirect::new(&format!("{}admin", config.root_url)).into())
2020-12-17 10:05:26 +01:00
}
2022-02-28 19:02:02 +01:00
AdminQuery::EditGroup(query) => {
if let Some(Ok(group_id)) = if query.group.is_empty() {
Some(Ok(ROOT_GROUP_ID))
} else {
dbs.group_by_name
.get(&query.group)
.unwrap()
.map(|o| GroupId::try_from(o.as_ref()))
} {
if let Some(group) = dbs.group.get(&group_id).unwrap() {
if let Ok(group) = bincode::deserialize::<Group>(&group) {
if query.group == query.name
|| !dbs.group_by_name.contains_key(&query.name).unwrap()
{
dbs.group
.insert(
group_id,
bincode::serialize(&Group {
parent: group.parent,
name: query.name.clone(),
title: query.title,
})
.unwrap(),
)
.unwrap();
if group.name != query.name {
dbs.group_by_name.remove(&group.name).unwrap();
dbs.group_by_name
.insert(query.name.clone(), &group_id)
.unwrap();
}
return Ok(tide::Redirect::new(&format!(
"{}admin/g/{}",
config.root_url, query.name
))
.into());
}
}
}
return Ok(tide::Redirect::new(&format!(
"{}admin/g/{}",
config.root_url, query.name
))
.into());
}
Ok(tide::Redirect::new(&format!("{}admin", config.root_url)).into())
}
2020-12-17 17:13:11 +01:00
_ => serve_admin(req, config, templates, dbs, &[]).await,
2020-12-17 10:05:26 +01:00
}
} else {
serve_admin_login(
req,
2020-12-17 17:13:11 +01:00
config,
2020-12-17 10:05:26 +01:00
templates,
&[ErrorTemplate {
text: "Mot de passe administrateur invalide",
}],
)
.await
}
2022-02-25 15:41:50 +01:00
} else if let AdminQuery::Login(query) = req.body_form::<AdminQuery>().await? {
2020-12-17 10:05:26 +01:00
if config.admin_passwords.contains(&query.psw) {
2020-12-17 17:13:11 +01:00
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());
2020-12-18 08:39:29 +01:00
if let Some(domain) = &config.cookies_domain {
cookie.set_domain(domain.clone());
}
if config.cookies_https_only {
cookie.set_secure(Some(true));
}
2020-12-17 17:13:11 +01:00
r.insert_cookie(cookie);
r
})
2020-12-17 10:05:26 +01:00
} else {
serve_admin_login(
req,
2020-12-17 17:13:11 +01:00
config,
2020-12-17 10:05:26 +01:00
templates,
&[ErrorTemplate {
text: "Mot de passe administrateur invalide",
}],
)
.await
}
} else {
2020-12-17 17:13:11 +01:00
serve_admin_login(req, config, templates, &[]).await
2020-12-17 10:05:26 +01:00
}
2020-10-26 23:43:18 +01:00
}
2020-12-17 17:13:11 +01:00
async fn handle_admin_logout(
req: tide::Request<()>,
2020-12-17 23:08:31 +01:00
config: Arc<Config>,
2020-12-17 17:13:11 +01:00
) -> tide::Result<tide::Response> {
2020-12-17 10:05:26 +01:00
let mut r: tide::Response = tide::Redirect::new("/").into();
if let Some(mut cookie) = req.cookie("admin") {
2020-12-17 17:13:11 +01:00
cookie.set_path(config.root_url.clone());
2020-12-18 08:39:29 +01:00
if let Some(domain) = &config.cookies_domain {
cookie.set_domain(domain.clone());
}
2020-12-17 10:05:26 +01:00
r.remove_cookie(cookie);
}
Ok(r)
}