Hash admin passwords

This commit is contained in:
Pascal Engélibert 2022-10-15 17:32:35 +02:00
commit 86495543ce
Signed by: tuxmain
GPG key ID: 3504BC6D362F7DCA
7 changed files with 106 additions and 7 deletions

View file

@ -1,5 +1,6 @@
use crate::{config::*, db::*, helpers, queries::*, templates::*};
use argon2::{Argon2, PasswordHash, PasswordVerifier};
use log::error;
use std::sync::Arc;
use tera::Context;
@ -54,7 +55,7 @@ async fn serve_comments<'a>(
};
let admin = req.cookie("admin").map_or(false, |psw| {
config.admin_passwords.contains(&String::from(psw.value()))
check_admin_password_hash(&config, &String::from(psw.value()))
});
let topic_hash = TopicHash::from_topic(topic);
@ -127,9 +128,9 @@ async fn serve_admin<'a>(
&dbs.comment_pending
.iter()
.filter_map(|entry| {
let ((_topic_hash, _time, comment_id), ()) = dbg!(entry
let ((_topic_hash, _time, comment_id), ()) = entry
.map_err(|e| error!("Reading comment_pending: {:?}", e))
.ok()?);
.ok()?;
let comment = dbs
.comment
.get(&comment_id)
@ -227,7 +228,7 @@ async fn handle_post_admin(
dbs: Dbs,
) -> tide::Result<tide::Response> {
if let Some(psw) = req.cookie("admin") {
if config.admin_passwords.contains(&String::from(psw.value())) {
if check_admin_password(&config, &String::from(psw.value())).is_some() {
match req.body_form::<AdminQuery>().await? {
_ => serve_admin(req, config, templates, dbs).await,
}
@ -235,11 +236,11 @@ async fn handle_post_admin(
serve_admin_login(req, config, templates).await
}
} else if let AdminQuery::Login(query) = req.body_form::<AdminQuery>().await? {
if config.admin_passwords.contains(&query.psw) {
if let Some(password_hash) = check_admin_password(&config, &query.psw) {
serve_admin(req, config.clone(), templates, dbs)
.await
.map(|mut r| {
let mut cookie = tide::http::Cookie::new("admin", query.psw);
let mut cookie = tide::http::Cookie::new("admin", password_hash);
cookie.set_http_only(Some(true));
cookie.set_path(config.root_url.clone());
if let Some(domain) = &config.cookies_domain {
@ -258,3 +259,21 @@ async fn handle_post_admin(
serve_admin_login(req, config, templates).await
}
}
fn check_admin_password(config: &Config, password: &str) -> Option<String> {
let argon2 = Argon2::default();
config
.admin_passwords
.iter()
.filter_map(|admin_password| PasswordHash::new(admin_password).ok())
.find(|admin_password| {
argon2
.verify_password(password.as_bytes(), admin_password)
.is_ok()
})
.map(|password_hash| password_hash.to_string())
}
fn check_admin_password_hash(config: &Config, password_hash: &str) -> bool {
config.admin_passwords.iter().any(|h| h == password_hash)
}