832 lines
22 KiB
Rust
832 lines
22 KiB
Rust
use super::{cli, config::*, db::*, queries::*, static_files, templates::*, utils::*};
|
|
|
|
use argon2::{
|
|
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
|
Argon2,
|
|
};
|
|
use handlebars::to_json;
|
|
use std::{convert::TryFrom, sync::Arc};
|
|
|
|
pub async fn start_server(
|
|
config: Config,
|
|
dbs: Dbs,
|
|
templates: Templates<'static>,
|
|
opt: cli::MainOpt,
|
|
) {
|
|
tide::log::start();
|
|
|
|
let templates = Arc::new(templates);
|
|
let config = Arc::new(config);
|
|
|
|
let mut app = tide::new();
|
|
app.at(&format!("{}static", config.root_url))
|
|
.serve_dir(opt.dir.0.join(static_files::STATIC_DIR))
|
|
.unwrap();
|
|
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,
|
|
config.clone(),
|
|
templates.clone(),
|
|
dbs.clone(),
|
|
&[],
|
|
None,
|
|
)
|
|
}
|
|
});
|
|
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, config.clone(), templates.clone(), dbs.clone())
|
|
}
|
|
});
|
|
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", 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())
|
|
}
|
|
});
|
|
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())
|
|
}
|
|
});
|
|
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())
|
|
}
|
|
});
|
|
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,
|
|
config.clone(),
|
|
templates.clone(),
|
|
dbs.clone(),
|
|
&[],
|
|
None,
|
|
)
|
|
}
|
|
});
|
|
app.at(&format!("{}admin", 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())
|
|
}
|
|
});
|
|
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())
|
|
}
|
|
});
|
|
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())
|
|
}
|
|
});
|
|
app.at(&format!("{}admin", 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())
|
|
}
|
|
});
|
|
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())
|
|
}
|
|
});
|
|
app.at(&format!("{}admin/ad/:ad", config.root_url)).post({
|
|
let config = config.clone();
|
|
move |req: tide::Request<()>| {
|
|
handle_post_admin(req, config.clone(), templates.clone(), dbs.clone())
|
|
}
|
|
});
|
|
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<Config>,
|
|
templates: Arc<Templates<'static>>,
|
|
dbs: Dbs,
|
|
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 {
|
|
common: CommonTemplate::new(&config, errors),
|
|
ads: &to_json(
|
|
dbs.ad_by_group
|
|
.scan_prefix(ROOT_GROUP_ID)
|
|
.filter_map(|x| {
|
|
let (k, _) = x.ok()?;
|
|
let ad_id = AdId::try_from(&k.as_ref()[16..32]).ok()?;
|
|
let ad_id_hex = hex::encode(&ad_id);
|
|
Some(AdWithId {
|
|
ad: bincode::deserialize::<Ad>(
|
|
&dbs.ad.get(&ad_id).unwrap()?,
|
|
)
|
|
.ok()?,
|
|
selected: selected_ad.map_or(false, |i| i == ad_id_hex),
|
|
id: ad_id_hex,
|
|
})
|
|
})
|
|
.collect::<Vec<AdWithId>>(),
|
|
),
|
|
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>>(),
|
|
),
|
|
new_ad_form_refill,
|
|
},
|
|
)
|
|
.unwrap_or_else(|e| e.to_string()),
|
|
)
|
|
.build())
|
|
}
|
|
|
|
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() {
|
|
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(
|
|
"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, _) = x.ok()?;
|
|
let ad_id =
|
|
AdId::try_from(&k.as_ref()[16..32]).ok()?;
|
|
let ad_id_hex = hex::encode(&ad_id);
|
|
Some(AdWithId {
|
|
ad: bincode::deserialize::<Ad>(
|
|
&dbs.ad.get(&ad_id).unwrap()?,
|
|
)
|
|
.ok()?,
|
|
selected: selected_ad
|
|
.map_or(false, |i| i == ad_id_hex),
|
|
id: ad_id_hex,
|
|
})
|
|
})
|
|
.collect::<Vec<AdWithId>>(),
|
|
),
|
|
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,
|
|
)
|
|
}),
|
|
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()),
|
|
)
|
|
.build());
|
|
}
|
|
}
|
|
}
|
|
serve_index(
|
|
req,
|
|
config,
|
|
templates,
|
|
dbs,
|
|
&[ErrorTemplate {
|
|
text: "Le groupe demandé n'existe pas.",
|
|
}],
|
|
None,
|
|
)
|
|
.await
|
|
} 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 {
|
|
common: CommonTemplate::new(&config, errors),
|
|
ads: &to_json(
|
|
dbs.ad_by_group
|
|
.scan_prefix(group_id.clone())
|
|
.filter_map(|x| {
|
|
let (k, _) = x.ok()?;
|
|
let ad_id =
|
|
AdId::try_from(&k.as_ref()[16..32]).ok()?;
|
|
let ad_id_hex = hex::encode(&ad_id);
|
|
Some(AdWithId {
|
|
ad: bincode::deserialize::<Ad>(
|
|
&dbs.ad.get(&ad_id).unwrap()?,
|
|
)
|
|
.ok()?,
|
|
selected: selected_ad
|
|
.map_or(false, |i| i == ad_id_hex),
|
|
id: ad_id_hex,
|
|
})
|
|
})
|
|
.collect::<Vec<AdWithId>>(),
|
|
),
|
|
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,
|
|
)
|
|
}),
|
|
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
|
|
}
|
|
}
|
|
|
|
async fn serve_admin<'a>(
|
|
req: tide::Request<()>,
|
|
config: Arc<Config>,
|
|
templates: Arc<Templates<'static>>,
|
|
dbs: Dbs,
|
|
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 {
|
|
common: CommonTemplate::new(&config, errors),
|
|
ads: &to_json(
|
|
dbs.ad_by_group
|
|
.scan_prefix(ROOT_GROUP_ID)
|
|
.filter_map(|x| {
|
|
let (k, _) = x.ok()?;
|
|
let ad_id = AdId::try_from(&k.as_ref()[16..32]).ok()?;
|
|
let ad_id_hex = hex::encode(&ad_id);
|
|
Some(AdWithId {
|
|
ad: bincode::deserialize::<Ad>(
|
|
&dbs.ad.get(&ad_id).unwrap()?,
|
|
)
|
|
.ok()?,
|
|
selected: selected_ad.map_or(false, |i| i == ad_id_hex),
|
|
id: ad_id_hex,
|
|
})
|
|
})
|
|
.collect::<Vec<AdWithId>>(),
|
|
),
|
|
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>>(),
|
|
),
|
|
},
|
|
)
|
|
.unwrap_or_else(|e| e.to_string()),
|
|
)
|
|
.build())
|
|
}
|
|
|
|
async fn serve_admin_login<'a>(
|
|
_req: tide::Request<()>,
|
|
config: Arc<Config>,
|
|
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",
|
|
&AdminLoginTemplate {
|
|
common: CommonTemplate::new(&config, errors),
|
|
},
|
|
)
|
|
.unwrap_or_else(|e| e.to_string()),
|
|
)
|
|
.build())
|
|
}
|
|
|
|
async fn handle_post_index(
|
|
mut req: tide::Request<()>,
|
|
config: Arc<Config>,
|
|
templates: Arc<Templates<'static>>,
|
|
dbs: Dbs,
|
|
) -> tide::Result<tide::Response> {
|
|
match req.body_form::<IndexQuery>().await? {
|
|
IndexQuery::NewAd(query) => {
|
|
handle_new_ad(req, config.clone(), templates.clone(), dbs.clone(), query).await
|
|
}
|
|
IndexQuery::RmAd(query) => {
|
|
handle_rm_ad(req, config.clone(), templates.clone(), dbs.clone(), query).await
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn handle_new_ad(
|
|
req: tide::Request<()>,
|
|
config: Arc<Config>,
|
|
templates: Arc<Templates<'static>>,
|
|
dbs: Dbs,
|
|
query: NewAdQuery,
|
|
) -> tide::Result<tide::Response> {
|
|
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()))
|
|
} {
|
|
let ad_id = AdId::random();
|
|
dbs.ad
|
|
.insert(
|
|
ad_id.clone(),
|
|
bincode::serialize(&Ad {
|
|
pubkey: if query.pubkey.is_empty() {
|
|
None
|
|
} else {
|
|
Some(match format_pubkey(&query.pubkey) {
|
|
Ok(pubkey) => pubkey,
|
|
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
|
|
}
|
|
})
|
|
},
|
|
author: query.author,
|
|
password: Argon2::default()
|
|
.hash_password(query.psw.as_bytes(), &SaltString::generate(&mut OsRng))
|
|
.unwrap()
|
|
.to_string(),
|
|
price: query.price,
|
|
quantity: query.quantity,
|
|
time: 0,
|
|
title: query.title,
|
|
})
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
dbs.ad_by_group
|
|
.insert([group_id, ad_id.0].concat(), &[])
|
|
.unwrap();
|
|
dbs.ad.flush_async().await.unwrap();
|
|
}
|
|
Ok(tide::Redirect::new(&config.root_url).into())
|
|
}
|
|
|
|
async fn handle_rm_ad(
|
|
req: tide::Request<()>,
|
|
config: Arc<Config>,
|
|
templates: Arc<Templates<'static>>,
|
|
dbs: Dbs,
|
|
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()) {
|
|
if let Some(raw) = dbs.ad.get(&ad_id).unwrap() {
|
|
if let Ok(ad) = bincode::deserialize::<Ad>(&raw) {
|
|
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();
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Ok(tide::Redirect::new(&config.root_url).into())
|
|
}
|
|
|
|
async fn handle_admin(
|
|
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(req, config, templates, dbs, &[]).await
|
|
} else {
|
|
serve_admin_login(
|
|
req,
|
|
config,
|
|
templates,
|
|
&[ErrorTemplate {
|
|
text: "Mot de passe administrateur invalide",
|
|
}],
|
|
)
|
|
.await
|
|
}
|
|
} else {
|
|
serve_admin_login(req, config, templates, &[]).await
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
async fn handle_post_admin(
|
|
mut 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())) {
|
|
match req.body_form::<AdminQuery>().await? {
|
|
AdminQuery::RmAd(query) => {
|
|
if let Ok(ad_id) = hex::decode(query.ad) {
|
|
if let Ok(ad_id) = AdId::try_from(ad_id.as_ref()) {
|
|
dbs.ad.remove(&ad_id).unwrap();
|
|
|
|
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());
|
|
}
|
|
return Ok(tide::Redirect::new(&format!(
|
|
"{}admin/g/{}",
|
|
config.root_url, query.parent
|
|
))
|
|
.into());
|
|
}
|
|
Ok(tide::Redirect::new(&format!("{}admin", config.root_url)).into())
|
|
}
|
|
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())
|
|
}
|
|
_ => serve_admin(req, config, templates, dbs, &[]).await,
|
|
}
|
|
} else {
|
|
serve_admin_login(
|
|
req,
|
|
config,
|
|
templates,
|
|
&[ErrorTemplate {
|
|
text: "Mot de passe administrateur invalide",
|
|
}],
|
|
)
|
|
.await
|
|
}
|
|
} else if let AdminQuery::Login(query) = req.body_form::<AdminQuery>().await? {
|
|
if config.admin_passwords.contains(&query.psw) {
|
|
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());
|
|
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
|
|
})
|
|
} else {
|
|
serve_admin_login(
|
|
req,
|
|
config,
|
|
templates,
|
|
&[ErrorTemplate {
|
|
text: "Mot de passe administrateur invalide",
|
|
}],
|
|
)
|
|
.await
|
|
}
|
|
} else {
|
|
serve_admin_login(req, config, templates, &[]).await
|
|
}
|
|
}
|
|
|
|
async fn handle_admin_logout(
|
|
req: tide::Request<()>,
|
|
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)
|
|
}
|