Mercurial > lbo > hg > analyrics
changeset 5:2101c91aad43
Implement session handling
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sat, 09 Jul 2022 16:25:07 -0700 |
parents | 7e94d639963c |
children | 204877b11751 |
files | Cargo.toml src/main.rs |
diffstat | 2 files changed, 45 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/Cargo.toml Sat Jul 09 13:22:42 2022 -0700 +++ b/Cargo.toml Sat Jul 09 16:25:07 2022 -0700 @@ -14,4 +14,5 @@ rocket_db_pools = { version = "0.1.0-rc.2", features = ["sqlx_sqlite"] } rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["handlebars"] } sha256 = "1.0.3" +time = "0.3.11" tokio = { version = "1.19.2", features = ["fs"] }
--- a/src/main.rs Sat Jul 09 13:22:42 2022 -0700 +++ b/src/main.rs Sat Jul 09 16:25:07 2022 -0700 @@ -56,6 +56,7 @@ S6: AsRef<str>, >( conn: &mut PoolConnection<Sqlite>, + session: Option<u32>, ip: S1, domain: S2, path: S3, @@ -65,8 +66,9 @@ ua: S6, ntags: u32, ) -> Result<u32, Error> { - let q = sqlx::query("INSERT INTO RequestLog (ip, atime, domain, path, status, pagename, refer, ua, ntags) VALUES (?, strftime('%s', 'now'), ?, ?, ?, ?, ?, ?, ?) RETURNING id"); + let q = sqlx::query("INSERT INTO RequestLog (session, ip, atime, domain, path, status, pagename, refer, ua, ntags) VALUES (?, ?, strftime('%s', 'now'), ?, ?, ?, ?, ?, ?, ?) RETURNING id"); let q = q + .bind(session) .bind(ip.as_ref()) .bind(domain.as_ref()) .bind(path.as_ref()) @@ -101,6 +103,20 @@ Ok(ntags) } +async fn start_session(conn: &mut PoolConnection<Sqlite>) -> Result<u32, Error> { + Ok(sqlx::query("INSERT INTO Sessions (start, last) VALUES (strftime('%s', 'now'), strftime('%s', 'now')) RETURNING id") + .fetch_one(conn) + .await?.get(0)) +} + +async fn update_session_time(conn: &mut PoolConnection<Sqlite>, id: u32) -> Result<(), Error> { + sqlx::query("UPDATE Sessions SET last = strftime('%s', 'now') WHERE id = ?") + .bind(id) + .execute(conn) + .await?; + Ok(()) +} + const USER_ID_COOKIE_KEY: &str = "user_id"; struct LoggedInGuard(String); @@ -235,7 +251,8 @@ // TODO: ignore requests when logged in. #[rocket::get("/log?<host>&<status>&<path>&<pagename>&<referer>&<tags>")] async fn route_log( - conn: Connection<LogsDB>, + mut conn: Connection<LogsDB>, + cookies: &CookieJar<'_>, host: Option<String>, status: Option<u16>, path: Option<String>, @@ -245,6 +262,30 @@ ip: IpAddr, headers: HeadersGuard<'_>, ) -> (Status, Either<NamedFile, &'static str>) { + let mut session_id = None; + // Get session ID from cookie, or start new session. + if let Some(sessioncookie) = cookies.get_private("analyrics_session") { + if let Ok(id) = u32::from_str_radix(sessioncookie.value(), 10) { + session_id = Some(id); + match update_session_time(&mut conn, id).await { + Ok(()) => {} + Err(e) => error!("Couldn't update session time: {}", e), + } + } + } + if session_id.is_none() { + match start_session(&mut conn).await { + Ok(id) => { + session_id = Some(id); + let c = Cookie::build("analyrics_session", id.to_string()) + .max_age(time::Duration::hours(12)) + .finish(); + cookies.add_private(c); + } + Err(e) => error!("Couldn't start session: {}", e), + } + } + let mut conn = conn.into_inner(); let ntags = tags.len() as u32; let ua = headers.0.get_one("user-agent").unwrap_or(""); @@ -260,6 +301,7 @@ ); match log_request( &mut conn, + session_id, ip.to_string(), host, path.unwrap_or(String::new()),