diff options
Diffstat (limited to 'src/invite/app.rs')
| -rw-r--r-- | src/invite/app.rs | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/src/invite/app.rs b/src/invite/app.rs index 6e235b2..6684d03 100644 --- a/src/invite/app.rs +++ b/src/invite/app.rs @@ -5,13 +5,15 @@ use super::{Id, Invite, Summary, repo::Provider as _}; use crate::{ clock::DateTime, db::{Duplicate as _, NotFound as _}, - event::Broadcaster, - name::Name, + event::{Broadcaster, repo::Provider as _}, + login::Login, + name::{self, Name}, password::Password, token::{Secret, Token, repo::Provider as _}, user::{ - User, + self, create::{self, Create}, + repo::{LoadError, Provider as _}, }, }; @@ -25,9 +27,19 @@ impl<'a> Invites<'a> { Self { db, events } } - pub async fn issue(&self, issuer: &User, issued_at: &DateTime) -> Result<Invite, sqlx::Error> { + pub async fn issue(&self, issuer: &Login, issued_at: &DateTime) -> Result<Invite, Error> { + let issuer_not_found = || Error::IssuerNotFound(issuer.id.clone().into()); + let issuer_deleted = || Error::IssuerDeleted(issuer.id.clone().into()); + let mut tx = self.db.begin().await?; - let invite = tx.invites().create(issuer, issued_at).await?; + let issuer = tx + .users() + .by_login(issuer) + .await + .not_found(issuer_not_found)?; + let now = tx.sequence().current().await?; + let issuer = issuer.as_of(now).ok_or_else(issuer_deleted)?; + let invite = tx.invites().create(&issuer, issued_at).await?; tx.commit().await?; Ok(invite) @@ -71,8 +83,8 @@ impl<'a> Invites<'a> { .store(&mut tx) .await .duplicate(|| AcceptError::DuplicateLogin(name.clone()))?; - let user = stored.user().as_created(); - let (token, secret) = Token::generate(&user, accepted_at); + let login = stored.login(); + let (token, secret) = Token::generate(login, accepted_at); tx.tokens().create(&token, &secret).await?; tx.commit().await?; @@ -94,6 +106,28 @@ impl<'a> Invites<'a> { } #[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("issuing user {0} not found")] + IssuerNotFound(user::Id), + #[error("issuing user {0} deleted")] + IssuerDeleted(user::Id), + #[error(transparent)] + Database(#[from] sqlx::Error), + #[error(transparent)] + Name(#[from] name::Error), +} + +impl From<user::repo::LoadError> for Error { + fn from(error: LoadError) -> Self { + use user::repo::LoadError; + match error { + LoadError::Database(error) => error.into(), + LoadError::Name(error) => error.into(), + } + } +} + +#[derive(Debug, thiserror::Error)] pub enum AcceptError { #[error("invite not found: {0}")] NotFound(Id), |
