From 74ef9102a62f713f36f6f8412732be9d837d8d2c Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Thu, 12 Sep 2024 00:15:32 -0400 Subject: Push most endpoint and extractor logic into functoins of `App`. This is, again, groundwork for logic that requires more than just a database connection. The login process has been changed to be more conventional, attempting login _before_ account creation rather than after it. This was not previously possible, because the data access methods used to perform these steps did not return enough information to carry out the workflow in that order. Separating storage from password validation and hashing forces the issue, and makes it clearer _at the App_ whether an account exists or not. This does introduce the possibility of two racing inserts trying to lay claim to the same username. Transaction isolation should ensure that only one of them "wins," which is what you get before this change anyways. --- src/channel/app.rs | 21 +++++++++++++++++++++ src/channel/mod.rs | 1 + src/channel/routes.rs | 5 +---- 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/channel/app.rs (limited to 'src/channel') diff --git a/src/channel/app.rs b/src/channel/app.rs new file mode 100644 index 0000000..84822cb --- /dev/null +++ b/src/channel/app.rs @@ -0,0 +1,21 @@ +use sqlx::sqlite::SqlitePool; + +use super::repo::Provider as _; +use crate::error::BoxedError; + +pub struct Channels<'a> { + db: &'a SqlitePool, +} + +impl<'a> Channels<'a> { + pub fn new(db: &'a SqlitePool) -> Self { + Self { db } + } + + pub async fn create(&self, name: &str) -> Result<(), BoxedError> { + let mut tx = self.db.begin().await?; + tx.channels().create(name).await?; + tx.commit().await?; + Ok(()) + } +} diff --git a/src/channel/mod.rs b/src/channel/mod.rs index 238e116..f67ea04 100644 --- a/src/channel/mod.rs +++ b/src/channel/mod.rs @@ -1,3 +1,4 @@ +pub mod app; pub mod repo; mod routes; diff --git a/src/channel/routes.rs b/src/channel/routes.rs index 6e06cc9..864f1b3 100644 --- a/src/channel/routes.rs +++ b/src/channel/routes.rs @@ -5,7 +5,6 @@ use axum::{ Router, }; -use super::repo::Provider as _; use crate::{app::App, error::InternalError, login::repo::logins::Login}; pub fn router() -> Router { @@ -22,9 +21,7 @@ async fn on_create( _: Login, // requires auth, but doesn't actually care who you are Form(form): Form, ) -> Result { - let mut tx = app.db.begin().await?; - tx.channels().create(&form.name).await?; - tx.commit().await?; + app.channels().create(&form.name).await?; Ok(Redirect::to("/")) } -- cgit v1.2.3