diff options
Diffstat (limited to 'src/token/repo')
| -rw-r--r-- | src/token/repo/auth.rs | 105 | ||||
| -rw-r--r-- | src/token/repo/mod.rs | 1 | ||||
| -rw-r--r-- | src/token/repo/token.rs | 43 |
3 files changed, 16 insertions, 133 deletions
diff --git a/src/token/repo/auth.rs b/src/token/repo/auth.rs deleted file mode 100644 index a42fa1a..0000000 --- a/src/token/repo/auth.rs +++ /dev/null @@ -1,105 +0,0 @@ -use sqlx::{SqliteConnection, Transaction, sqlite::Sqlite}; - -use crate::{ - clock::DateTime, - db::NotFound, - event::{Instant, Sequence}, - name::{self, Name}, - password::StoredHash, - user::{self, History, User}, -}; - -pub trait Provider { - fn auth(&mut self) -> Auth<'_>; -} - -impl Provider for Transaction<'_, Sqlite> { - fn auth(&mut self) -> Auth<'_> { - Auth(self) - } -} - -pub struct Auth<'t>(&'t mut SqliteConnection); - -impl Auth<'_> { - pub async fn for_name(&mut self, name: &Name) -> Result<(History, StoredHash), LoadError> { - let name = name.canonical(); - let row = sqlx::query!( - r#" - select - id as "id: user::Id", - login.display_name as "display_name: String", - login.canonical_name as "canonical_name: String", - user.created_sequence as "created_sequence: Sequence", - user.created_at as "created_at: DateTime", - login.password as "password: StoredHash" - from user - join login using (id) - where login.canonical_name = $1 - "#, - name, - ) - .fetch_one(&mut *self.0) - .await?; - - let login = 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((login, row.password)) - } - - pub async fn for_user(&mut self, user: &User) -> Result<(History, StoredHash), LoadError> { - let row = sqlx::query!( - r#" - select - id as "id: user::Id", - login.display_name as "display_name: String", - login.canonical_name as "canonical_name: String", - user.created_sequence as "created_sequence: Sequence", - user.created_at as "created_at: DateTime", - login.password as "password: StoredHash" - from user - join login using (id) - where id = $1 - "#, - user.id, - ) - .fetch_one(&mut *self.0) - .await?; - - let user = 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((user, row.password)) - } -} - -#[derive(Debug, thiserror::Error)] -#[error(transparent)] -pub enum LoadError { - Database(#[from] sqlx::Error), - Name(#[from] name::Error), -} - -impl<T> NotFound for Result<T, LoadError> { - type Ok = T; - type Error = LoadError; - - fn optional(self) -> Result<Option<T>, LoadError> { - match self { - Ok(value) => Ok(Some(value)), - Err(LoadError::Database(sqlx::Error::RowNotFound)) => Ok(None), - Err(other) => Err(other), - } - } -} diff --git a/src/token/repo/mod.rs b/src/token/repo/mod.rs index d8463eb..9df5bbb 100644 --- a/src/token/repo/mod.rs +++ b/src/token/repo/mod.rs @@ -1,4 +1,3 @@ -pub mod auth; mod token; pub use self::token::{LoadError, Provider}; diff --git a/src/token/repo/token.rs b/src/token/repo/token.rs index afcde53..52a3987 100644 --- a/src/token/repo/token.rs +++ b/src/token/repo/token.rs @@ -3,10 +3,9 @@ use sqlx::{SqliteConnection, Transaction, sqlite::Sqlite}; use crate::{ clock::DateTime, db::NotFound, - event::{Instant, Sequence}, + login::{self, Login}, name::{self, Name}, token::{Id, Secret, Token}, - user::{self, History, User}, }; pub trait Provider { @@ -31,11 +30,11 @@ impl Tokens<'_> { "#, token.id, secret, - token.user, + token.login, token.issued_at, token.last_used_at, ) - .fetch_one(&mut *self.0) + .execute(&mut *self.0) .await?; Ok(()) @@ -71,8 +70,7 @@ impl Tokens<'_> { } // 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 @@ -80,7 +78,7 @@ impl Tokens<'_> { where login = $1 returning id as "id: Id" "#, - user, + login.id, ) .fetch_all(&mut *self.0) .await?; @@ -106,14 +104,11 @@ 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<(Token, 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 @@ -125,7 +120,7 @@ impl Tokens<'_> { where secret = $2 returning id as "id: Id", - login as "login: user::Id", + login as "login: login::Id", issued_at as "issued_at: DateTime", last_used_at as "last_used_at: DateTime" "#, @@ -134,7 +129,7 @@ impl Tokens<'_> { ) .map(|row| Token { id: row.id, - user: row.login, + login: row.login, issued_at: row.issued_at, last_used_at: row.last_used_at, }) @@ -144,24 +139,18 @@ impl Tokens<'_> { let user = sqlx::query!( r#" select - id as "id: user::Id", - login.display_name as "display_name: String", - login.canonical_name as "canonical_name: String", - user.created_sequence as "created_sequence: Sequence", - user.created_at as "created_at: DateTime" - from user - join login using (id) + id as "id: login::Id", + display_name, + canonical_name + from login where id = $1 "#, - token.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) |
