From a11fc5a0a742954802b8d57cd3a0efaabfe2fbe0 Mon Sep 17 00:00:00 2001 From: Aumetra Weisman Date: Wed, 15 Jan 2025 23:20:45 +0100 Subject: [PATCH] redirect uri mismatch --- lib/komainu/src/code_grant.rs | 10 ++- lib/komainu/tests/{flows.rs => code_grant.rs} | 66 ++++++++----------- ...cess-2.snap => code_grant__success-2.snap} | 2 +- ..._success.snap => code_grant__success.snap} | 2 +- lib/komainu/tests/util.rs | 36 ++++++++++ 5 files changed, 76 insertions(+), 40 deletions(-) rename lib/komainu/tests/{flows.rs => code_grant.rs} (54%) rename lib/komainu/tests/snapshots/{flows__success-2.snap => code_grant__success-2.snap} (80%) rename lib/komainu/tests/snapshots/{flows__success.snap => code_grant__success.snap} (82%) create mode 100644 lib/komainu/tests/util.rs diff --git a/lib/komainu/src/code_grant.rs b/lib/komainu/src/code_grant.rs index 366b556fb..86c40a4e3 100644 --- a/lib/komainu/src/code_grant.rs +++ b/lib/komainu/src/code_grant.rs @@ -2,7 +2,7 @@ use crate::{ error::Error, flow::pkce, params::ParamStorage, scope::Scope, AuthInstruction, Client, ClientExtractor, }; -use std::{borrow::Cow, future::Future, str::FromStr}; +use std::{borrow::Cow, fmt, future::Future, str::FromStr}; use strum::{AsRefStr, Display}; use thiserror::Error; @@ -154,6 +154,14 @@ impl Acceptor { } } +impl fmt::Debug for Acceptor { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct(std::any::type_name::()) + .finish_non_exhaustive() + } +} + pub struct Authorizer<'a, I> { issuer: &'a I, client: Client<'a>, diff --git a/lib/komainu/tests/flows.rs b/lib/komainu/tests/code_grant.rs similarity index 54% rename from lib/komainu/tests/flows.rs rename to lib/komainu/tests/code_grant.rs index 27b17947a..99622fac5 100644 --- a/lib/komainu/tests/flows.rs +++ b/lib/komainu/tests/code_grant.rs @@ -1,49 +1,15 @@ -use self::fixtures::Fixture; +use self::{fixtures::Fixture, util::SerdeResponse}; use bytes::Bytes; use http_body_util::Empty; -use komainu::scope::Scope; -use serde::Serialize; +use komainu::{code_grant::GrantError, scope::Scope}; use std::str::FromStr; mod fixtures; +mod util; #[allow(clippy::unreadable_literal)] const RNG_SEED: u64 = 0xBADD1E; -#[derive(Serialize)] -struct SerdeResponse { - body: Option, - #[serde(with = "http_serde::header_map")] - headers: http::HeaderMap, - #[serde(with = "http_serde::status_code")] - status: http::StatusCode, -} - -impl From> for SerdeResponse { - #[inline] - fn from(value: http::Response<()>) -> Self { - let (parts, _body) = value.into_parts(); - - Self { - body: None, - headers: parts.headers, - status: parts.status, - } - } -} - -impl From> for SerdeResponse { - #[inline] - fn from(value: http::Response) -> Self { - let (parts, body) = value.into_parts(); - let body = String::from_utf8(body.to_vec()).unwrap(); - - let mut response: Self = http::Response::from_parts(parts, ()).into(); - response.body = Some(body); - response - } -} - #[futures_test::test] async fn success() { fastrand::seed(RNG_SEED); @@ -78,3 +44,29 @@ async fn success() { insta::assert_json_snapshot!(SerdeResponse::from(acceptor.into_response())); insta::assert_json_snapshot!(SerdeResponse::from(deny)); } + +#[futures_test::test] +async fn redirect_uri_mismatch() { + fastrand::seed(RNG_SEED); + let fixture = Fixture::generate(); + + let uri = http::Uri::builder() + .scheme("http") + .authority("komainu.example") + .path_and_query("/oauth/authorize?response_type=code&client_id=client_1&redirect_uri=http%3A%2F%2Fbad-redirect-uri.example%2Fhehe") + .build() + .unwrap(); + + let req = http::Request::builder() + .uri(uri) + .body(Empty::::new()) + .unwrap(); + let req = komainu::Request::read_from(req).await.unwrap(); + + let err = match fixture.code_grant.extract_raw(&req).await { + Ok(..) => panic!(), + Err(err) => err, + }; + + assert!(matches!(err, GrantError::AccessDenied)); +} diff --git a/lib/komainu/tests/snapshots/flows__success-2.snap b/lib/komainu/tests/snapshots/code_grant__success-2.snap similarity index 80% rename from lib/komainu/tests/snapshots/flows__success-2.snap rename to lib/komainu/tests/snapshots/code_grant__success-2.snap index 6ac81973b..4c2048b47 100644 --- a/lib/komainu/tests/snapshots/flows__success-2.snap +++ b/lib/komainu/tests/snapshots/code_grant__success-2.snap @@ -1,5 +1,5 @@ --- -source: lib/komainu/tests/flows.rs +source: lib/komainu/tests/code_grant.rs expression: "SerdeResponse::from(deny)" --- { diff --git a/lib/komainu/tests/snapshots/flows__success.snap b/lib/komainu/tests/snapshots/code_grant__success.snap similarity index 82% rename from lib/komainu/tests/snapshots/flows__success.snap rename to lib/komainu/tests/snapshots/code_grant__success.snap index 689e3d056..0d17124c0 100644 --- a/lib/komainu/tests/snapshots/flows__success.snap +++ b/lib/komainu/tests/snapshots/code_grant__success.snap @@ -1,5 +1,5 @@ --- -source: lib/komainu/tests/flows.rs +source: lib/komainu/tests/code_grant.rs expression: "SerdeResponse::from(acceptor.into_response())" --- { diff --git a/lib/komainu/tests/util.rs b/lib/komainu/tests/util.rs new file mode 100644 index 000000000..3240611dd --- /dev/null +++ b/lib/komainu/tests/util.rs @@ -0,0 +1,36 @@ +use bytes::Bytes; +use serde::Serialize; + +#[derive(Serialize)] +pub struct SerdeResponse { + pub body: Option, + #[serde(with = "http_serde::header_map")] + pub headers: http::HeaderMap, + #[serde(with = "http_serde::status_code")] + pub status: http::StatusCode, +} + +impl From> for SerdeResponse { + #[inline] + fn from(value: http::Response<()>) -> Self { + let (parts, _body) = value.into_parts(); + + Self { + body: None, + headers: parts.headers, + status: parts.status, + } + } +} + +impl From> for SerdeResponse { + #[inline] + fn from(value: http::Response) -> Self { + let (parts, body) = value.into_parts(); + let body = String::from_utf8(body.to_vec()).unwrap(); + + let mut response: Self = http::Response::from_parts(parts, ()).into(); + response.body = Some(body); + response + } +}