1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-08-09 04:22:45 +03:00

Axum migration: CSRF token and login page

This commit is contained in:
Quentin Gliech
2022-03-25 15:38:30 +01:00
parent 5d3b4aa182
commit 5e95c705d4
5 changed files with 130 additions and 98 deletions

View File

@@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize};
use serde_with::{serde_as, TimestampSeconds};
use thiserror::Error;
use crate::{CookieExt, PrivateCookieJar};
use crate::{cookies::CookieDecodeError, CookieExt, PrivateCookieJar};
/// Failed to validate CSRF token
#[derive(Debug, Error)]
@@ -28,6 +28,14 @@ pub enum CsrfError {
#[error("CSRF token mismatch")]
Mismatch,
/// The token in the form did not match the token in the cookie
#[error("Missing CSRF cookie")]
Missing,
/// Failed to decode the token
#[error("could not decode CSRF cookie")]
DecodeCookie(#[from] CookieDecodeError),
/// The token expired
#[error("CSRF token expired")]
Expired,
@@ -89,8 +97,18 @@ impl CsrfToken {
}
}
// A CSRF-protected form
#[derive(Deserialize)]
pub struct ProtectedForm<T> {
csrf: String,
#[serde(flatten)]
inner: T,
}
pub trait CsrfExt {
fn csrf_token(self) -> (CsrfToken, Self);
fn verify_form<T>(&self, form: ProtectedForm<T>) -> Result<T, CsrfError>;
}
impl<K> CsrfExt for PrivateCookieJar<K> {
@@ -108,4 +126,12 @@ impl<K> CsrfExt for PrivateCookieJar<K> {
let jar = jar.add(cookie);
(new_token, jar)
}
fn verify_form<T>(&self, form: ProtectedForm<T>) -> Result<T, CsrfError> {
let cookie = self.get("csrf").ok_or(CsrfError::Missing)?;
let token: CsrfToken = cookie.decode()?;
let token = token.verify_expiration()?;
token.verify_form_value(&form.csrf)?;
Ok(form.inner)
}
}

View File

@@ -50,7 +50,9 @@ where
}
}
pub fn fancy_error<E: Error + 'static>(templates: Templates) -> impl Fn(E) -> FancyError {
pub fn fancy_error<E: std::fmt::Display + 'static>(
templates: Templates,
) -> impl Fn(E) -> FancyError {
move |error: E| FancyError {
templates: Some(templates.clone()),
error: Box::new(error),
@@ -69,7 +71,7 @@ where
pub struct FancyError {
templates: Option<Templates>,
error: Box<dyn Error>,
error: Box<dyn std::fmt::Display>,
}
impl IntoResponse for FancyError {
@@ -99,4 +101,3 @@ impl IntoResponse for FancyError {
res
}
}