diff --git a/Cargo.lock b/Cargo.lock index bbbdd4f2..c4ac6c78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -488,9 +488,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.4.8" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9f346c92c1e9a71d14fe4aaf7c2a5d9932cc4e5e48d8fb6641524416eb79ddd" +checksum = "47594e438a243791dba58124b6669561f5baa14cb12046641d8008bf035e5a25" dependencies = [ "async-trait", "axum-core", @@ -501,6 +501,7 @@ dependencies = [ "http", "http-body", "hyper", + "itoa 1.0.1", "matchit", "memchr", "mime", @@ -519,9 +520,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.1.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbcda393bef9c87572779cb8ef916f12d77750b27535dd6819fa86591627a51" +checksum = "9a671c9ae99531afdd5d3ee8340b8da547779430689947144c140fc74a740244" dependencies = [ "async-trait", "bytes 1.1.0", @@ -2282,9 +2283,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "matchit" -version = "0.4.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9376a4f0340565ad675d11fc1419227faf5f60cd7ac9cb2e7185a471f30af833" +checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" [[package]] name = "md-5" diff --git a/crates/axum-utils/Cargo.toml b/crates/axum-utils/Cargo.toml index ce408087..7c4e174d 100644 --- a/crates/axum-utils/Cargo.toml +++ b/crates/axum-utils/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" [dependencies] async-trait = "0.1.52" -axum = { version = "0.4.8", features = ["headers"] } +axum = { version = "0.5.1", features = ["headers"] } bincode = "1.3.3" chrono = "0.4.19" cookie = { version = "0.16.0", features = ["signed", "private", "percent-encode"] } diff --git a/crates/axum-utils/src/client_authorization.rs b/crates/axum-utils/src/client_authorization.rs index 2e75856f..e9e4b8f4 100644 --- a/crates/axum-utils/src/client_authorization.rs +++ b/crates/axum-utils/src/client_authorization.rs @@ -223,9 +223,7 @@ where // If it's missing it is fine TypedHeaderRejectionReason::Missing => None, // If the header could not be parsed, return the error - TypedHeaderRejectionReason::Error(_) => { - return Err(ClientAuthorizationError::InvalidHeader) - } + _ => return Err(ClientAuthorizationError::InvalidHeader), }, }; diff --git a/crates/axum-utils/src/cookies.rs b/crates/axum-utils/src/cookies.rs index a6b867c6..32bb1034 100644 --- a/crates/axum-utils/src/cookies.rs +++ b/crates/axum-utils/src/cookies.rs @@ -14,10 +14,13 @@ //! Private (encrypted) cookie jar, based on axum-extra's cookie jar -use std::marker::PhantomData; +use std::{convert::Infallible, marker::PhantomData}; use async_trait::async_trait; -use axum::extract::{Extension, FromRequest, RequestParts}; +use axum::{ + extract::{Extension, FromRequest, RequestParts}, + response::IntoResponseParts, +}; pub use cookie::Cookie; use data_encoding::BASE64URL_NOPAD; use headers::HeaderMap; @@ -68,12 +71,6 @@ impl PrivateCookieJar { } } } - - pub fn headers(self) -> HeaderMap { - let mut headers = HeaderMap::new(); - self.set_cookies(&mut headers); - headers - } } #[async_trait] @@ -91,13 +88,8 @@ where let mut jar = cookie::CookieJar::new(); let mut private_jar = jar.private_mut(&key); - // TODO: remove this when axum 0.5 gets released - // https://github.com/tokio-rs/axum/pull/698 - let empty_headers = HeaderMap::new(); - let cookies = req .headers() - .unwrap_or(&empty_headers) .get_all(COOKIE) .into_iter() .filter_map(|value| value.to_str().ok()) @@ -118,6 +110,17 @@ where } } +impl IntoResponseParts for PrivateCookieJar { + type Error = Infallible; + fn into_response_parts( + self, + mut res: axum::response::ResponseParts, + ) -> Result { + self.set_cookies(res.headers_mut()); + Ok(res) + } +} + #[derive(Debug, Error)] #[error("could not decode cookie")] pub enum CookieDecodeError { diff --git a/crates/axum-utils/src/user_authorization.rs b/crates/axum-utils/src/user_authorization.rs index d9dc7cf1..87bd1e9e 100644 --- a/crates/axum-utils/src/user_authorization.rs +++ b/crates/axum-utils/src/user_authorization.rs @@ -287,9 +287,7 @@ where // If it's missing it is fine TypedHeaderRejectionReason::Missing => None, // If the header could not be parsed, return the error - TypedHeaderRejectionReason::Error(_) => { - return Err(UserAuthorizationError::InvalidHeader) - } + _ => return Err(UserAuthorizationError::InvalidHeader), }, }; diff --git a/crates/handlers/Cargo.toml b/crates/handlers/Cargo.toml index 0636e9fc..3b362049 100644 --- a/crates/handlers/Cargo.toml +++ b/crates/handlers/Cargo.toml @@ -22,7 +22,7 @@ anyhow = "1.0.56" # Web server hyper = { version = "0.14.17", features = ["full"] } tower = "0.4.12" -axum = "0.4.8" +axum = "0.5.1" axum-macros = "0.2.0" # Emails diff --git a/crates/handlers/src/oauth2/authorization.rs b/crates/handlers/src/oauth2/authorization.rs index 47a53e38..a837f7fd 100644 --- a/crates/handlers/src/oauth2/authorization.rs +++ b/crates/handlers/src/oauth2/authorization.rs @@ -149,12 +149,8 @@ where .context("could not serialize redirect URI query params")?; redirect_uri.set_query(Some(&new_qs)); - let redirect_uri = redirect_uri - .as_str() - .parse() - .context("could not convert redirect URI")?; - Ok(Redirect::to(redirect_uri).into_response()) + Ok(Redirect::to(redirect_uri.as_str()).into_response()) } ResponseMode::Fragment => { let existing: Option> = redirect_uri @@ -173,12 +169,8 @@ where .context("could not serialize redirect URI fragment params")?; redirect_uri.set_fragment(Some(&new_qs)); - let redirect_uri = redirect_uri - .as_str() - .parse() - .context("could not convert redirect URI")?; - Ok(Redirect::to(redirect_uri).into_response()) + Ok(Redirect::to(redirect_uri.as_str()).into_response()) } ResponseMode::FormPost => { let merged = ParamsWithState { state, params }; @@ -389,7 +381,7 @@ pub(crate) async fn get( let next: ReauthRequest = next.into(); let next = next.build_uri()?; - Ok(Redirect::to(next).into_response()) + Ok(Redirect::to(&next.to_string()).into_response()) } (Some(user_session), _) => { // Other cases where we already have a session @@ -403,7 +395,7 @@ pub(crate) async fn get( let next: RegisterRequest = next.into(); let next = next.build_uri()?; - Ok(Redirect::to(next).into_response()) + Ok(Redirect::to(&next.to_string()).into_response()) } (None, _) => { // Other cases where we don't have a session, ask for a login @@ -413,7 +405,7 @@ pub(crate) async fn get( let next: LoginRequest = next.into(); let next = next.build_uri()?; - Ok(Redirect::to(next).into_response()) + Ok(Redirect::to(&next.to_string()).into_response()) } } }) @@ -424,7 +416,7 @@ pub(crate) async fn get( Err(_e) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), }; - Ok((cookie_jar.headers(), response).into_response()) + Ok((cookie_jar, response).into_response()) } #[derive(Serialize, Deserialize, Clone)] @@ -486,7 +478,7 @@ pub(crate) async fn step_get( let next: PostAuthAction = next.into(); let login: LoginRequest = next.into(); let login = login.build_uri()?; - return Ok((cookie_jar.headers(), Redirect::to(login)).into_response()); + return Ok((cookie_jar, Redirect::to(&login.to_string())).into_response()); }; step(next, session, txn, &templates).await @@ -565,7 +557,7 @@ async fn step( let next: ReauthRequest = next.into(); let next = next.build_uri()?; - Redirect::to(next).into_response() + Redirect::to(&next.to_string()).into_response() } }; diff --git a/crates/handlers/src/views/account/emails.rs b/crates/handlers/src/views/account/emails.rs index d2d9e15e..7dac5e70 100644 --- a/crates/handlers/src/views/account/emails.rs +++ b/crates/handlers/src/views/account/emails.rs @@ -70,7 +70,7 @@ pub(crate) async fn get( } else { let login = LoginRequest::default(); let login = login.build_uri().map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), Redirect::to(login)).into_response()) + Ok((cookie_jar, Redirect::to(&login.to_string())).into_response()) } } @@ -95,7 +95,7 @@ async fn render( .await .map_err(fancy_error(templates))?; - Ok((cookie_jar.headers(), Html(content)).into_response()) + Ok((cookie_jar, Html(content)).into_response()) } async fn start_email_verification( @@ -151,7 +151,7 @@ pub(crate) async fn post( } else { let login = LoginRequest::default(); let login = login.build_uri().map_err(fancy_error(templates.clone()))?; - return Ok((cookie_jar.headers(), Redirect::to(login)).into_response()); + return Ok((cookie_jar, Redirect::to(&login.to_string())).into_response()); }; let form = cookie_jar diff --git a/crates/handlers/src/views/account/mod.rs b/crates/handlers/src/views/account/mod.rs index 8c0fdced..48212061 100644 --- a/crates/handlers/src/views/account/mod.rs +++ b/crates/handlers/src/views/account/mod.rs @@ -50,7 +50,7 @@ pub(crate) async fn get( } else { let login = LoginRequest::default(); let login = login.build_uri().map_err(fancy_error(templates.clone()))?; - return Ok((cookie_jar.headers(), Redirect::to(login)).into_response()); + return Ok((cookie_jar, Redirect::to(&login.to_string())).into_response()); }; let active_sessions = count_active_sessions(&mut conn, &session.user) @@ -70,5 +70,5 @@ pub(crate) async fn get( .await .map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), Html(content)).into_response()) + Ok((cookie_jar, Html(content)).into_response()) } diff --git a/crates/handlers/src/views/account/password.rs b/crates/handlers/src/views/account/password.rs index dfd37715..8bdaec5b 100644 --- a/crates/handlers/src/views/account/password.rs +++ b/crates/handlers/src/views/account/password.rs @@ -62,7 +62,7 @@ pub(crate) async fn get( } else { let login = LoginRequest::default(); let login = login.build_uri().map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), Redirect::to(login)).into_response()) + Ok((cookie_jar, Redirect::to(&login.to_string())).into_response()) } } @@ -82,7 +82,7 @@ async fn render( .await .map_err(fancy_error(templates))?; - Ok((cookie_jar.headers(), Html(content)).into_response()) + Ok((cookie_jar, Html(content)).into_response()) } pub(crate) async fn post( @@ -109,7 +109,7 @@ pub(crate) async fn post( } else { let login = LoginRequest::default(); let login = login.build_uri().map_err(fancy_error(templates.clone()))?; - return Ok((cookie_jar.headers(), Redirect::to(login)).into_response()); + return Ok((cookie_jar, Redirect::to(&login.to_string())).into_response()); }; authenticate_session(&mut txn, &mut session, form.current_password) diff --git a/crates/handlers/src/views/index.rs b/crates/handlers/src/views/index.rs index a616d6ec..19578296 100644 --- a/crates/handlers/src/views/index.rs +++ b/crates/handlers/src/views/index.rs @@ -50,5 +50,5 @@ pub async fn get( .await .map_err(fancy_error(templates))?; - Ok((cookie_jar.headers(), Html(content))) + Ok((cookie_jar, Html(content))) } diff --git a/crates/handlers/src/views/login.rs b/crates/handlers/src/views/login.rs index 428d6d68..ade09e93 100644 --- a/crates/handlers/src/views/login.rs +++ b/crates/handlers/src/views/login.rs @@ -71,7 +71,7 @@ impl LoginRequest { Uri::from_static("/") }; - Ok(Redirect::to(uri)) + Ok(Redirect::to(&uri.to_string())) } } @@ -129,7 +129,7 @@ pub(crate) async fn get( .await .map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), Html(content)).into_response()) + Ok((cookie_jar, Html(content)).into_response()) } } @@ -157,7 +157,7 @@ pub(crate) async fn post( Ok(session_info) => { let cookie_jar = cookie_jar.set_session(&session_info); let reply = query.redirect().map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), reply).into_response()) + Ok((cookie_jar, reply).into_response()) } Err(e) => { let errored_form = match e { @@ -174,7 +174,7 @@ pub(crate) async fn post( .await .map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), Html(content)).into_response()) + Ok((cookie_jar, Html(content)).into_response()) } } } diff --git a/crates/handlers/src/views/logout.rs b/crates/handlers/src/views/logout.rs index 883e1e7e..d011091c 100644 --- a/crates/handlers/src/views/logout.rs +++ b/crates/handlers/src/views/logout.rs @@ -16,7 +16,6 @@ use axum::{ extract::{Extension, Form}, response::{IntoResponse, Redirect}, }; -use hyper::Uri; use mas_axum_utils::{ csrf::{CsrfExt, ProtectedForm}, fancy_error, FancyError, PrivateCookieJar, SessionInfoExt, @@ -54,6 +53,5 @@ pub(crate) async fn post( txn.commit().await.map_err(fancy_error(templates))?; - let to = Uri::from_static("/login"); - Ok((cookie_jar.headers(), Redirect::to(to))) + Ok((cookie_jar, Redirect::to("/login"))) } diff --git a/crates/handlers/src/views/reauth.rs b/crates/handlers/src/views/reauth.rs index 6ebb6633..451b774c 100644 --- a/crates/handlers/src/views/reauth.rs +++ b/crates/handlers/src/views/reauth.rs @@ -63,13 +63,11 @@ impl ReauthRequest { } fn redirect(self) -> Result { - let uri = if let Some(action) = self.post_auth_action { - action.build_uri()? + if let Some(action) = self.post_auth_action { + Ok(Redirect::to(&action.build_uri()?.to_string())) } else { - Uri::from_static("/") - }; - - Ok(Redirect::to(uri)) + Ok(Redirect::to("/")) + } } } @@ -104,7 +102,7 @@ pub(crate) async fn get( // PostAuthAction let login: LoginRequest = query.post_auth_action.into(); let login = login.build_uri().map_err(fancy_error(templates.clone()))?; - return Ok((cookie_jar.headers(), Redirect::to(login)).into_response()); + return Ok((cookie_jar, Redirect::to(&login.to_string())).into_response()); }; let ctx = ReauthContext::default(); @@ -125,7 +123,7 @@ pub(crate) async fn get( .await .map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), Html(content)).into_response()) + Ok((cookie_jar, Html(content)).into_response()) } pub(crate) async fn post( @@ -155,7 +153,7 @@ pub(crate) async fn post( // PostAuthAction let login: LoginRequest = query.post_auth_action.into(); let login = login.build_uri().map_err(fancy_error(templates.clone()))?; - return Ok((cookie_jar.headers(), Redirect::to(login)).into_response()); + return Ok((cookie_jar, Redirect::to(&login.to_string())).into_response()); }; // TODO: recover from errors here @@ -166,5 +164,5 @@ pub(crate) async fn post( txn.commit().await.map_err(fancy_error(templates.clone()))?; let redirection = query.redirect().map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), redirection).into_response()) + Ok((cookie_jar, redirection).into_response()) } diff --git a/crates/handlers/src/views/register.rs b/crates/handlers/src/views/register.rs index 722d4a69..89a3abf7 100644 --- a/crates/handlers/src/views/register.rs +++ b/crates/handlers/src/views/register.rs @@ -64,13 +64,11 @@ impl RegisterRequest { } fn redirect(self) -> Result { - let uri = if let Some(action) = self.post_auth_action { - action.build_uri()? + if let Some(action) = self.post_auth_action { + Ok(Redirect::to(&action.build_uri()?.to_string())) } else { - Uri::from_static("/") - }; - - Ok(Redirect::to(uri)) + Ok(Redirect::to("/")) + } } } @@ -129,7 +127,7 @@ pub(crate) async fn get( .await .map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), Html(content)).into_response()) + Ok((cookie_jar, Html(content)).into_response()) } } @@ -164,5 +162,5 @@ pub(crate) async fn post( let cookie_jar = cookie_jar.set_session(&session); let reply = query.redirect().map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), reply).into_response()) + Ok((cookie_jar, reply).into_response()) } diff --git a/crates/handlers/src/views/verify.rs b/crates/handlers/src/views/verify.rs index 06e235f9..71aee768 100644 --- a/crates/handlers/src/views/verify.rs +++ b/crates/handlers/src/views/verify.rs @@ -66,5 +66,5 @@ pub(crate) async fn get( txn.commit().await.map_err(fancy_error(templates.clone()))?; - Ok((cookie_jar.headers(), Html(content))) + Ok((cookie_jar, Html(content))) } diff --git a/crates/static-files/Cargo.toml b/crates/static-files/Cargo.toml index 3f8c2469..853f90a9 100644 --- a/crates/static-files/Cargo.toml +++ b/crates/static-files/Cargo.toml @@ -9,7 +9,7 @@ license = "Apache-2.0" dev = [] [dependencies] -axum = "0.4.8" +axum = "0.5.1" headers = "0.3.7" http = "0.2.6" mime_guess = "2.0.4"