From 51f9ad9fbc186d58e998853dce437b0eb95e7c5a Mon Sep 17 00:00:00 2001 From: sd Date: Tue, 25 Jun 2024 10:36:14 +0200 Subject: [PATCH] move helper fn's only used in tests outside of main code --- Cargo.lock | 1 + src/bin/Cargo.toml | 1 + src/bin/tests/common.rs | 39 +++++++++++++++++++- src/bin/tests/zza_handler_cust_attrs.rs | 5 +-- src/common/src/utils.rs | 47 ------------------------- 5 files changed, 43 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5208444e..28a06d29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4121,6 +4121,7 @@ dependencies = [ "rustls 0.23.10", "rustls-pemfile 2.1.2", "rustls-pki-types", + "serde", "serde_json", "spow", "tokio", diff --git a/src/bin/Cargo.toml b/src/bin/Cargo.toml index 3b81e261..bc885088 100644 --- a/src/bin/Cargo.toml +++ b/src/bin/Cargo.toml @@ -47,4 +47,5 @@ josekit = "0.8" pretty_assertions = "1" reqwest = { workspace = true } ring = { workspace = true } +serde = "1" tokio-test = "*" diff --git a/src/bin/tests/common.rs b/src/bin/tests/common.rs index d5d3e4fa..4647af29 100644 --- a/src/bin/tests/common.rs +++ b/src/bin/tests/common.rs @@ -1,7 +1,8 @@ #![allow(dead_code)] use rauthy_api_types::oidc::{LoginRequest, SessionInfoResponse, TokenRequest}; use rauthy_common::constants::CSRF_HEADER; -use rauthy_common::utils::base64_url_encode; +use rauthy_common::utils::{base64_url_encode, base64_url_no_pad_decode}; +use rauthy_error::{ErrorResponse, ErrorResponseType}; use rauthy_service::token_set::TokenSet; use reqwest::header::{HeaderMap, HeaderValue, SET_COOKIE}; use reqwest::{header, Response}; @@ -9,6 +10,7 @@ use ring::digest; use std::env; use std::error::Error; use std::sync::OnceLock; +use tracing::error; #[macro_export] macro_rules! aw { @@ -206,3 +208,38 @@ pub fn code_state_from_headers(res: Response) -> Result<(String, Option) Ok((code, state)) } + +// Extracts the claims from a given token into a HashMap. +// Returns an empty HashMap if no values could be extracted at all. +// CAUTION: Does not validate the token! +pub fn extract_token_claims_unverified(token: &str) -> Result +where + T: for<'a> serde::Deserialize<'a>, +{ + let body = match token.split_once('.') { + None => None, + Some((_metadata, rest)) => rest.split_once('.').map(|(body, _validation_str)| body), + }; + if body.is_none() { + return Err(ErrorResponse::new( + ErrorResponseType::Unauthorized, + "Invalid or malformed JWT Token", + )); + } + let body = body.unwrap(); + let b64 = base64_url_no_pad_decode(body).unwrap(); + + let s = String::from_utf8_lossy(b64.as_slice()); + let claims = match serde_json::from_str::(s.as_ref()) { + Ok(claims) => claims, + Err(err) => { + error!("Error deserializing JWT Token claims: {}", err); + return Err(ErrorResponse::new( + ErrorResponseType::BadRequest, + "Invalid JWT Token claims", + )); + } + }; + + Ok(claims) +} diff --git a/src/bin/tests/zza_handler_cust_attrs.rs b/src/bin/tests/zza_handler_cust_attrs.rs index f833caa0..d13424fd 100644 --- a/src/bin/tests/zza_handler_cust_attrs.rs +++ b/src/bin/tests/zza_handler_cust_attrs.rs @@ -1,4 +1,6 @@ -use crate::common::{get_auth_headers, get_backend_url, get_token_set}; +use crate::common::{ + extract_token_claims_unverified, get_auth_headers, get_backend_url, get_token_set, +}; use rauthy_api_types::clients::{ClientResponse, UpdateClientRequest}; use rauthy_api_types::oidc::JwkKeyPairAlg; use rauthy_api_types::scopes::{ScopeRequest, ScopeResponse}; @@ -6,7 +8,6 @@ use rauthy_api_types::users::{ UserAttrConfigRequest, UserAttrConfigResponse, UserAttrValueRequest, UserAttrValuesResponse, UserAttrValuesUpdateRequest, }; -use rauthy_common::utils::extract_token_claims_unverified; use rauthy_models::entity::user_attr::UserAttrConfigEntity; use rauthy_models::JwtAccessClaims; use serde_json::Value; diff --git a/src/common/src/utils.rs b/src/common/src/utils.rs index f744e709..3f6a8232 100644 --- a/src/common/src/utils.rs +++ b/src/common/src/utils.rs @@ -100,53 +100,6 @@ pub fn new_store_id() -> String { get_rand(24) } -// Extracts the claims from a given token into a HashMap. -// Returns an empty HashMap if no values could be extracted at all. -// CAUTION: Does not validate the token! -pub fn extract_token_claims_unverified(token: &str) -> Result -where - T: for<'a> serde::Deserialize<'a>, -{ - let body = match token.split_once('.') { - None => None, - Some((_metadata, rest)) => rest.split_once('.').map(|(body, _validation_str)| body), - }; - if body.is_none() { - return Err(ErrorResponse::new( - ErrorResponseType::Unauthorized, - "Invalid or malformed JWT Token", - )); - } - let body = body.unwrap(); - - let b64 = match B64_URL_SAFE_NO_PAD.decode(body) { - Ok(values) => values, - Err(err) => { - error!( - "Error decoding JWT token body '{}' from base64: {}", - body, err - ); - return Err(ErrorResponse::new( - ErrorResponseType::BadRequest, - "Invalid JWT Token body", - )); - } - }; - let s = String::from_utf8_lossy(b64.as_slice()); - let claims = match serde_json::from_str::(s.as_ref()) { - Ok(claims) => claims, - Err(err) => { - error!("Error deserializing JWT Token claims: {}", err); - return Err(ErrorResponse::new( - ErrorResponseType::BadRequest, - "Invalid JWT Token claims", - )); - } - }; - - Ok(claims) -} - // TODO unify real_ip_from_req and real_ip_from_svc_req by using an impl Trait #[inline(always)] pub fn real_ip_from_req(req: &HttpRequest) -> Result {