diff options
Diffstat (limited to 'src/token/repo/token.rs')
| -rw-r--r-- | src/token/repo/token.rs | 97 |
1 files changed, 40 insertions, 57 deletions
diff --git a/src/token/repo/token.rs b/src/token/repo/token.rs index 7ac4ac5..52a3987 100644 --- a/src/token/repo/token.rs +++ b/src/token/repo/token.rs @@ -1,13 +1,11 @@ use sqlx::{SqliteConnection, Transaction, sqlite::Sqlite}; -use uuid::Uuid; use crate::{ clock::DateTime, db::NotFound, - event::{Instant, Sequence}, + login::{self, Login}, name::{self, Name}, - token::{Id, Secret}, - user::{self, History, User}, + token::{Id, Secret, Token}, }; pub trait Provider { @@ -23,33 +21,23 @@ impl Provider for Transaction<'_, Sqlite> { pub struct Tokens<'t>(&'t mut SqliteConnection); impl Tokens<'_> { - // Issue a new token for an existing user. The issued_at timestamp will - // determine the token's initial expiry deadline. - pub async fn issue( - &mut self, - user: &History, - issued_at: &DateTime, - ) -> Result<Secret, sqlx::Error> { - let id = Id::generate(); - let secret = Uuid::new_v4().to_string(); - let user = user.id(); - - let secret = sqlx::query_scalar!( + pub async fn create(&mut self, token: &Token, secret: &Secret) -> Result<(), sqlx::Error> { + sqlx::query!( r#" insert - into token (id, secret, user, issued_at, last_used_at) - values ($1, $2, $3, $4, $4) - returning secret as "secret!: Secret" + into token (id, secret, login, issued_at, last_used_at) + values ($1, $2, $3, $4, $5) "#, - id, + token.id, secret, - user, - issued_at, + token.login, + token.issued_at, + token.last_used_at, ) - .fetch_one(&mut *self.0) + .execute(&mut *self.0) .await?; - Ok(secret) + Ok(()) } pub async fn require(&mut self, token: &Id) -> Result<(), sqlx::Error> { @@ -67,34 +55,30 @@ impl Tokens<'_> { Ok(()) } - // Revoke a token by its secret. - pub async fn revoke(&mut self, token: &Id) -> Result<(), sqlx::Error> { - sqlx::query_scalar!( + pub async fn revoke(&mut self, token: &Token) -> Result<(), sqlx::Error> { + sqlx::query!( r#" - delete - from token + delete from token where id = $1 - returning id as "id: Id" "#, - token, + token.id, ) - .fetch_one(&mut *self.0) + .execute(&mut *self.0) .await?; Ok(()) } // Revoke tokens for a login - pub async fn revoke_all(&mut self, user: &user::History) -> Result<Vec<Id>, sqlx::Error> { - let user = user.id(); + pub async fn revoke_all(&mut self, login: &Login) -> Result<Vec<Id>, sqlx::Error> { let tokens = sqlx::query_scalar!( r#" delete from token - where user = $1 + where login = $1 returning id as "id: Id" "#, - user, + login.id, ) .fetch_all(&mut *self.0) .await?; @@ -120,54 +104,53 @@ impl Tokens<'_> { Ok(tokens) } - // Validate a token by its secret, retrieving the associated Login record. - // Will return an error if the token is not valid. If successful, the - // retrieved token's last-used timestamp will be set to `used_at`. pub async fn validate( &mut self, secret: &Secret, used_at: &DateTime, - ) -> Result<(Id, History), LoadError> { + ) -> Result<(Token, Login), LoadError> { // I would use `update … returning` to do this in one query, but // sqlite3, as of this writing, does not allow an update's `returning` // clause to reference columns from tables joined into the update. Two // queries is fine, but it feels untidy. - let (token, user) = sqlx::query!( + let token = sqlx::query!( r#" update token set last_used_at = $1 where secret = $2 returning - id as "token: Id", - user as "user: user::Id" + id as "id: Id", + login as "login: login::Id", + issued_at as "issued_at: DateTime", + last_used_at as "last_used_at: DateTime" "#, used_at, secret, ) - .map(|row| (row.token, row.user)) + .map(|row| Token { + id: row.id, + login: row.login, + issued_at: row.issued_at, + last_used_at: row.last_used_at, + }) .fetch_one(&mut *self.0) .await?; let user = sqlx::query!( r#" select - id as "id: user::Id", - display_name as "display_name: String", - canonical_name as "canonical_name: String", - created_sequence as "created_sequence: Sequence", - created_at as "created_at: DateTime" - from user + id as "id: login::Id", + display_name, + canonical_name + from login where id = $1 "#, - user, + token.login, ) .map(|row| { - Ok::<_, name::Error>(History { - user: User { - id: row.id, - name: Name::new(row.display_name, row.canonical_name)?, - }, - created: Instant::new(row.created_at, row.created_sequence), + Ok::<_, name::Error>(Login { + id: row.id, + name: Name::new(row.display_name, row.canonical_name)?, }) }) .fetch_one(&mut *self.0) |
