diff options
Diffstat (limited to 'src/login/repo/tokens.rs')
| -rw-r--r-- | src/login/repo/tokens.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/login/repo/tokens.rs b/src/login/repo/tokens.rs new file mode 100644 index 0000000..080e35a --- /dev/null +++ b/src/login/repo/tokens.rs @@ -0,0 +1,47 @@ +use sqlx::{sqlite::Sqlite, SqliteConnection, Transaction}; +use uuid::Uuid; + +use super::logins::Id as LoginId; +use crate::error::BoxedError; + +type DateTime = chrono::DateTime<chrono::Utc>; + +pub trait Provider { + fn tokens(&mut self) -> Tokens; +} + +impl<'c> Provider for Transaction<'c, Sqlite> { + fn tokens(&mut self) -> Tokens { + Tokens(self) + } +} + +pub struct Tokens<'t>(&'t mut SqliteConnection); + +impl<'c> Tokens<'c> { + /// Issue a new token for an existing login. The issued_at timestamp will + /// be used to control expiry. + pub async fn issue( + &mut self, + login: &LoginId, + issued_at: DateTime, + ) -> Result<String, BoxedError> { + let secret = Uuid::new_v4().to_string(); + + let secret = sqlx::query_scalar!( + r#" + insert + into token (secret, login, issued_at) + values ($1, $2, $3) + returning secret as "secret!" + "#, + secret, + login, + issued_at, + ) + .fetch_one(&mut *self.0) + .await?; + + Ok(secret) + } +} |
