summaryrefslogtreecommitdiff
path: root/src/token/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/token/app.rs')
-rw-r--r--src/token/app.rs49
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)]