summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.rs12
-rw-r--r--src/channel/routes.rs9
-rw-r--r--src/cli.rs6
-rw-r--r--src/index.rs18
-rw-r--r--src/lib.rs1
-rw-r--r--src/login/extract/login.rs13
-rw-r--r--src/login/routes.rs13
7 files changed, 39 insertions, 33 deletions
diff --git a/src/app.rs b/src/app.rs
new file mode 100644
index 0000000..eff1b5e
--- /dev/null
+++ b/src/app.rs
@@ -0,0 +1,12 @@
+use sqlx::sqlite::SqlitePool;
+
+#[derive(Clone)]
+pub struct App {
+ pub db: SqlitePool,
+}
+
+impl App {
+ pub fn from(db: SqlitePool) -> Self {
+ Self { db }
+ }
+}
diff --git a/src/channel/routes.rs b/src/channel/routes.rs
index 014a57b..6e06cc9 100644
--- a/src/channel/routes.rs
+++ b/src/channel/routes.rs
@@ -4,12 +4,11 @@ use axum::{
routing::post,
Router,
};
-use sqlx::sqlite::SqlitePool;
use super::repo::Provider as _;
-use crate::{error::InternalError, login::repo::logins::Login};
+use crate::{app::App, error::InternalError, login::repo::logins::Login};
-pub fn router() -> Router<SqlitePool> {
+pub fn router() -> Router<App> {
Router::new().route("/create", post(on_create))
}
@@ -19,11 +18,11 @@ struct CreateRequest {
}
async fn on_create(
- State(db): State<SqlitePool>,
+ State(app): State<App>,
_: Login, // requires auth, but doesn't actually care who you are
Form(form): Form<CreateRequest>,
) -> Result<impl IntoResponse, InternalError> {
- let mut tx = db.begin().await?;
+ let mut tx = app.db.begin().await?;
tx.channels().create(&form.name).await?;
tx.commit().await?;
diff --git a/src/cli.rs b/src/cli.rs
index eef006e..6b24b65 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -6,7 +6,7 @@ use clap::Parser;
use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions};
use tokio::net;
-use crate::{channel, clock, error::BoxedError, index, login};
+use crate::{app::App, channel, clock, error::BoxedError, index, login};
pub type Result<T> = std::result::Result<T, BoxedError>;
@@ -30,7 +30,7 @@ impl Args {
let app = routers()
.route_layer(middleware::from_fn(clock::middleware))
- .with_state(pool);
+ .with_state(App::from(pool));
let listener = self.listener().await?;
let started_msg = started_msg(&listener)?;
@@ -62,7 +62,7 @@ impl Args {
}
}
-fn routers() -> Router<SqlitePool> {
+fn routers() -> Router<App> {
[channel::router(), login::router()]
.into_iter()
.fold(index::router(), Router::merge)
diff --git a/src/index.rs b/src/index.rs
index 9efd7cc..843cb77 100644
--- a/src/index.rs
+++ b/src/index.rs
@@ -1,28 +1,26 @@
use axum::{extract::State, routing::get, Router};
use maud::Markup;
-use sqlx::sqlite::SqlitePool;
-use crate::{channel::repo::Provider as _, error::InternalError, login::repo::logins::Login};
+use crate::{
+ app::App, channel::repo::Provider as _, error::InternalError, login::repo::logins::Login,
+};
-async fn index(
- State(db): State<SqlitePool>,
- login: Option<Login>,
-) -> Result<Markup, InternalError> {
+async fn index(State(app): State<App>, login: Option<Login>) -> Result<Markup, InternalError> {
match login {
None => Ok(templates::unauthenticated()),
- Some(login) => index_authenticated(db, login).await,
+ Some(login) => index_authenticated(app, login).await,
}
}
-async fn index_authenticated(db: SqlitePool, login: Login) -> Result<Markup, InternalError> {
- let mut tx = db.begin().await?;
+async fn index_authenticated(app: App, login: Login) -> Result<Markup, InternalError> {
+ let mut tx = app.db.begin().await?;
let channels = tx.channels().all().await?;
tx.commit().await?;
Ok(templates::authenticated(login, &channels))
}
-pub fn router() -> Router<SqlitePool> {
+pub fn router() -> Router<App> {
Router::new().route("/", get(index))
}
diff --git a/src/lib.rs b/src/lib.rs
index 3b8bbcd..d8c9cc0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,4 @@
+mod app;
mod channel;
pub mod cli;
mod clock;
diff --git a/src/login/extract/login.rs b/src/login/extract/login.rs
index da0a90e..4155ec2 100644
--- a/src/login/extract/login.rs
+++ b/src/login/extract/login.rs
@@ -3,9 +3,9 @@ use axum::{
http::{request::Parts, StatusCode},
response::{IntoResponse, Response},
};
-use sqlx::sqlite::SqlitePool;
use crate::{
+ app::App,
clock::RequestedAt,
error::InternalError,
login::{
@@ -15,13 +15,10 @@ use crate::{
};
#[async_trait::async_trait]
-impl FromRequestParts<SqlitePool> for Login {
+impl FromRequestParts<App> for Login {
type Rejection = LoginError<InternalError>;
- async fn from_request_parts(
- parts: &mut Parts,
- state: &SqlitePool,
- ) -> Result<Self, Self::Rejection> {
+ async fn from_request_parts(parts: &mut Parts, state: &App) -> Result<Self, Self::Rejection> {
// After Rust 1.82 (and #[feature(min_exhaustive_patterns)] lands on
// stable), the following can be replaced:
//
@@ -31,8 +28,8 @@ impl FromRequestParts<SqlitePool> for Login {
let secret = identity_token.secret().ok_or(LoginError::Forbidden)?;
- let db = State::<SqlitePool>::from_request_parts(parts, state).await?;
- let mut tx = db.begin().await?;
+ let app = State::<App>::from_request_parts(parts, state).await?;
+ let mut tx = app.db.begin().await?;
tx.tokens().expire(requested_at).await?;
let login = tx.tokens().validate(secret, requested_at).await?;
tx.commit().await?;
diff --git a/src/login/routes.rs b/src/login/routes.rs
index c30bcb1..9cefe38 100644
--- a/src/login/routes.rs
+++ b/src/login/routes.rs
@@ -5,16 +5,15 @@ use axum::{
routing::post,
Router,
};
-use sqlx::sqlite::SqlitePool;
-use crate::{clock::RequestedAt, error::InternalError};
+use crate::{app::App, clock::RequestedAt, error::InternalError};
use super::{
extract::IdentityToken,
repo::{logins::Provider as _, tokens::Provider as _},
};
-pub fn router() -> Router<SqlitePool> {
+pub fn router() -> Router<App> {
Router::new()
.route("/login", post(on_login))
.route("/logout", post(on_logout))
@@ -27,12 +26,12 @@ struct LoginRequest {
}
async fn on_login(
- State(db): State<SqlitePool>,
+ State(app): State<App>,
RequestedAt(now): RequestedAt,
identity: IdentityToken,
Form(form): Form<LoginRequest>,
) -> Result<impl IntoResponse, InternalError> {
- let mut tx = db.begin().await?;
+ let mut tx = app.db.begin().await?;
// Spelling the following in the more conventional form,
// if let Some(…) = create().await? {}
@@ -88,11 +87,11 @@ impl IntoResponse for LoginResponse {
}
async fn on_logout(
- State(db): State<SqlitePool>,
+ State(app): State<App>,
identity: IdentityToken,
) -> Result<impl IntoResponse, InternalError> {
if let Some(secret) = identity.secret() {
- let mut tx = db.begin().await?;
+ let mut tx = app.db.begin().await?;
tx.tokens().revoke(secret).await?;
tx.commit().await?;
}