From 0f41ca80adad8f522b736e0c055b5a1aecc6ff8d Mon Sep 17 00:00:00 2001 From: senke Date: Wed, 11 Feb 2026 23:24:39 +0100 Subject: [PATCH] refactor(chat): deduplicate JwtManager algorithm/key/validation setup Extract build_keys_and_validation() private helper that encapsulates the 20 lines of algorithm parsing, EncodingKey/DecodingKey creation, and Validation configuration previously duplicated between new() and with_revocation_store_only(). - Remove with_revocation_store_only() intermediate function - with_revocation_store() now calls build_keys_and_validation() directly - with_pool_and_store() delegates to with_revocation_store() Addresses audit finding D10: code duplication in JwtManager constructors. Co-authored-by: Cursor --- veza-chat-server/src/jwt_manager.rs | 46 ++++++++++------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/veza-chat-server/src/jwt_manager.rs b/veza-chat-server/src/jwt_manager.rs index 08304fc48..4abfac919 100644 --- a/veza-chat-server/src/jwt_manager.rs +++ b/veza-chat-server/src/jwt_manager.rs @@ -148,8 +148,11 @@ pub struct JwtManager { } impl JwtManager { - /// Crée un nouveau gestionnaire JWT - pub fn new(config: SecurityConfig) -> Result { + /// Parse algorithm, create keys and validation from config. + /// Shared by all constructors to avoid duplication. + fn build_keys_and_validation( + config: &SecurityConfig, + ) -> Result<(EncodingKey, DecodingKey, Validation)> { let algorithm = match config.jwt_algorithm.as_str() { "HS256" => Algorithm::HS256, "HS384" => Algorithm::HS384, @@ -168,6 +171,14 @@ impl JwtManager { validation.set_issuer(&[&config.jwt_issuer]); validation.set_required_spec_claims(&["exp", "iat", "sub", "aud", "iss", "jti"]); + Ok((encoding_key, decoding_key, validation)) + } + + /// Crée un nouveau gestionnaire JWT + pub fn new(config: SecurityConfig) -> Result { + let (encoding_key, decoding_key, validation) = + Self::build_keys_and_validation(&config)?; + Ok(Self { config, encoding_key, @@ -191,33 +202,8 @@ impl JwtManager { config: SecurityConfig, store: Arc, ) -> Result { - let mut manager = Self::with_revocation_store_only(config, store)?; - manager.db_pool = None; - Ok(manager) - } - - /// Version interne avec store seulement - fn with_revocation_store_only( - config: SecurityConfig, - store: Arc, - ) -> Result { - let algorithm = match config.jwt_algorithm.as_str() { - "HS256" => Algorithm::HS256, - "HS384" => Algorithm::HS384, - "HS512" => Algorithm::HS512, - "RS256" => Algorithm::RS256, - "RS384" => Algorithm::RS384, - "RS512" => Algorithm::RS512, - _ => return Err(ChatError::configuration_error("Algorithme JWT invalide")), - }; - - let encoding_key = EncodingKey::from_secret(config.jwt_secret.as_bytes()); - let decoding_key = DecodingKey::from_secret(config.jwt_secret.as_bytes()); - - let mut validation = Validation::new(algorithm); - validation.set_audience(&[&config.jwt_audience]); - validation.set_issuer(&[&config.jwt_issuer]); - validation.set_required_spec_claims(&["exp", "iat", "sub", "aud", "iss", "jti"]); + let (encoding_key, decoding_key, validation) = + Self::build_keys_and_validation(&config)?; Ok(Self { config, @@ -236,7 +222,7 @@ impl JwtManager { pool: PgPool, store: Arc, ) -> Result { - let mut manager = Self::with_revocation_store_only(config, store)?; + let mut manager = Self::with_revocation_store(config, store)?; manager.db_pool = Some(pool); Ok(manager) }