From 0bbc83f09cc7517dddf16770a15f9e90815f48ba Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Sun, 24 Aug 2025 17:03:16 -0400 Subject: Generate tokens in memory and then store them. This is the leading edge of a larger storage refactoring, where repo types stop doing things like generating secrets or deciding whether to carry out an operation. To make this work, there is now a `Token` type that holds the complete state of a token, in memory. --- src/token/app.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src/token/app.rs') diff --git a/src/token/app.rs b/src/token/app.rs index 8ec61c5..a7a843d 100644 --- a/src/token/app.rs +++ b/src/token/app.rs @@ -6,7 +6,7 @@ use futures::{ use sqlx::sqlite::SqlitePool; use super::{ - Broadcaster, Event as TokenEvent, Id, Secret, + Broadcaster, Event as TokenEvent, Secret, Token, extract::Identity, repo::{self, Provider as _, auth::Provider as _}, }; @@ -48,12 +48,14 @@ impl<'a> Tokens<'a> { // if the account is deleted during that time. tx.commit().await?; - user.as_snapshot().ok_or(LoginError::Rejected)?; + let user = user.as_snapshot().ok_or(LoginError::Rejected)?; if stored_hash.verify(password)? { let mut tx = self.db.begin().await?; - let secret = tx.tokens().issue(&user, login_at).await?; + let (token, secret) = Token::generate(&user, login_at); + tx.tokens().create(&token, &secret).await?; tx.commit().await?; + Ok(secret) } else { Err(LoginError::Rejected) @@ -85,13 +87,16 @@ impl<'a> Tokens<'a> { return Err(LoginError::Rejected); } - user.as_snapshot().ok_or(LoginError::Rejected)?; + let user_snapshot = user.as_snapshot().ok_or(LoginError::Rejected)?; let to_hash = to.hash()?; let mut tx = self.db.begin().await?; - let tokens = tx.tokens().revoke_all(&user).await?; tx.users().set_password(&user, &to_hash).await?; - let secret = tx.tokens().issue(&user, changed_at).await?; + + let tokens = tx.tokens().revoke_all(&user).await?; + let (token, secret) = Token::generate(&user_snapshot, changed_at); + tx.tokens().create(&token, &secret).await?; + tx.commit().await?; for event in tokens.into_iter().map(TokenEvent::Revoked) { @@ -121,13 +126,15 @@ impl<'a> Tokens<'a> { pub async fn limit_stream( &self, - token: Id, + token: &Token, events: S, ) -> Result + std::fmt::Debug + use, ValidateError> where S: Stream + std::fmt::Debug, E: std::fmt::Debug, { + let token = token.id.clone(); + // Subscribe, first. let token_events = self.token_events.subscribe(); @@ -188,13 +195,13 @@ impl<'a> Tokens<'a> { Ok(()) } - pub async fn logout(&self, token: &Id) -> Result<(), ValidateError> { + pub async fn logout(&self, token: &Token) -> Result<(), ValidateError> { let mut tx = self.db.begin().await?; tx.tokens().revoke(token).await?; tx.commit().await?; self.token_events - .broadcast(TokenEvent::Revoked(token.clone())); + .broadcast(TokenEvent::Revoked(token.id.clone())); Ok(()) } -- cgit v1.2.3