diff --git a/src/auth/mod.rs b/src/auth/mod.rs index 8683ec1..15cde2d 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -83,6 +83,9 @@ impl UserAuthenticator { Self { db, backends } } + /// Attempt to verify credentials against all backends and return the user's most recent token if they match. + /// + /// If a valid token already exists, return it; if not, create a new one. #[instrument] pub async fn get_user_token( &self, @@ -108,12 +111,9 @@ impl UserAuthenticator { return Err(AuthenticationError::InvalidUserOrPassword); }; - // if a valid token exists, return it; if not, create a new one let mut db = self.db.lock().await; let token = if let Some(UserTokenEntry::Valid(old_token, _, _)) = db.get_token(&username).await? { - // TODO: update old_token's last_used value - old_token } else { let new_token = @@ -127,6 +127,9 @@ impl UserAuthenticator { Ok((username, token)) } + /// Check if the passed token matches the user's currently active one. + /// + /// Additionally, update the token's `last_used` value if verification is successful. #[instrument] pub async fn verify_user_token( &self, @@ -137,6 +140,7 @@ impl UserAuthenticator { if let Some(UserTokenEntry::Valid(user_token, ..)) = &db.get_token(username).await? { if token == user_token { + db.update_token_last_used(username, token).await?; return Ok(()); } } diff --git a/src/db.rs b/src/db.rs index d28451b..1e75c43 100644 --- a/src/db.rs +++ b/src/db.rs @@ -28,6 +28,12 @@ pub trait Database: Debug { async fn get_token(&mut self, username: &str) -> Result, sqlx::Error>; async fn save_token(&mut self, username: &str, token: &UserToken) -> Result<(), sqlx::Error>; + + async fn update_token_last_used( + &mut self, + username: &str, + token: &UserToken, + ) -> Result<(), sqlx::Error>; } #[derive(Debug)] @@ -122,4 +128,24 @@ impl Database for SqliteDatabase { Ok(()) } + + #[instrument] + async fn update_token_last_used( + &mut self, + username: &str, + token: &UserToken, + ) -> Result<(), sqlx::Error> { + let token_inner = token.0.expose_secret(); + query!( + "UPDATE user_tokens + SET last_used = DATETIME('NOW') + WHERE username = $1 AND token = $2", + username, + token_inner + ) + .execute(&mut self.conn) + .await?; + + Ok(()) + } }