implemented audit logs to syslog

This commit is contained in:
Artemis 2025-01-27 20:17:54 +01:00
parent f7da45312a
commit 755be599ee
3 changed files with 101 additions and 20 deletions

View file

@ -1,3 +1,5 @@
use std::net::IpAddr;
use rocket::{
form::{self, Contextual, Error, Form},
http::CookieJar,
@ -64,6 +66,7 @@ pub async fn change_settings(
user: User,
meta: CommonTemplateState,
mut form: Form<Contextual<'_, CommonSettings<'_>>>,
client_ip: IpAddr,
) -> PageResult {
let values = match form.value {
Some(ref v) => v,
@ -110,6 +113,13 @@ pub async fn change_settings(
user::update_info(&mut *db, &user.id, new_username, new_email).await?;
info!(
"[audit|{}] [{}] changed username/email (from {})",
client_ip,
user.id.to_string(),
user.username,
);
Ok(Redirect::to(uri!("/account", show_settings)).into())
}
@ -138,6 +148,7 @@ pub async fn change_password(
user: User,
meta: CommonTemplateState,
mut form: Form<Contextual<'_, PasswordSettings<'_>>>,
client_ip: IpAddr,
) -> PageResult {
let values = match form.value {
Some(ref v) => v,
@ -178,6 +189,12 @@ pub async fn change_password(
let new_password_hash = task::spawn_blocking(move || pw::hash(&new_password)).await??;
user::update_password(&mut *db, &user.id, &new_password_hash).await?;
info!(
"[audit|{}] [{}] changed password",
client_ip,
user.id.to_string()
);
Ok(Redirect::to(uri!("/account", show_settings)).into())
}
@ -190,10 +207,20 @@ pub struct DataDump {
}
#[get("/data_dump")]
pub async fn export_data(mut db: DollTagsDb, user: User) -> RawResult<Json<DataDump>> {
pub async fn export_data(
mut db: DollTagsDb,
user: User,
client_ip: IpAddr,
) -> RawResult<Json<DataDump>> {
let tags = doll::list(&mut *db, &user.id).await?;
let reserved_tags = doll::list_archived(&mut *db, &user.id).await?;
info!(
"[audit|{}] [{}] exported data",
client_ip,
user.id.to_string()
);
Ok(Json(DataDump {
account: user,
tags,
@ -225,10 +252,23 @@ pub async fn ask_delete(
}
#[get("/yes_delete_this/<id>")]
pub async fn confirm_delete(mut db: DollTagsDb, id: i32, _user: User) -> PageResult {
pub async fn confirm_delete(
mut db: DollTagsDb,
id: i32,
user: User,
client_ip: IpAddr,
) -> PageResult {
let mut trx = db.begin().await?;
doll::delete(&mut trx, id).await?;
trx.commit().await?;
info!(
"[audit|{}] [{}] deleted tag {:0>6}",
client_ip,
user.id.to_string(),
id
);
Ok(Redirect::to(uri!("/account", index)).into())
}
@ -242,6 +282,7 @@ pub async fn confirm_terminate_account(
mut db: DollTagsDb,
user: User,
cookies: &CookieJar<'_>,
client_ip: IpAddr,
) -> PageResult {
let mut trx = db.begin().await?;
doll::delete_all_from_account(&mut trx, &user.id).await?;
@ -249,5 +290,11 @@ pub async fn confirm_terminate_account(
session::logout(cookies);
trx.commit().await?;
info!(
"[audit|{}] [{}] deleted account",
client_ip,
user.id.to_string()
);
Ok(Redirect::to("/").into())
}

View file

@ -1,3 +1,5 @@
use std::net::IpAddr;
use regex::Regex;
use rocket::{
form::{self, Contextual, Form},
@ -49,24 +51,32 @@ pub async fn handle_login(
cookies: &CookieJar<'_>,
maybe_loggedin: Option<User>,
meta: CommonTemplateState,
client_ip: IpAddr,
) -> PageResult {
if maybe_loggedin.is_some() {
let next = String::from(next.unwrap_or("/"));
return Ok(Redirect::to(next).into());
}
let miss = || {
PageResponse::Page(Template::render(
"account/login",
context! {failure: true, meta},
))
};
let values = match &form.value {
None => return Ok(miss()),
None => {
return Ok(Template::render("account/login", context! {failure: true, meta}).into())
}
Some(v) => v,
};
let miss = (|username: String| {
move || {
info!("[audit|{}] login failure ({})", client_ip, username);
PageResponse::Page(Template::render(
"account/login",
context! {failure: true, meta},
))
}
})(String::from(values.username));
info!("[audit|{}] login attempt ({})", client_ip, &values.username);
let user_in_db = user::get(db, &values.username).await?;
let user = match user_in_db {
None => return Ok(miss()),
@ -79,6 +89,12 @@ pub async fn handle_login(
if right_password && user.enabled {
session::login(cookies, &user.id);
info!(
"[audit|{}] [{}] login successful ({})",
client_ip,
user.id.to_string(),
&values.username
);
let next_url = String::from(next.unwrap_or("/"));
Ok(Redirect::to(next_url).into())
} else {
@ -137,6 +153,7 @@ pub async fn handle_register(
cookies: &CookieJar<'_>,
maybe_loggedin: Option<User>,
meta: CommonTemplateState,
client_ip: IpAddr,
) -> PageResult {
if maybe_loggedin.is_some() {
return Ok(Redirect::to("/").into());
@ -161,11 +178,6 @@ pub async fn handle_register(
}
};
debug!(
"registering account {} ({:?})",
values.username, values.email
);
let password = String::from(values.password);
let hashed_password = task::spawn_blocking(move || pw::hash(&password)).await??;
@ -181,6 +193,11 @@ pub async fn handle_register(
)
.await?;
info!(
"[audit|{}] [{}] account creation",
client_ip,
&account_id.to_string()
);
session::login(cookies, &account_id);
Ok(Redirect::to(uri!("/")).into())

View file

@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::{collections::HashMap, net::IpAddr};
use rocket::{
form::{self, Contextual, Form},
@ -172,6 +172,7 @@ pub async fn handle_register(
tag: Form<Contextual<'_, TagForm<'_>>>,
user: User,
meta: CommonTemplateState,
client_ip: IpAddr,
) -> PageResult {
let tag = match tag.value {
Some(ref values) => values,
@ -194,7 +195,6 @@ pub async fn handle_register(
}
};
debug!("registering tag: {:?}", tag);
fn normalize_opt(opt: &str) -> Option<&str> {
if opt.len() != 0 {
Some(opt)
@ -208,10 +208,11 @@ pub async fn handle_register(
let microchip_id = normalize_opt(&normalized_microchip_id);
if doll::id_exists(&mut *db, id, microchip_id.unwrap_or("")).await? {
// TODO: that's weird... what was i expecting to do here?
return Ok(Redirect::found(uri!("/account", show_register)).into());
}
doll::create(
let creation_status = doll::create(
&mut *db,
CreateDollProfile {
id,
@ -232,7 +233,24 @@ pub async fn handle_register(
bound_to_id: &user.id,
},
)
.await?;
.await;
if creation_status.is_err() {
info!(
"[audit|{}] [{}] failed to register tag {}",
client_ip,
user.id.to_string(),
tag.ident
);
}
creation_status?;
info!(
"[audit|{}] [{}] registered tag {}",
client_ip,
user.id.to_string(),
tag.ident
);
Ok(Redirect::to(uri!(public::show_profile(Some(tag.ident), microchip_id))).into())
}
@ -267,7 +285,6 @@ pub async fn handle_edit_tag(
}
};
debug!("editing tag: {:?}", tag);
fn normalize_opt(opt: &str) -> Option<&str> {
if opt.len() != 0 {
Some(opt)