diff --git a/crates/axum-utils/src/csrf.rs b/crates/axum-utils/src/csrf.rs index c12a2ed8..e7037d55 100644 --- a/crates/axum-utils/src/csrf.rs +++ b/crates/axum-utils/src/csrf.rs @@ -15,7 +15,7 @@ use axum_extra::extract::cookie::{Cookie, PrivateCookieJar}; use chrono::{DateTime, Duration, Utc}; use data_encoding::{DecodeError, BASE64URL_NOPAD}; -use rand::{thread_rng, Rng}; +use rand::{Rng, RngCore}; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, TimestampSeconds}; use thiserror::Error; @@ -108,23 +108,22 @@ pub struct ProtectedForm { } pub trait CsrfExt { - fn csrf_token(self) -> (CsrfToken, Self); - fn verify_form(&self, form: ProtectedForm) -> Result; + fn csrf_token(self, now: DateTime, rng: R) -> (CsrfToken, Self) + where + R: RngCore; + fn verify_form(&self, now: DateTime, form: ProtectedForm) -> Result; } impl CsrfExt for PrivateCookieJar { - fn csrf_token(self) -> (CsrfToken, Self) { + fn csrf_token(self, now: DateTime, rng: R) -> (CsrfToken, Self) + where + R: RngCore, + { let jar = self; let mut cookie = jar.get("csrf").unwrap_or_else(|| Cookie::new("csrf", "")); cookie.set_path("/"); cookie.set_http_only(true); - // XXX: the rng source and clock should come from somewhere else - #[allow(clippy::disallowed_methods)] - let now = Utc::now(); - #[allow(clippy::disallowed_methods)] - let rng = thread_rng(); - let new_token = cookie .decode() .ok() @@ -137,11 +136,7 @@ impl CsrfExt for PrivateCookieJar { (new_token, jar) } - fn verify_form(&self, form: ProtectedForm) -> Result { - // XXX: the clock should come from somewhere else - #[allow(clippy::disallowed_methods)] - let now = Utc::now(); - + fn verify_form(&self, now: DateTime, form: ProtectedForm) -> Result { let cookie = self.get("csrf").ok_or(CsrfError::Missing)?; let token: CsrfToken = cookie.decode()?; let token = token.verify_expiration(now)?; diff --git a/crates/cli/src/commands/config.rs b/crates/cli/src/commands/config.rs index c2da1d73..a1d6376e 100644 --- a/crates/cli/src/commands/config.rs +++ b/crates/cli/src/commands/config.rs @@ -14,6 +14,7 @@ use clap::Parser; use mas_config::{ConfigurationSection, RootConfig}; +use rand::SeedableRng; use tracing::info; #[derive(Parser, Debug)] @@ -51,7 +52,9 @@ impl Options { Ok(()) } SC::Generate => { - let config = RootConfig::load_and_generate().await?; + // XXX: we should disallow SeedableRng::from_entropy + let rng = rand_chacha::ChaChaRng::from_entropy(); + let config = RootConfig::load_and_generate(rng).await?; serde_yaml::to_writer(std::io::stdout(), &config)?; diff --git a/crates/config/src/sections/clients.rs b/crates/config/src/sections/clients.rs index 6cd051d0..db0c8a15 100644 --- a/crates/config/src/sections/clients.rs +++ b/crates/config/src/sections/clients.rs @@ -17,6 +17,7 @@ use std::ops::{Deref, DerefMut}; use async_trait::async_trait; use mas_iana::oauth::OAuthClientAuthenticationMethod; use mas_jose::jwk::PublicJsonWebKeySet; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; @@ -171,8 +172,10 @@ impl ConfigurationSection<'_> for ClientsConfig { "clients" } - #[tracing::instrument] - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/sections/csrf.rs b/crates/config/src/sections/csrf.rs index ee74d4d9..ec7eeba6 100644 --- a/crates/config/src/sections/csrf.rs +++ b/crates/config/src/sections/csrf.rs @@ -14,6 +14,7 @@ use async_trait::async_trait; use chrono::Duration; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::serde_as; @@ -47,7 +48,10 @@ impl ConfigurationSection<'_> for CsrfConfig { "csrf" } - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/sections/database.rs b/crates/config/src/sections/database.rs index c65d6357..9a2046a2 100644 --- a/crates/config/src/sections/database.rs +++ b/crates/config/src/sections/database.rs @@ -16,6 +16,7 @@ use std::{num::NonZeroU32, path::PathBuf, time::Duration}; use anyhow::Context; use async_trait::async_trait; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, skip_serializing_none}; @@ -224,7 +225,10 @@ impl ConfigurationSection<'_> for DatabaseConfig { "database" } - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/sections/email.rs b/crates/config/src/sections/email.rs index 6db56057..713198a8 100644 --- a/crates/config/src/sections/email.rs +++ b/crates/config/src/sections/email.rs @@ -18,6 +18,7 @@ use anyhow::Context; use async_trait::async_trait; use lettre::{message::Mailbox, Address}; use mas_email::MailTransport; +use rand::Rng; use schemars::{ gen::SchemaGenerator, schema::{InstanceType, Schema, SchemaObject}, @@ -160,7 +161,10 @@ impl ConfigurationSection<'_> for EmailConfig { "email" } - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/sections/http.rs b/crates/config/src/sections/http.rs index 812bc571..d0683240 100644 --- a/crates/config/src/sections/http.rs +++ b/crates/config/src/sections/http.rs @@ -17,6 +17,7 @@ use std::{borrow::Cow, io::Cursor, ops::Deref, path::PathBuf}; use anyhow::bail; use async_trait::async_trait; use mas_keystore::PrivateKey; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; @@ -328,7 +329,10 @@ impl ConfigurationSection<'_> for HttpConfig { "http" } - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/sections/matrix.rs b/crates/config/src/sections/matrix.rs index 6ae887db..0a3866c6 100644 --- a/crates/config/src/sections/matrix.rs +++ b/crates/config/src/sections/matrix.rs @@ -13,6 +13,7 @@ // limitations under the License. use async_trait::async_trait; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::serde_as; @@ -46,7 +47,10 @@ impl ConfigurationSection<'_> for MatrixConfig { "matrix" } - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/sections/mod.rs b/crates/config/src/sections/mod.rs index 44a13483..df4482b7 100644 --- a/crates/config/src/sections/mod.rs +++ b/crates/config/src/sections/mod.rs @@ -13,6 +13,7 @@ // limitations under the License. use async_trait::async_trait; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -96,18 +97,21 @@ impl ConfigurationSection<'_> for RootConfig { "" } - async fn generate() -> anyhow::Result { + async fn generate(mut rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self { - clients: ClientsConfig::generate().await?, - http: HttpConfig::generate().await?, - database: DatabaseConfig::generate().await?, - telemetry: TelemetryConfig::generate().await?, - templates: TemplatesConfig::generate().await?, - csrf: CsrfConfig::generate().await?, - email: EmailConfig::generate().await?, - secrets: SecretsConfig::generate().await?, - matrix: MatrixConfig::generate().await?, - policy: PolicyConfig::generate().await?, + clients: ClientsConfig::generate(&mut rng).await?, + http: HttpConfig::generate(&mut rng).await?, + database: DatabaseConfig::generate(&mut rng).await?, + telemetry: TelemetryConfig::generate(&mut rng).await?, + templates: TemplatesConfig::generate(&mut rng).await?, + csrf: CsrfConfig::generate(&mut rng).await?, + email: EmailConfig::generate(&mut rng).await?, + secrets: SecretsConfig::generate(&mut rng).await?, + matrix: MatrixConfig::generate(&mut rng).await?, + policy: PolicyConfig::generate(&mut rng).await?, }) } diff --git a/crates/config/src/sections/policy.rs b/crates/config/src/sections/policy.rs index f7fe0993..7146701a 100644 --- a/crates/config/src/sections/policy.rs +++ b/crates/config/src/sections/policy.rs @@ -15,6 +15,7 @@ use std::path::PathBuf; use async_trait::async_trait; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::serde_as; @@ -76,7 +77,10 @@ impl ConfigurationSection<'_> for PolicyConfig { "policy" } - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/sections/secrets.rs b/crates/config/src/sections/secrets.rs index 8ba5e667..770c49b4 100644 --- a/crates/config/src/sections/secrets.rs +++ b/crates/config/src/sections/secrets.rs @@ -20,7 +20,7 @@ use mas_jose::jwk::{JsonWebKey, JsonWebKeySet}; use mas_keystore::{Encrypter, Keystore, PrivateKey}; use rand::{ distributions::{Alphanumeric, DistString}, - thread_rng, SeedableRng, + Rng, SeedableRng, }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -137,12 +137,11 @@ impl ConfigurationSection<'_> for SecretsConfig { "secrets" } - #[tracing::instrument] - async fn generate() -> anyhow::Result { - // XXX: that RNG should come from somewhere else - #[allow(clippy::disallowed_methods)] - let mut rng = rand_chacha::ChaChaRng::from_rng(thread_rng())?; - + #[tracing::instrument(skip_all)] + async fn generate(mut rng: R) -> anyhow::Result + where + R: Rng + Send, + { info!("Generating keys..."); let span = tracing::info_span!("rsa"); diff --git a/crates/config/src/sections/telemetry.rs b/crates/config/src/sections/telemetry.rs index 316af941..2c21bd28 100644 --- a/crates/config/src/sections/telemetry.rs +++ b/crates/config/src/sections/telemetry.rs @@ -15,6 +15,7 @@ use std::num::NonZeroU16; use async_trait::async_trait; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; @@ -274,7 +275,10 @@ impl ConfigurationSection<'_> for TelemetryConfig { "telemetry" } - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/sections/templates.rs b/crates/config/src/sections/templates.rs index a3273425..f51f9a97 100644 --- a/crates/config/src/sections/templates.rs +++ b/crates/config/src/sections/templates.rs @@ -13,6 +13,7 @@ // limitations under the License. use async_trait::async_trait; +use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -49,7 +50,10 @@ impl ConfigurationSection<'_> for TemplatesConfig { "templates" } - async fn generate() -> anyhow::Result { + async fn generate(_rng: R) -> anyhow::Result + where + R: Rng + Send, + { Ok(Self::default()) } diff --git a/crates/config/src/util.rs b/crates/config/src/util.rs index 268cad10..5cd3ca92 100644 --- a/crates/config/src/util.rs +++ b/crates/config/src/util.rs @@ -21,6 +21,7 @@ use figment::{ providers::{Env, Format, Serialized, Yaml}, Figment, Profile, }; +use rand::Rng; use serde::{Deserialize, Serialize}; #[async_trait] @@ -31,7 +32,9 @@ pub trait ConfigurationSection<'a>: Sized + Deserialize<'a> + Serialize { fn path() -> &'static str; /// Generate a sample configuration for this section. - async fn generate() -> anyhow::Result; + async fn generate(rng: R) -> anyhow::Result + where + R: Rng + Send; /// Generate a sample configuration and override it with environment /// variables. @@ -44,8 +47,11 @@ pub trait ConfigurationSection<'a>: Sized + Deserialize<'a> + Serialize { /// export MAS_HTTP_ADDRESS=127.0.0.1:1234 /// matrix-authentication-service config generate /// ``` - async fn load_and_generate() -> anyhow::Result { - let base = Self::generate() + async fn load_and_generate(rng: R) -> anyhow::Result + where + R: Rng + Send, + { + let base = Self::generate(rng) .await .context("could not generate configuration")?; diff --git a/crates/handlers/src/compat/login_sso_complete.rs b/crates/handlers/src/compat/login_sso_complete.rs index 97dd0e00..43602aca 100644 --- a/crates/handlers/src/compat/login_sso_complete.rs +++ b/crates/handlers/src/compat/login_sso_complete.rs @@ -28,10 +28,7 @@ use mas_axum_utils::{ use mas_data_model::Device; use mas_keystore::Encrypter; use mas_router::{CompatLoginSsoAction, PostAuthAction, Route}; -use mas_storage::{ - compat::{fullfill_compat_sso_login, get_compat_sso_login_by_id}, - Clock, -}; +use mas_storage::compat::{fullfill_compat_sso_login, get_compat_sso_login_by_id}; use mas_templates::{CompatSsoContext, ErrorContext, TemplateContext, Templates}; use serde::{Deserialize, Serialize}; use sqlx::PgPool; @@ -58,11 +55,11 @@ pub async fn get( Path(id): Path, Query(params): Query, ) -> Result { - let clock = Clock::default(); + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; let (session_info, cookie_jar) = cookie_jar.session_info(); - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let maybe_session = session_info.load_session(&mut conn).await?; @@ -128,7 +125,7 @@ pub async fn post( let mut txn = pool.begin().await?; let (session_info, cookie_jar) = cookie_jar.session_info(); - cookie_jar.verify_form(form)?; + cookie_jar.verify_form(clock.now(), form)?; let maybe_session = session_info.load_session(&mut txn).await?; diff --git a/crates/handlers/src/oauth2/consent.rs b/crates/handlers/src/oauth2/consent.rs index e3f9f0bf..a963c74e 100644 --- a/crates/handlers/src/oauth2/consent.rs +++ b/crates/handlers/src/oauth2/consent.rs @@ -57,6 +57,7 @@ pub(crate) async fn get( cookie_jar: PrivateCookieJar, Path(grant_id): Path, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool .acquire() .await @@ -76,7 +77,7 @@ pub(crate) async fn get( } if let Some(session) = maybe_session { - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let mut policy = policy_factory.instantiate().await?; let res = policy @@ -126,7 +127,7 @@ pub(crate) async fn post( .context("failed to begin db transaction")?; cookie_jar - .verify_form(form) + .verify_form(clock.now(), form) .context("csrf verification failed")?; let (session_info, cookie_jar) = cookie_jar.session_info(); diff --git a/crates/handlers/src/views/account/emails/add.rs b/crates/handlers/src/views/account/emails/add.rs index 805f2e5a..a3b46846 100644 --- a/crates/handlers/src/views/account/emails/add.rs +++ b/crates/handlers/src/views/account/emails/add.rs @@ -42,9 +42,10 @@ pub(crate) async fn get( State(pool): State, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.begin().await?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let (session_info, cookie_jar) = cookie_jar.session_info(); let maybe_session = session_info.load_session(&mut conn).await?; @@ -75,7 +76,7 @@ pub(crate) async fn post( let (clock, mut rng) = crate::rng_and_clock()?; let mut txn = pool.begin().await?; - let form = cookie_jar.verify_form(form)?; + let form = cookie_jar.verify_form(clock.now(), form)?; let (session_info, cookie_jar) = cookie_jar.session_info(); let maybe_session = session_info.load_session(&mut txn).await?; diff --git a/crates/handlers/src/views/account/emails/mod.rs b/crates/handlers/src/views/account/emails/mod.rs index 8d7b6d2b..cefb244a 100644 --- a/crates/handlers/src/views/account/emails/mod.rs +++ b/crates/handlers/src/views/account/emails/mod.rs @@ -57,6 +57,8 @@ pub(crate) async fn get( State(pool): State, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; + let mut conn = pool.acquire().await?; let (session_info, cookie_jar) = cookie_jar.session_info(); @@ -64,7 +66,7 @@ pub(crate) async fn get( let maybe_session = session_info.load_session(&mut conn).await?; if let Some(session) = maybe_session { - render(templates, session, cookie_jar, &mut conn).await + render(&mut rng, &clock, templates, session, cookie_jar, &mut conn).await } else { let login = mas_router::Login::default(); Ok((cookie_jar, login.go()).into_response()) @@ -72,12 +74,14 @@ pub(crate) async fn get( } async fn render( + rng: impl Rng, + clock: &Clock, templates: Templates, session: BrowserSession, cookie_jar: PrivateCookieJar, executor: impl PgExecutor<'_>, ) -> Result { - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), rng); let emails = get_user_emails(executor, &session.user).await?; @@ -149,7 +153,7 @@ pub(crate) async fn post( return Ok((cookie_jar, login.go()).into_response()); }; - let form = cookie_jar.verify_form(form)?; + let form = cookie_jar.verify_form(clock.now(), form)?; match form { ManagementForm::Add { email } => { @@ -199,7 +203,15 @@ pub(crate) async fn post( } }; - let reply = render(templates.clone(), session, cookie_jar, &mut txn).await?; + let reply = render( + &mut rng, + &clock, + templates.clone(), + session, + cookie_jar, + &mut txn, + ) + .await?; txn.commit().await?; diff --git a/crates/handlers/src/views/account/emails/verify.rs b/crates/handlers/src/views/account/emails/verify.rs index ff1addea..ac762687 100644 --- a/crates/handlers/src/views/account/emails/verify.rs +++ b/crates/handlers/src/views/account/emails/verify.rs @@ -49,9 +49,10 @@ pub(crate) async fn get( Path(id): Path, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let (session_info, cookie_jar) = cookie_jar.session_info(); let maybe_session = session_info.load_session(&mut conn).await?; @@ -90,7 +91,7 @@ pub(crate) async fn post( let clock = Clock::default(); let mut txn = pool.begin().await?; - let form = cookie_jar.verify_form(form)?; + let form = cookie_jar.verify_form(clock.now(), form)?; let (session_info, cookie_jar) = cookie_jar.session_info(); let maybe_session = session_info.load_session(&mut txn).await?; diff --git a/crates/handlers/src/views/account/mod.rs b/crates/handlers/src/views/account/mod.rs index b35e6b04..bda28415 100644 --- a/crates/handlers/src/views/account/mod.rs +++ b/crates/handlers/src/views/account/mod.rs @@ -32,9 +32,10 @@ pub(crate) async fn get( State(pool): State, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let (session_info, cookie_jar) = cookie_jar.session_info(); let maybe_session = session_info.load_session(&mut conn).await?; diff --git a/crates/handlers/src/views/account/password.rs b/crates/handlers/src/views/account/password.rs index 7f317868..35414c7d 100644 --- a/crates/handlers/src/views/account/password.rs +++ b/crates/handlers/src/views/account/password.rs @@ -27,9 +27,10 @@ use mas_keystore::Encrypter; use mas_router::Route; use mas_storage::{ user::{authenticate_session, set_password}, - PostgresqlBackend, + Clock, PostgresqlBackend, }; use mas_templates::{EmptyContext, TemplateContext, Templates}; +use rand::Rng; use serde::Deserialize; use sqlx::PgPool; @@ -45,6 +46,7 @@ pub(crate) async fn get( State(pool): State, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; let (session_info, cookie_jar) = cookie_jar.session_info(); @@ -52,7 +54,7 @@ pub(crate) async fn get( let maybe_session = session_info.load_session(&mut conn).await?; if let Some(session) = maybe_session { - render(templates, session, cookie_jar).await + render(&mut rng, &clock, templates, session, cookie_jar).await } else { let login = mas_router::Login::and_then(mas_router::PostAuthAction::ChangePassword); Ok((cookie_jar, login.go()).into_response()) @@ -60,11 +62,13 @@ pub(crate) async fn get( } async fn render( + rng: impl Rng, + clock: &Clock, templates: Templates, session: BrowserSession, cookie_jar: PrivateCookieJar, ) -> Result { - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), rng); let ctx = EmptyContext .with_session(session) @@ -84,7 +88,7 @@ pub(crate) async fn post( let (clock, mut rng) = crate::rng_and_clock()?; let mut txn = pool.begin().await?; - let form = cookie_jar.verify_form(form)?; + let form = cookie_jar.verify_form(clock.now(), form)?; let (session_info, cookie_jar) = cookie_jar.session_info(); @@ -122,7 +126,7 @@ pub(crate) async fn post( ) .await?; - let reply = render(templates.clone(), session, cookie_jar).await?; + let reply = render(&mut rng, &clock, templates.clone(), session, cookie_jar).await?; txn.commit().await?; diff --git a/crates/handlers/src/views/index.rs b/crates/handlers/src/views/index.rs index 66ef34bc..3e4f6811 100644 --- a/crates/handlers/src/views/index.rs +++ b/crates/handlers/src/views/index.rs @@ -29,9 +29,10 @@ pub async fn get( State(pool): State, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let (session_info, cookie_jar) = cookie_jar.session_info(); let session = session_info.load_session(&mut conn).await?; diff --git a/crates/handlers/src/views/login.rs b/crates/handlers/src/views/login.rs index c62f5098..71a043ef 100644 --- a/crates/handlers/src/views/login.rs +++ b/crates/handlers/src/views/login.rs @@ -42,16 +42,16 @@ impl ToFormState for LoginForm { type Field = LoginFormField; } -#[tracing::instrument(skip(templates, pool, cookie_jar))] pub(crate) async fn get( State(templates): State, State(pool): State, Query(query): Query, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let (session_info, cookie_jar) = cookie_jar.session_info(); let maybe_session = session_info.load_session(&mut conn).await?; @@ -83,9 +83,9 @@ pub(crate) async fn post( let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; - let form = cookie_jar.verify_form(form)?; + let form = cookie_jar.verify_form(clock.now(), form)?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); // Validate the form let state = { diff --git a/crates/handlers/src/views/logout.rs b/crates/handlers/src/views/logout.rs index a742a9f3..fd76bc6b 100644 --- a/crates/handlers/src/views/logout.rs +++ b/crates/handlers/src/views/logout.rs @@ -34,7 +34,7 @@ pub(crate) async fn post( let clock = Clock::default(); let mut txn = pool.begin().await?; - let form = cookie_jar.verify_form(form)?; + let form = cookie_jar.verify_form(clock.now(), form)?; let (session_info, mut cookie_jar) = cookie_jar.session_info(); diff --git a/crates/handlers/src/views/reauth.rs b/crates/handlers/src/views/reauth.rs index dfaa8e0e..aaf09d6c 100644 --- a/crates/handlers/src/views/reauth.rs +++ b/crates/handlers/src/views/reauth.rs @@ -41,9 +41,10 @@ pub(crate) async fn get( Query(query): Query, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let (session_info, cookie_jar) = cookie_jar.session_info(); let maybe_session = session_info.load_session(&mut conn).await?; @@ -83,7 +84,7 @@ pub(crate) async fn post( let (clock, mut rng) = crate::rng_and_clock()?; let mut txn = pool.begin().await?; - let form = cookie_jar.verify_form(form)?; + let form = cookie_jar.verify_form(clock.now(), form)?; let (session_info, cookie_jar) = cookie_jar.session_info(); diff --git a/crates/handlers/src/views/register.rs b/crates/handlers/src/views/register.rs index d1957d33..ce66a591 100644 --- a/crates/handlers/src/views/register.rs +++ b/crates/handlers/src/views/register.rs @@ -63,9 +63,10 @@ pub(crate) async fn get( Query(query): Query, cookie_jar: PrivateCookieJar, ) -> Result { + let (clock, mut rng) = crate::rng_and_clock()?; let mut conn = pool.acquire().await?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); let (session_info, cookie_jar) = cookie_jar.session_info(); let maybe_session = session_info.load_session(&mut conn).await?; @@ -100,9 +101,9 @@ pub(crate) async fn post( let (clock, mut rng) = crate::rng_and_clock()?; let mut txn = pool.begin().await?; - let form = cookie_jar.verify_form(form)?; + let form = cookie_jar.verify_form(clock.now(), form)?; - let (csrf_token, cookie_jar) = cookie_jar.csrf_token(); + let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock.now(), &mut rng); // Validate the form let state = {