diff --git a/Cargo.lock b/Cargo.lock index 6c18ea3be..f3f51e73a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,7 +175,7 @@ dependencies = [ "log", "pin-project-lite", "serde", - "strum", + "strum 0.25.0", "thiserror", "tokio", "tower", @@ -303,23 +303,23 @@ dependencies = [ [[package]] name = "async-graphql" -version = "6.0.11" +version = "7.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298a5d587d6e6fdb271bf56af2dc325a80eb291fd0fc979146584b9a05494a8c" +checksum = "bf338d20ba5bab309f55ce8df95d65ee19446f7737f06f4a64593ab2c6b546ad" dependencies = [ "async-graphql-derive", "async-graphql-parser", "async-graphql-value", "async-stream", "async-trait", - "base64 0.13.1", + "base64 0.22.1", "bytes", "chrono", "fast_chemail", "fnv", "futures-util", "handlebars", - "http 0.2.12", + "http 1.1.0", "indexmap 2.2.6", "mime", "multer", @@ -330,7 +330,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "static_assertions", + "static_assertions_next", "tempfile", "thiserror", "tracing", @@ -340,9 +340,9 @@ dependencies = [ [[package]] name = "async-graphql-derive" -version = "6.0.11" +version = "7.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f329c7eb9b646a72f70c9c4b516c70867d356ec46cb00dcac8ad343fd006b0" +checksum = "fc51fd6b7102acda72bc94e8ae1543844d5688ff394a6cf7c21f2a07fe2d64e4" dependencies = [ "Inflector", "async-graphql-parser", @@ -350,16 +350,16 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "strum", + "strum 0.26.3", "syn 2.0.68", "thiserror", ] [[package]] name = "async-graphql-parser" -version = "6.0.11" +version = "7.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6139181845757fd6a73fbb8839f3d036d7150b798db0e9bb3c6e83cdd65bd53b" +checksum = "75361eefd64e39f89bead4cb45fddbaf60ddb0e7b15fb7c852b6088bcd63071f" dependencies = [ "async-graphql-value", "pest", @@ -369,9 +369,9 @@ dependencies = [ [[package]] name = "async-graphql-value" -version = "6.0.11" +version = "7.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323a5143f5bdd2030f45e3f2e0c821c9b1d36e79cf382129c64299c50a7f3750" +checksum = "c1f665d2d52b41c4ed1f01c43f3ef27a2fe0af2452ed5c8bc7ac9b1a8719afaa" dependencies = [ "bytes", "indexmap 2.2.6", @@ -707,12 +707,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.7" @@ -2158,9 +2152,9 @@ dependencies = [ [[package]] name = "handlebars" -version = "4.5.0" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" dependencies = [ "log", "pest", @@ -3360,6 +3354,7 @@ dependencies = [ "psl", "rand", "rand_chacha", + "rustls 0.23.10", "sentry", "serde", "serde_json", @@ -3909,16 +3904,15 @@ checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" [[package]] name = "multer" -version = "2.1.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" dependencies = [ "bytes", "encoding_rs", "futures-util", - "http 0.2.12", + "http 1.1.0", "httparse", - "log", "memchr", "mime", "spin", @@ -4732,11 +4726,10 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "once_cell", "toml_edit", ] @@ -6045,10 +6038,10 @@ dependencies = [ ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "static_assertions_next" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766" [[package]] name = "stringprep" @@ -6073,7 +6066,16 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "strum_macros", + "strum_macros 0.25.3", +] + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", ] [[package]] @@ -6089,6 +6091,19 @@ dependencies = [ "syn 2.0.68", ] +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.68", +] + [[package]] name = "subtle" version = "2.6.1" @@ -6361,9 +6376,9 @@ checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.6", "toml_datetime", diff --git a/Cargo.toml b/Cargo.toml index b002bed1d..3e5f52c13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ oauth2-types = { path = "./crates/oauth2-types/", version = "=0.9.0" } # GraphQL server [workspace.dependencies.async-graphql] -version = "6.0.11" +version = "7.0.6" features = ["chrono", "url", "tracing"] # Utility to write and implement async traits diff --git a/crates/axum-utils/src/client_authorization.rs b/crates/axum-utils/src/client_authorization.rs index d716b0dc9..d4217430c 100644 --- a/crates/axum-utils/src/client_authorization.rs +++ b/crates/axum-utils/src/client_authorization.rs @@ -489,7 +489,7 @@ where #[cfg(test)] mod tests { - use axum::body::{Bytes, Full}; + use axum::body::Body; use http::{Method, Request}; use super::*; @@ -502,7 +502,7 @@ mod tests { http::header::CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref(), ) - .body(Full::::new("client_id=client-id&foo=bar".into())) + .body(Body::new("client_id=client-id&foo=bar".to_owned())) .unwrap(); assert_eq!( @@ -530,7 +530,7 @@ mod tests { http::header::AUTHORIZATION, "Basic Y2xpZW50LWlkOmNsaWVudC1zZWNyZXQ=", ) - .body(Full::::new("foo=bar".into())) + .body(Body::new("foo=bar".to_owned())) .unwrap(); assert_eq!( @@ -557,7 +557,7 @@ mod tests { http::header::AUTHORIZATION, "Basic Y2xpZW50LWlkOmNsaWVudC1zZWNyZXQ=", ) - .body(Full::::new("client_id=client-id&foo=bar".into())) + .body(Body::new("client_id=client-id&foo=bar".to_owned())) .unwrap(); assert_eq!( @@ -584,7 +584,7 @@ mod tests { http::header::AUTHORIZATION, "Basic Y2xpZW50LWlkOmNsaWVudC1zZWNyZXQ=", ) - .body(Full::::new("client_id=mismatch-id&foo=bar".into())) + .body(Body::new("client_id=mismatch-id&foo=bar".to_owned())) .unwrap(); assert!(matches!( @@ -600,7 +600,7 @@ mod tests { mime::APPLICATION_WWW_FORM_URLENCODED.as_ref(), ) .header(http::header::AUTHORIZATION, "Basic invalid") - .body(Full::::new("foo=bar".into())) + .body(Body::new("foo=bar".to_owned())) .unwrap(); assert!(matches!( @@ -617,8 +617,8 @@ mod tests { http::header::CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref(), ) - .body(Full::::new( - "client_id=client-id&client_secret=client-secret&foo=bar".into(), + .body(Body::new( + "client_id=client-id&client_secret=client-secret&foo=bar".to_owned(), )) .unwrap(); @@ -640,7 +640,7 @@ mod tests { async fn client_assertion_test() { // Signed with client_secret = "client-secret" let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnQtaWQiLCJzdWIiOiJjbGllbnQtaWQiLCJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tL29hdXRoMi9pbnRyb3NwZWN0IiwianRpIjoiYWFiYmNjIiwiZXhwIjoxNTE2MjM5MzIyLCJpYXQiOjE1MTYyMzkwMjJ9.XTaACG_Rww0GPecSZvkbem-AczNy9LLNBueCLCiQajU"; - let body = Bytes::from(format!( + let body = Body::new(format!( "client_assertion_type={JWT_BEARER_CLIENT_ASSERTION}&client_assertion={jwt}&foo=bar", )); @@ -650,7 +650,7 @@ mod tests { http::header::CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref(), ) - .body(Full::new(body)) + .body(body) .unwrap(); let authz = ClientAuthorization::::from_request(req, &()) diff --git a/crates/handlers/Cargo.toml b/crates/handlers/Cargo.toml index 98b2c7281..398ff9ddb 100644 --- a/crates/handlers/Cargo.toml +++ b/crates/handlers/Cargo.toml @@ -34,6 +34,7 @@ tower-http.workspace = true axum.workspace = true axum-macros = "0.4.1" axum-extra.workspace = true +rustls.workspace = true async-graphql.workspace = true diff --git a/crates/handlers/src/compat/login.rs b/crates/handlers/src/compat/login.rs index f7766a419..749314ee4 100644 --- a/crates/handlers/src/compat/login.rs +++ b/crates/handlers/src/compat/login.rs @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use axum::{extract::State, response::IntoResponse, Json, TypedHeader}; +use axum::{extract::State, response::IntoResponse, Json}; +use axum_extra::typed_header::TypedHeader; use chrono::Duration; use hyper::StatusCode; use mas_axum_utils::sentry::SentryEventID; @@ -433,12 +434,12 @@ mod tests { use sqlx::PgPool; use super::*; - use crate::test_utils::{init_tracing, RequestBuilderExt, ResponseExt, TestState}; + use crate::test_utils::{setup, RequestBuilderExt, ResponseExt, TestState}; /// Test that the server advertises the right login flows. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_get_login(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Now let's get the login flows @@ -470,7 +471,7 @@ mod tests { /// manager is disabled #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_password_disabled(pool: PgPool) { - init_tracing(); + setup(); let state = { let mut state = TestState::from_pool(pool).await.unwrap(); state.password_manager = PasswordManager::disabled(); @@ -518,7 +519,7 @@ mod tests { /// compatibility API. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_user_password_login(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Let's provision a user and add a password to it. This part is hard to test @@ -633,7 +634,7 @@ mod tests { /// Test the response of an unsupported login flow. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_unsupported_login(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Try to login with an unsupported login flow. @@ -650,7 +651,7 @@ mod tests { /// Test `m.login.token` login flow. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_login_token_login(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a user diff --git a/crates/handlers/src/compat/logout.rs b/crates/handlers/src/compat/logout.rs index f74fe45e8..55fb20664 100644 --- a/crates/handlers/src/compat/logout.rs +++ b/crates/handlers/src/compat/logout.rs @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use axum::{response::IntoResponse, Json, TypedHeader}; +use axum::{response::IntoResponse, Json}; +use axum_extra::typed_header::TypedHeader; use headers::{authorization::Bearer, Authorization}; use hyper::StatusCode; use mas_axum_utils::sentry::SentryEventID; diff --git a/crates/handlers/src/graphql/mod.rs b/crates/handlers/src/graphql/mod.rs index 1ea288080..12dbfebe7 100644 --- a/crates/handlers/src/graphql/mod.rs +++ b/crates/handlers/src/graphql/mod.rs @@ -23,11 +23,13 @@ use async_graphql::{ }; use axum::{ async_trait, - extract::{BodyStream, RawQuery, State as AxumState}, + body::Body, + extract::{RawQuery, State as AxumState}, http::StatusCode, response::{Html, IntoResponse, Response}, - Json, TypedHeader, + Json, }; +use axum_extra::typed_header::TypedHeader; use futures_util::TryStreamExt; use headers::{authorization::Bearer, Authorization, ContentType, HeaderValue}; use hyper::header::CACHE_CONTROL; @@ -286,8 +288,9 @@ pub async fn post( cookie_jar: CookieJar, content_type: Option>, authorization: Option>>, - body: BodyStream, + body: Body, ) -> Result { + let body = body.into_data_stream(); let token = authorization .as_ref() .map(|TypedHeader(Authorization(bearer))| bearer.token()); diff --git a/crates/handlers/src/graphql/tests.rs b/crates/handlers/src/graphql/tests.rs index 64a3db4c1..463abb61d 100644 --- a/crates/handlers/src/graphql/tests.rs +++ b/crates/handlers/src/graphql/tests.rs @@ -29,7 +29,7 @@ use sqlx::PgPool; use crate::{ test_utils, - test_utils::{init_tracing, RequestBuilderExt, ResponseExt, TestState}, + test_utils::{setup, RequestBuilderExt, ResponseExt, TestState}, }; async fn create_test_client(state: &TestState) -> Client { @@ -131,7 +131,7 @@ struct GraphQLResponse { /// Test that the GraphQL endpoint can be queried with a GET request. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_get(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let request = Request::get("/graphql?query={viewer{__typename}}").empty(); @@ -155,7 +155,7 @@ async fn test_get(pool: PgPool) { /// anonymously. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_anonymous_viewer(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let req = Request::post("/graphql").json(serde_json::json!({ @@ -186,7 +186,7 @@ async fn test_anonymous_viewer(pool: PgPool) { /// Test that the GraphQL endpoint can be authenticated with a bearer token. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_oauth2_viewer(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Start by creating a user, a client and a token @@ -203,7 +203,7 @@ async fn test_oauth2_viewer(pool: PgPool) { query { viewer { __typename - + ... on User { id username @@ -233,7 +233,7 @@ async fn test_oauth2_viewer(pool: PgPool) { /// Test that the GraphQL endpoint requires the GraphQL scope. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_oauth2_no_scope(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Start by creating a user, a client and a token @@ -271,7 +271,7 @@ async fn test_oauth2_no_scope(pool: PgPool) { /// Test the admin scope on the GraphQL endpoint. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_oauth2_admin(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Start by creating a user, a client and two tokens @@ -301,7 +301,7 @@ async fn test_oauth2_admin(pool: PgPool) { username } } - ", + ", "variables": { "id": format!("user:{id}", id = user2.id), }, @@ -331,7 +331,7 @@ async fn test_oauth2_admin(pool: PgPool) { username } } - ", + ", "variables": { "id": format!("user:{id}", id = user2.id), }, @@ -358,7 +358,7 @@ async fn test_oauth2_admin(pool: PgPool) { /// client_credentials grant. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_oauth2_client_credentials(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client @@ -397,7 +397,7 @@ async fn test_oauth2_client_credentials(pool: PgPool) { viewer { __typename } - + viewerSession { __typename } @@ -464,7 +464,7 @@ async fn test_oauth2_client_credentials(pool: PgPool) { viewer { __typename } - + viewerSession { __typename } @@ -572,7 +572,7 @@ async fn test_oauth2_client_credentials(pool: PgPool) { /// Test the addUser mutation #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_add_user(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client diff --git a/crates/handlers/src/lib.rs b/crates/handlers/src/lib.rs index 51f3185e1..bc7def815 100644 --- a/crates/handlers/src/lib.rs +++ b/crates/handlers/src/lib.rs @@ -26,11 +26,10 @@ use std::{convert::Infallible, time::Duration}; use axum::{ - body::{Bytes, HttpBody}, extract::{FromRef, FromRequestParts, OriginalUri, RawQuery, State}, http::Method, response::{Html, IntoResponse}, - routing::{get, on, post, MethodFilter}, + routing::{get, post}, Router, }; use headers::HeaderName; @@ -97,20 +96,16 @@ pub use self::{ upstream_oauth2::cache::MetadataCache, }; -pub fn healthcheck_router() -> Router +pub fn healthcheck_router() -> Router where - B: HttpBody + Send + 'static, S: Clone + Send + Sync + 'static, PgPool: FromRef, { Router::new().route(mas_router::Healthcheck::route(), get(self::health::get)) } -pub fn graphql_router(playground: bool) -> Router +pub fn graphql_router(playground: bool) -> Router where - B: HttpBody + Send + 'static, - ::Data: Into, - ::Error: std::error::Error + Send + Sync, S: Clone + Send + Sync + 'static, graphql::Schema: FromRef, BoundActivityTracker: FromRequestParts, @@ -147,9 +142,8 @@ where router } -pub fn discovery_router() -> Router +pub fn discovery_router() -> Router where - B: HttpBody + Send + 'static, S: Clone + Send + Sync + 'static, Keystore: FromRef, SiteConfig: FromRef, @@ -181,11 +175,8 @@ where ) } -pub fn api_router() -> Router +pub fn api_router() -> Router where - B: HttpBody + Send + 'static, - ::Data: Send, - ::Error: std::error::Error + Send + Sync, S: Clone + Send + Sync + 'static, Keystore: FromRef, UrlBuilder: FromRef, @@ -207,10 +198,7 @@ where ) .route( mas_router::OidcUserinfo::route(), - on( - MethodFilter::POST | MethodFilter::GET, - self::oauth2::userinfo::get, - ), + get(self::oauth2::userinfo::get).post(self::oauth2::userinfo::get), ) .route( mas_router::OAuth2Introspection::route(), @@ -248,11 +236,8 @@ where } #[allow(clippy::trait_duplication_in_bounds)] -pub fn compat_router() -> Router +pub fn compat_router() -> Router where - B: HttpBody + Send + 'static, - ::Data: Send, - ::Error: std::error::Error + Send + Sync, S: Clone + Send + Sync + 'static, UrlBuilder: FromRef, SiteConfig: FromRef, @@ -305,11 +290,8 @@ where } #[allow(clippy::too_many_lines)] -pub fn human_router(templates: Templates) -> Router +pub fn human_router(templates: Templates) -> Router where - B: HttpBody + Send + 'static, - ::Data: Send, - ::Error: std::error::Error + Send + Sync, S: Clone + Send + Sync + 'static, UrlBuilder: FromRef, PreferredLanguage: FromRequestParts, diff --git a/crates/handlers/src/oauth2/device/authorize.rs b/crates/handlers/src/oauth2/device/authorize.rs index 4cc9ed8b1..594253910 100644 --- a/crates/handlers/src/oauth2/device/authorize.rs +++ b/crates/handlers/src/oauth2/device/authorize.rs @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use axum::{extract::State, response::IntoResponse, Json, TypedHeader}; +use axum::{extract::State, response::IntoResponse, Json}; +use axum_extra::typed_header::TypedHeader; use chrono::Duration; use headers::{CacheControl, Pragma}; use hyper::StatusCode; @@ -177,11 +178,11 @@ mod tests { }; use sqlx::PgPool; - use crate::test_utils::{init_tracing, RequestBuilderExt, ResponseExt, TestState}; + use crate::test_utils::{setup, RequestBuilderExt, ResponseExt, TestState}; #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_device_code_request(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client diff --git a/crates/handlers/src/oauth2/discovery.rs b/crates/handlers/src/oauth2/discovery.rs index d1e09aaf4..80a543284 100644 --- a/crates/handlers/src/oauth2/discovery.rs +++ b/crates/handlers/src/oauth2/discovery.rs @@ -206,11 +206,11 @@ mod tests { use oauth2_types::oidc::ProviderMetadata; use sqlx::PgPool; - use crate::test_utils::{init_tracing, RequestBuilderExt, ResponseExt, TestState}; + use crate::test_utils::{setup, RequestBuilderExt, ResponseExt, TestState}; #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_valid_discovery_metadata(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let request = Request::get("/.well-known/openid-configuration").empty(); diff --git a/crates/handlers/src/oauth2/introspection.rs b/crates/handlers/src/oauth2/introspection.rs index cec375068..44eff0cdc 100644 --- a/crates/handlers/src/oauth2/introspection.rs +++ b/crates/handlers/src/oauth2/introspection.rs @@ -474,12 +474,12 @@ mod tests { use crate::{ oauth2::generate_token_pair, - test_utils::{init_tracing, RequestBuilderExt, ResponseExt, TestState}, + test_utils::{setup, RequestBuilderExt, ResponseExt, TestState}, }; #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_introspect_oauth_tokens(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client which will be used to do introspection requests @@ -678,7 +678,7 @@ mod tests { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_introspect_compat_tokens(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client which will be used to do introspection requests diff --git a/crates/handlers/src/oauth2/registration.rs b/crates/handlers/src/oauth2/registration.rs index 5b493b144..5600f7a26 100644 --- a/crates/handlers/src/oauth2/registration.rs +++ b/crates/handlers/src/oauth2/registration.rs @@ -317,7 +317,7 @@ mod tests { use crate::{ oauth2::registration::host_is_public_suffix, - test_utils::{init_tracing, RequestBuilderExt, ResponseExt, TestState}, + test_utils::{setup, RequestBuilderExt, ResponseExt, TestState}, }; #[test] @@ -342,7 +342,7 @@ mod tests { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_registration_error(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Body is not a JSON @@ -439,7 +439,7 @@ mod tests { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_registration(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // A successful registration with no authentication should not return a client diff --git a/crates/handlers/src/oauth2/revoke.rs b/crates/handlers/src/oauth2/revoke.rs index 9e2d4c79a..ff725df32 100644 --- a/crates/handlers/src/oauth2/revoke.rs +++ b/crates/handlers/src/oauth2/revoke.rs @@ -258,12 +258,12 @@ mod tests { use super::*; use crate::{ oauth2::generate_token_pair, - test_utils::{init_tracing, RequestBuilderExt, ResponseExt, TestState}, + test_utils::{setup, RequestBuilderExt, ResponseExt, TestState}, }; #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_revoke_access_token(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let request = diff --git a/crates/handlers/src/oauth2/token.rs b/crates/handlers/src/oauth2/token.rs index a11aab359..79e95a4b8 100644 --- a/crates/handlers/src/oauth2/token.rs +++ b/crates/handlers/src/oauth2/token.rs @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use axum::{extract::State, response::IntoResponse, Json, TypedHeader}; +use axum::{extract::State, response::IntoResponse, Json}; +use axum_extra::typed_header::TypedHeader; use chrono::Duration; use headers::{CacheControl, HeaderMap, HeaderMapExt, Pragma}; use hyper::StatusCode; @@ -781,11 +782,11 @@ mod tests { use sqlx::PgPool; use super::*; - use crate::test_utils::{init_tracing, RequestBuilderExt, ResponseExt, TestState}; + use crate::test_utils::{setup, RequestBuilderExt, ResponseExt, TestState}; #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_auth_code_grant(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client @@ -995,7 +996,7 @@ mod tests { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_refresh_token_grant(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client @@ -1118,7 +1119,7 @@ mod tests { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_client_credentials(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client @@ -1245,7 +1246,7 @@ mod tests { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_device_code_grant(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client @@ -1431,7 +1432,7 @@ mod tests { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_unsupported_grant(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); // Provision a client diff --git a/crates/handlers/src/oauth2/webfinger.rs b/crates/handlers/src/oauth2/webfinger.rs index 7f925d15f..4904442cb 100644 --- a/crates/handlers/src/oauth2/webfinger.rs +++ b/crates/handlers/src/oauth2/webfinger.rs @@ -15,8 +15,9 @@ use axum::{ extract::{Query, State}, response::IntoResponse, - Json, TypedHeader, + Json, }; +use axum_extra::typed_header::TypedHeader; use headers::ContentType; use mas_router::UrlBuilder; use oauth2_types::webfinger::WebFingerResponse; diff --git a/crates/handlers/src/preferred_language.rs b/crates/handlers/src/preferred_language.rs index 0e21b1fc4..1ec12495d 100644 --- a/crates/handlers/src/preferred_language.rs +++ b/crates/handlers/src/preferred_language.rs @@ -18,8 +18,8 @@ use axum::{ async_trait, extract::{FromRef, FromRequestParts}, http::request::Parts, - TypedHeader, }; +use axum_extra::typed_header::TypedHeader; use mas_axum_utils::language_detection::AcceptLanguage; use mas_i18n::{locale, DataLocale, Translator}; diff --git a/crates/handlers/src/test_utils.rs b/crates/handlers/src/test_utils.rs index 7ddc1f7e5..cdead2bb3 100644 --- a/crates/handlers/src/test_utils.rs +++ b/crates/handlers/src/test_utils.rs @@ -60,10 +60,11 @@ use crate::{ ActivityTracker, BoundActivityTracker, }; -// This might fail if it's not the first time it's being called, which is fine, -// so we ignore the result +/// Setup rustcrypto and tracing for tests. #[allow(unused_must_use)] -pub(crate) fn init_tracing() { +pub(crate) fn setup() { + rustls::crypto::aws_lc_rs::default_provider().install_default(); + tracing_subscriber::fmt() .with_max_level(tracing::Level::INFO) .with_test_writer() @@ -230,8 +231,7 @@ impl TestState { pub async fn request(&self, request: Request) -> Response where - B: HttpBody + Send + 'static, - ::Data: Into, + B: HttpBody + Send + 'static, ::Error: std::error::Error + Send + Sync, B::Error: std::error::Error + Send + Sync, B::Data: Send, @@ -242,7 +242,8 @@ impl TestState { .merge(crate::compat_router()) .merge(crate::human_router(self.templates.clone())) .merge(crate::graphql_router(false)) - .with_state(self.clone()); + .with_state(self.clone()) + .into_service(); // Both unwrap are on Infallible, so this is safe let response = app @@ -256,7 +257,7 @@ impl TestState { let (parts, body) = response.into_parts(); // This could actually fail, but do we really care about that? - let body = hyper::body::to_bytes(body) + let body = axum::body::to_bytes(body, usize::MAX) .await .expect("Failed to read response body"); let body = std::str::from_utf8(&body) diff --git a/crates/handlers/src/upstream_oauth2/cache.rs b/crates/handlers/src/upstream_oauth2/cache.rs index cd04260d1..67e547915 100644 --- a/crates/handlers/src/upstream_oauth2/cache.rs +++ b/crates/handlers/src/upstream_oauth2/cache.rs @@ -293,11 +293,11 @@ mod tests { use ulid::Ulid; use super::*; - use crate::test_utils::init_tracing; + use crate::test_utils::setup; #[tokio::test] async fn test_metadata_cache() { - init_tracing(); + setup(); let calls = Arc::new(AtomicUsize::new(0)); let closure_calls = Arc::clone(&calls); let handler = move |req: Request| { @@ -418,7 +418,7 @@ mod tests { #[tokio::test] async fn test_lazy_provider_infos() { - init_tracing(); + setup(); let calls = Arc::new(AtomicUsize::new(0)); let closure_calls = Arc::clone(&calls); let handler = move |req: Request| { diff --git a/crates/handlers/src/upstream_oauth2/link.rs b/crates/handlers/src/upstream_oauth2/link.rs index c51c89a37..34f100f83 100644 --- a/crates/handlers/src/upstream_oauth2/link.rs +++ b/crates/handlers/src/upstream_oauth2/link.rs @@ -15,8 +15,9 @@ use axum::{ extract::{Path, State}, response::{Html, IntoResponse, Response}, - Form, TypedHeader, + Form, }; +use axum_extra::typed_header::TypedHeader; use hyper::StatusCode; use mas_axum_utils::{ cookies::CookieJar, @@ -859,13 +860,11 @@ mod tests { use sqlx::PgPool; use super::UpstreamSessionsCookie; - use crate::test_utils::{ - init_tracing, CookieHelper, RequestBuilderExt, ResponseExt, TestState, - }; + use crate::test_utils::{setup, CookieHelper, RequestBuilderExt, ResponseExt, TestState}; #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_register(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let mut rng = state.rng(); let cookies = CookieHelper::new(); diff --git a/crates/handlers/src/views/login.rs b/crates/handlers/src/views/login.rs index a626a53cd..177253d78 100644 --- a/crates/handlers/src/views/login.rs +++ b/crates/handlers/src/views/login.rs @@ -15,8 +15,8 @@ use axum::{ extract::{Form, Query, State}, response::{Html, IntoResponse, Response}, - TypedHeader, }; +use axum_extra::typed_header::TypedHeader; use hyper::StatusCode; use mas_axum_utils::{ cookies::CookieJar, @@ -319,14 +319,14 @@ mod test { use crate::{ test_utils::{ - init_tracing, test_site_config, CookieHelper, RequestBuilderExt, ResponseExt, TestState, + setup, test_site_config, CookieHelper, RequestBuilderExt, ResponseExt, TestState, }, SiteConfig, }; #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_password_disabled(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool_with_site_config( pool, SiteConfig { @@ -431,7 +431,7 @@ mod test { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_password_login(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let mut rng = state.rng(); let cookies = CookieHelper::new(); diff --git a/crates/handlers/src/views/recovery/start.rs b/crates/handlers/src/views/recovery/start.rs index c8324042c..06091b997 100644 --- a/crates/handlers/src/views/recovery/start.rs +++ b/crates/handlers/src/views/recovery/start.rs @@ -17,8 +17,9 @@ use std::str::FromStr; use axum::{ extract::State, response::{Html, IntoResponse, Response}, - Form, TypedHeader, + Form, }; +use axum_extra::typed_header::TypedHeader; use lettre::Address; use mas_axum_utils::{ cookies::CookieJar, diff --git a/crates/handlers/src/views/register.rs b/crates/handlers/src/views/register.rs index 12371d805..67cb9425f 100644 --- a/crates/handlers/src/views/register.rs +++ b/crates/handlers/src/views/register.rs @@ -17,8 +17,8 @@ use std::str::FromStr; use axum::{ extract::{Form, Query, State}, response::{Html, IntoResponse, Response}, - TypedHeader, }; +use axum_extra::typed_header::TypedHeader; use hyper::StatusCode; use lettre::Address; use mas_axum_utils::{ @@ -335,14 +335,14 @@ mod tests { use crate::{ test_utils::{ - init_tracing, test_site_config, CookieHelper, RequestBuilderExt, ResponseExt, TestState, + setup, test_site_config, CookieHelper, RequestBuilderExt, ResponseExt, TestState, }, SiteConfig, }; #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_password_disabled(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool_with_site_config( pool, SiteConfig { @@ -375,7 +375,7 @@ mod tests { /// Test the registration happy path #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_register(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let cookies = CookieHelper::new(); @@ -425,7 +425,7 @@ mod tests { /// When the two password fields mismatch, it should give an error #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_register_password_mismatch(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let cookies = CookieHelper::new(); @@ -466,7 +466,7 @@ mod tests { #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_register_username_too_short(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let cookies = CookieHelper::new(); @@ -508,7 +508,7 @@ mod tests { /// When the user already exists in the database, it should give an error #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_register_user_exists(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let mut rng = state.rng(); let cookies = CookieHelper::new(); @@ -560,7 +560,7 @@ mod tests { /// an error #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_register_user_reserved(pool: PgPool) { - init_tracing(); + setup(); let state = TestState::from_pool(pool).await.unwrap(); let cookies = CookieHelper::new();