diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-09-03 20:38:48 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-09-03 20:38:48 -0400 |
| commit | 289e99ba977ebe6c4599141bc368c17f9905ffcc (patch) | |
| tree | 1dc34400c1284f8246e4bc5f5164b8f805f6cc0a /src/login/routes.rs | |
| parent | b404344a7c4ab5cb6c7d7b445fab796be79b848f (diff) | |
Add logout support.
Diffstat (limited to 'src/login/routes.rs')
| -rw-r--r-- | src/login/routes.rs | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/src/login/routes.rs b/src/login/routes.rs index c9def2a..a00982d 100644 --- a/src/login/routes.rs +++ b/src/login/routes.rs @@ -5,16 +5,20 @@ use axum::{ routing::post, Router, }; -use axum_extra::extract::cookie::{Cookie, CookieJar}; use chrono::Utc; use sqlx::sqlite::SqlitePool; use crate::error::InternalError; -use super::repo::{logins::Provider as _, tokens::Provider as _}; +use super::{ + extract::IdentityToken, + repo::{logins::Provider as _, tokens::Provider as _}, +}; pub fn router() -> Router<SqlitePool> { - Router::new().route("/login", post(on_login)) + Router::new() + .route("/login", post(on_login)) + .route("/logout", post(on_logout)) } #[derive(serde::Deserialize)] @@ -25,10 +29,15 @@ struct Login { async fn on_login( State(db): State<SqlitePool>, - cookies: CookieJar, + identity: IdentityToken, Form(form): Form<Login>, ) -> Result<impl IntoResponse, InternalError> { let now = Utc::now(); + + if identity.token().is_some() { + return Ok((StatusCode::BAD_REQUEST, identity, "already logged in")); + } + let mut tx = db.begin().await?; // Spelling the following in the more conventional form, @@ -59,20 +68,30 @@ async fn on_login( tx.commit().await?; let resp = if let Some(token) = token { - let cookie = Cookie::build(("identity", token)) - .http_only(true) - .permanent() - .build(); - let cookies = cookies.add(cookie); - - (StatusCode::OK, cookies, "logged in") + let identity = identity.set(&token); + (StatusCode::OK, identity, "logged in") } else { ( StatusCode::UNAUTHORIZED, - cookies, + identity, "invalid name or password", ) }; Ok(resp) } + +async fn on_logout( + State(db): State<SqlitePool>, + identity: IdentityToken, +) -> Result<impl IntoResponse, InternalError> { + if let Some(token) = identity.token() { + let mut tx = db.begin().await?; + tx.tokens().revoke(token).await?; + tx.commit().await?; + } + + let identity = identity.clear(); + + Ok((StatusCode::OK, identity, "logged out")) +} |
