summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2025-10-27 17:47:30 -0400
committerOwen Jacobson <owen@grimoire.ca>2025-10-28 01:42:48 -0400
commit38ac83aef9667f1a4fe86e03e53565376081179f (patch)
tree9bb5f4e43ee7d2a1db5a0a653fc59eeb740c545a
parentf305e487d619f1d993d11d728c8cf7261bf3b371 (diff)
Convert `Logins` into a freestanding component.
-rw-r--r--src/app.rs10
-rw-r--r--src/login/app.rs10
-rw-r--r--src/login/handlers/login/mod.rs14
-rw-r--r--src/login/handlers/login/test.rs8
-rw-r--r--src/login/handlers/password/mod.rs8
-rw-r--r--src/login/handlers/password/test.rs2
-rw-r--r--src/test/fixtures/cookie.rs14
7 files changed, 39 insertions, 27 deletions
diff --git a/src/app.rs b/src/app.rs
index 2d6d62b..793bdab 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -50,8 +50,8 @@ impl App {
Invites::new(self.db.clone(), self.events.clone())
}
- pub const fn logins(&self) -> Logins<'_> {
- Logins::new(&self.db, &self.token_events)
+ pub fn logins(&self) -> Logins {
+ Logins::new(self.db.clone(), self.token_events.clone())
}
pub const fn messages(&self) -> Messages<'_> {
@@ -89,3 +89,9 @@ impl FromRef<App> for Invites {
app.invites()
}
}
+
+impl FromRef<App> for Logins {
+ fn from_ref(app: &App) -> Self {
+ app.logins()
+ }
+}
diff --git a/src/login/app.rs b/src/login/app.rs
index e471000..a2f9636 100644
--- a/src/login/app.rs
+++ b/src/login/app.rs
@@ -9,13 +9,13 @@ use crate::{
token::{Broadcaster, Event as TokenEvent, Secret, Token, repo::Provider as _},
};
-pub struct Logins<'a> {
- db: &'a SqlitePool,
- token_events: &'a Broadcaster,
+pub struct Logins {
+ db: SqlitePool,
+ token_events: Broadcaster,
}
-impl<'a> Logins<'a> {
- pub const fn new(db: &'a SqlitePool, token_events: &'a Broadcaster) -> Self {
+impl Logins {
+ pub const fn new(db: SqlitePool, token_events: Broadcaster) -> Self {
Self { db, token_events }
}
diff --git a/src/login/handlers/login/mod.rs b/src/login/handlers/login/mod.rs
index 6591984..2ce8a67 100644
--- a/src/login/handlers/login/mod.rs
+++ b/src/login/handlers/login/mod.rs
@@ -5,21 +5,25 @@ use axum::{
};
use crate::{
- app::App, clock::RequestedAt, empty::Empty, error::Internal, login::app, name::Name,
- password::Password, token::extract::IdentityCookie,
+ clock::RequestedAt,
+ empty::Empty,
+ error::Internal,
+ login::{app, app::Logins},
+ name::Name,
+ password::Password,
+ token::extract::IdentityCookie,
};
#[cfg(test)]
mod test;
pub async fn handler(
- State(app): State<App>,
+ State(logins): State<Logins>,
RequestedAt(now): RequestedAt,
identity: IdentityCookie,
Json(request): Json<Request>,
) -> Result<(IdentityCookie, Empty), Error> {
- let secret = app
- .logins()
+ let secret = logins
.with_password(&request.name, &request.password, &now)
.await
.map_err(Error)?;
diff --git a/src/login/handlers/login/test.rs b/src/login/handlers/login/test.rs
index f3911d0..7bb56b6 100644
--- a/src/login/handlers/login/test.rs
+++ b/src/login/handlers/login/test.rs
@@ -22,7 +22,7 @@ async fn correct_credentials() {
password,
};
let (identity, Empty) =
- super::handler(State(app.clone()), logged_in_at, identity, Json(request))
+ super::handler(State(app.logins()), logged_in_at, identity, Json(request))
.await
.expect("logged in with valid credentials");
@@ -52,7 +52,7 @@ async fn invalid_name() {
password,
};
let super::Error(error) =
- super::handler(State(app.clone()), logged_in_at, identity, Json(request))
+ super::handler(State(app.logins()), logged_in_at, identity, Json(request))
.await
.expect_err("logged in with an incorrect password fails");
@@ -77,7 +77,7 @@ async fn incorrect_password() {
password: fixtures::user::propose_password(),
};
let super::Error(error) =
- super::handler(State(app.clone()), logged_in_at, identity, Json(request))
+ super::handler(State(app.logins()), logged_in_at, identity, Json(request))
.await
.expect_err("logged in with an incorrect password");
@@ -98,7 +98,7 @@ async fn token_expires() {
let logged_in_at = fixtures::ancient();
let identity = fixtures::cookie::not_logged_in();
let request = super::Request { name, password };
- let (identity, _) = super::handler(State(app.clone()), logged_in_at, identity, Json(request))
+ let (identity, _) = super::handler(State(app.logins()), logged_in_at, identity, Json(request))
.await
.expect("logged in with valid credentials");
let secret = identity.secret().expect("logged in with valid credentials");
diff --git a/src/login/handlers/password/mod.rs b/src/login/handlers/password/mod.rs
index 94c7fb4..8b82605 100644
--- a/src/login/handlers/password/mod.rs
+++ b/src/login/handlers/password/mod.rs
@@ -5,11 +5,10 @@ use axum::{
};
use crate::{
- app::App,
clock::RequestedAt,
empty::Empty,
error::Internal,
- login::app,
+ login::{app, app::Logins},
password::Password,
token::extract::{Identity, IdentityCookie},
};
@@ -18,14 +17,13 @@ use crate::{
mod test;
pub async fn handler(
- State(app): State<App>,
+ State(logins): State<Logins>,
RequestedAt(now): RequestedAt,
identity: Identity,
cookie: IdentityCookie,
Json(request): Json<Request>,
) -> Result<(IdentityCookie, Empty), Error> {
- let secret = app
- .logins()
+ let secret = logins
.change_password(&identity.login, &request.password, &request.to, &now)
.await
.map_err(Error)?;
diff --git a/src/login/handlers/password/test.rs b/src/login/handlers/password/test.rs
index ba2f28f..61d5b5a 100644
--- a/src/login/handlers/password/test.rs
+++ b/src/login/handlers/password/test.rs
@@ -21,7 +21,7 @@ async fn password_change() {
to: to.clone(),
};
let (new_cookie, Empty) = super::handler(
- State(app.clone()),
+ State(app.logins()),
fixtures::now(),
identity.clone(),
cookie.clone(),
diff --git a/src/test/fixtures/cookie.rs b/src/test/fixtures/cookie.rs
index 7dc5083..0b5ec9b 100644
--- a/src/test/fixtures/cookie.rs
+++ b/src/test/fixtures/cookie.rs
@@ -1,21 +1,25 @@
+use axum::extract::FromRef;
use uuid::Uuid;
use crate::{
- app::App, clock::RequestedAt, name::Name, password::Password, token::extract::IdentityCookie,
+ clock::RequestedAt, login::app::Logins, name::Name, password::Password,
+ token::extract::IdentityCookie,
};
pub fn not_logged_in() -> IdentityCookie {
IdentityCookie::new()
}
-pub async fn logged_in(
+pub async fn logged_in<App>(
app: &App,
credentials: &(Name, Password),
now: &RequestedAt,
-) -> IdentityCookie {
+) -> IdentityCookie
+where
+ Logins: FromRef<App>,
+{
let (name, password) = credentials;
- let secret = app
- .logins()
+ let secret = Logins::from_ref(app)
.with_password(name, password, now)
.await
.expect("should succeed given known-valid credentials");