From 7009f645e601bb87a72e72c6132226d0820282d2 Mon Sep 17 00:00:00 2001 From: cduvray Date: Sat, 14 Jan 2023 09:07:02 +0100 Subject: [PATCH] test: integration tests --- Cargo.lock | 4 +- jwt-authorizer/Cargo.toml | 5 ++- jwt-authorizer/src/tests.rs | 78 ++++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b33c3a4..71f9694 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -708,13 +708,14 @@ dependencies = [ [[package]] name = "jwt-authorizer" -version = "0.3.0" +version = "0.3.1" dependencies = [ "axum", "futures-core", "futures-util", "headers", "http", + "hyper", "jsonwebtoken", "pin-project", "reqwest", @@ -722,6 +723,7 @@ dependencies = [ "serde_json", "thiserror", "tokio", + "tower", "tower-http", "tower-layer", "tower-service", diff --git a/jwt-authorizer/Cargo.toml b/jwt-authorizer/Cargo.toml index 638e520..aef8cc7 100644 --- a/jwt-authorizer/Cargo.toml +++ b/jwt-authorizer/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "jwt-authorizer" description = "jwt authorizer middleware for axum" -version = "0.3.0" +version = "0.3.1" edition = "2021" authors = ["cduvray "] license = "MIT" @@ -16,7 +16,6 @@ futures-core = "0.3.25" headers = "0.3" jsonwebtoken = "8.2.0" http = "0.2.8" -# pin-project-lite = "0.2.9" pin-project = "1.0.12" reqwest = { version = "0.11.13", features = ["json"] } serde = { version = "1.0", features = ["derive"] } @@ -30,4 +29,6 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } [dev-dependencies] +hyper = { version = "0.14", features = ["full"] } +tower = { version = "0.4", features = ["util"] } wiremock = "0.5" \ No newline at end of file diff --git a/jwt-authorizer/src/tests.rs b/jwt-authorizer/src/tests.rs index ec521da..068f750 100644 --- a/jwt-authorizer/src/tests.rs +++ b/jwt-authorizer/src/tests.rs @@ -1 +1,77 @@ -// TODO: tests +#[cfg(test)] +mod tests { + use crate::{JwtClaims, JwtAuthorizer}; + use axum::{ + body::Body, + http::{Request, StatusCode}, + routing::get, Router, + }; + use serde::Deserialize; + use tower::ServiceExt; + + const JWT_RSA_OK: &str = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtleS1yc2EifQ.eyJzdWIiOiJiQGIuY29tIiwiZXhwIjoyMDAwMDAwMDAwfQ.K9QFjvVquRF2-Wt1QRfipOGwiYsmRs7SAwqKskHemFb9BRRZutpfV4oEoHaXMLomTUe8rH0TMjpKcweYK_H1I8D4r-mAN216oUfxCQiFWDB8T2VBI8um-efUg67i2myDZJr5VXdZH8ywj7bn9LyNS4I_xT-J3XvsngeCpuxVSRiYu4FkcUkLrPzbu2sDyBXFqYO9FOorZ8sl0Ninc93fWT2uUrEG8jRyWCa4xpoqbKbm7CN7T2tOKF7mx_xdSPTeSM-U9mUiHsMOrXi1S05IM0hvNJrBduLS6sMTFWrVhis6zqnuxDOirwZS-aN0_SgMDnZTFPsCh8dkqFde1Pv1IYjZfr5OOHjQ9QWj6UDjam6M1eWVPK6QLlxv5bU_gnlAiHm9wJX38-REwmVhIJIBzKxsgJAu1gnRBxe36OM3rkgYxpB86YvfDyOoFlqx8erdxYv38AtvJibe4HB6KLndp_QMm5XXQsbfyEXWGe8hzDwozdhGeQsJXz7PcI3KPlv19PrUM8njElFpOiyfAEXwbtp1EZTzMZ4ZNF6LLFy1fpLcosgyp05o_2YMvngltSnN3v0IPncJx50StdYsoxPN9Ac_nH8VbNlHfmPHMklD1plof0pYf5SiL8yCQP9Uiw9NrN2PeQzbveMKF1T1UNbn2tefxoxr3k6sgWiMH_g_kkk"; + + #[derive(Debug, Deserialize, Clone)] + struct User { + sub: String, + } + + fn app() -> Router { + + let jwt_auth: JwtAuthorizer = JwtAuthorizer::new() + .from_rsa_pem("../config/jwtRS256.key.pub"); + + Router::new() + .route("/public", get(|| async { "hello" })) + .route( + "/protected", + get(|JwtClaims(user): JwtClaims| async move { + format!("hello: {}", user.sub) + }) + .layer(jwt_auth.layer().unwrap()), + ) + } + + #[tokio::test] + async fn protected_without_jwt() { + + let response = app() + .oneshot(Request::builder().uri("/protected").body(Body::empty()).unwrap()) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::FORBIDDEN); + // TODO: check error code (https://datatracker.ietf.org/doc/html/rfc6750#section-3.1) + } + + #[tokio::test] + async fn protected_with_jwt() { + + let response = app() + .oneshot( + Request::builder().uri("/protected").header("Authorization", JWT_RSA_OK).body(Body::empty()).unwrap() + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + + let body = hyper::body::to_bytes(response.into_body()).await.unwrap(); + assert_eq!(&body[..], b"hello: b@b.com"); + } + + #[tokio::test] + async fn protected_with_bad_jwt() { + + let response = app() + .oneshot( + Request::builder().uri("/protected").header("Authorization", "xxx.xxx.xxx").body(Body::empty()).unwrap() + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::FORBIDDEN); + // TODO: check error code (https://datatracker.ietf.org/doc/html/rfc6750#section-3.1) + } + +} \ No newline at end of file