summaryrefslogtreecommitdiff
path: root/src/invite/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/invite/app.rs')
-rw-r--r--src/invite/app.rs50
1 files changed, 43 insertions, 7 deletions
diff --git a/src/invite/app.rs b/src/invite/app.rs
index 1c85562..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, repo::Provider as _},
+ 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,7 +83,9 @@ impl<'a> Invites<'a> {
.store(&mut tx)
.await
.duplicate(|| AcceptError::DuplicateLogin(name.clone()))?;
- let secret = tx.tokens().issue(stored.user(), accepted_at).await?;
+ let login = stored.login();
+ let (token, secret) = Token::generate(login, accepted_at);
+ tx.tokens().create(&token, &secret).await?;
tx.commit().await?;
stored.publish(self.events);
@@ -92,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),