log usage #379

Merged
philipp merged 1 commits from usage-stats into staging 2024-04-16 08:53:49 +02:00
3 changed files with 58 additions and 2 deletions
Showing only changes of commit a9f74fcd3c - Show all commits

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ Rocket.toml
frontend/node_modules/* frontend/node_modules/*
/static/ /static/
/data-ergo/ /data-ergo/
usage.txt

View File

@ -3,3 +3,4 @@ secret_key = "/NtVGizglEoyoxBLzsRDWTy4oAG1qDw4J4O+CWJSv+fypD7W9sam8hUY4j90EZsbZk
rss_key = "rss-key-for-ci" rss_key = "rss-key-for-ci"
limits = { file = "10 MiB", data-form = "10 MiB"} limits = { file = "10 MiB", data-form = "10 MiB"}
smtp_pw = "8kIjlLH79Ky6D3jQ" smtp_pw = "8kIjlLH79Ky6D3jQ"
usage_log_path = "./usage.txt"

View File

@ -1,6 +1,9 @@
use std::{fs::OpenOptions, io::Write};
use chrono::Local;
use rocket::{ use rocket::{
catch, catchers, catch, catchers,
fairing::AdHoc, fairing::{AdHoc, Fairing, Info, Kind},
form::Form, form::Form,
fs::FileServer, fs::FileServer,
get, get,
@ -10,7 +13,7 @@ use rocket::{
response::{Flash, Redirect}, response::{Flash, Redirect},
routes, routes,
time::{Duration, OffsetDateTime}, time::{Duration, OffsetDateTime},
Build, FromForm, Request, Rocket, State, Build, Data, FromForm, Request, Rocket, State,
}; };
use rocket_dyn_templates::Template; use rocket_dyn_templates::Template;
use serde::Deserialize; use serde::Deserialize;
@ -100,11 +103,61 @@ fn forbidden_error() -> Flash<Redirect> {
Flash::error(Redirect::to("/"), "Keine Berechtigung für diese Aktion. Wenn du der Meinung bist, dass du das machen darfst, melde dich bitte bei it@rudernlinz.at.") Flash::error(Redirect::to("/"), "Keine Berechtigung für diese Aktion. Wenn du der Meinung bist, dass du das machen darfst, melde dich bitte bei it@rudernlinz.at.")
} }
struct Usage {
data: Vec<String>,
}
#[rocket::async_trait]
impl Fairing for Usage {
fn info(&self) -> Info {
Info {
name: "Usage stats of website",
kind: Kind::Request,
}
}
// Increment the counter for `GET` and `POST` requests.
async fn on_request(&self, req: &mut Request<'_>, _: &mut Data<'_>) {
let timestamp = Local::now().format("%Y-%m-%dT%H:%M:%S");
let user = match req.cookies().get_private("loggedin_user") {
Some(user_id) => match user_id.value().parse::<i32>() {
Ok(user_id) => {
let db = req.rocket().state::<SqlitePool>().unwrap();
if let Some(user) = User::find_by_id(db, user_id).await {
user.name
} else {
format!("USER ID {user_id} NOT EXISTS")
}
}
Err(_) => format!("INVALID USER ID ({user_id})"),
},
None => "NOT LOGGED IN".to_string(),
};
let uri = req.uri().to_string();
if !uri.ends_with(".css") && !uri.ends_with(".js") {
let config = req.rocket().state::<Config>().unwrap();
let mut file = OpenOptions::new()
.write(true)
.append(true)
.open(config.usage_log_path.clone())
.unwrap();
if let Err(e) = writeln!(file, "{timestamp};{user};{uri}") {
eprintln!("Couldn't write to file: {}", e);
}
}
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(crate = "rocket::serde")] #[serde(crate = "rocket::serde")]
pub struct Config { pub struct Config {
rss_key: String, rss_key: String,
smtp_pw: String, smtp_pw: String,
usage_log_path: String,
} }
pub fn config(rocket: Rocket<Build>) -> Rocket<Build> { pub fn config(rocket: Rocket<Build>) -> Rocket<Build> {
@ -127,6 +180,7 @@ pub fn config(rocket: Rocket<Build>) -> Rocket<Build> {
.register("/", catchers![unauthorized_error, forbidden_error]) .register("/", catchers![unauthorized_error, forbidden_error])
.attach(Template::fairing()) .attach(Template::fairing())
.attach(AdHoc::config::<Config>()) .attach(AdHoc::config::<Config>())
.attach(Usage { data: Vec::new() })
} }
#[cfg(test)] #[cfg(test)]