diff options
Diffstat (limited to 'src/token/app.rs')
| -rw-r--r-- | src/token/app.rs | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/token/app.rs b/src/token/app.rs index 15fd858..c19d6a0 100644 --- a/src/token/app.rs +++ b/src/token/app.rs @@ -7,12 +7,14 @@ use futures::{ use sqlx::sqlite::SqlitePool; use super::{ - repo::auth::Provider as _, repo::Provider as _, Broadcaster, Event as TokenEvent, Id, Secret, + repo::{self, auth::Provider as _, Provider as _}, + Broadcaster, Event as TokenEvent, Id, Secret, }; use crate::{ clock::DateTime, db::NotFound as _, login::{Login, Password}, + name::{self, Name}, }; pub struct Tokens<'a> { @@ -27,10 +29,10 @@ impl<'a> Tokens<'a> { pub async fn login( &self, - name: &str, + name: &Name, password: &Password, login_at: &DateTime, - ) -> Result<Secret, LoginError> { + ) -> Result<(Login, Secret), LoginError> { let mut tx = self.db.begin().await?; let (login, stored_hash) = tx .auth() @@ -45,6 +47,8 @@ impl<'a> Tokens<'a> { // if the account is deleted during that time. tx.commit().await?; + let snapshot = login.as_snapshot().ok_or(LoginError::Rejected)?; + let token = if stored_hash.verify(password)? { let mut tx = self.db.begin().await?; let token = tx.tokens().issue(&login, login_at).await?; @@ -54,7 +58,7 @@ impl<'a> Tokens<'a> { Err(LoginError::Rejected)? }; - Ok(token) + Ok((snapshot, token)) } pub async fn validate( @@ -63,14 +67,16 @@ impl<'a> Tokens<'a> { used_at: &DateTime, ) -> Result<(Id, Login), ValidateError> { let mut tx = self.db.begin().await?; - let login = tx + let (token, login) = tx .tokens() .validate(secret, used_at) .await .not_found(|| ValidateError::InvalidToken)?; tx.commit().await?; - Ok(login) + let login = login.as_snapshot().ok_or(ValidateError::LoginDeleted)?; + + Ok((token, login)) } pub async fn limit_stream<E>( @@ -158,17 +164,42 @@ pub enum LoginError { #[error("invalid login")] Rejected, #[error(transparent)] - DatabaseError(#[from] sqlx::Error), + Database(#[from] sqlx::Error), + #[error(transparent)] + Name(#[from] name::Error), #[error(transparent)] - PasswordHashError(#[from] password_hash::Error), + PasswordHash(#[from] password_hash::Error), +} + +impl From<repo::auth::LoadError> for LoginError { + fn from(error: repo::auth::LoadError) -> Self { + use repo::auth::LoadError; + match error { + LoadError::Database(error) => error.into(), + LoadError::Name(error) => error.into(), + } + } } #[derive(Debug, thiserror::Error)] pub enum ValidateError { #[error("invalid token")] InvalidToken, + #[error("login deleted")] + LoginDeleted, + #[error(transparent)] + Database(#[from] sqlx::Error), #[error(transparent)] - DatabaseError(#[from] sqlx::Error), + Name(#[from] name::Error), +} + +impl From<repo::LoadError> for ValidateError { + fn from(error: repo::LoadError) -> Self { + match error { + repo::LoadError::Database(error) => error.into(), + repo::LoadError::Name(error) => error.into(), + } + } } #[derive(Debug)] |
