diff --git a/proxy/src/auth/backend/classic.rs b/proxy/src/auth/backend/classic.rs index de32a06e9e60..6d26c998329c 100644 --- a/proxy/src/auth/backend/classic.rs +++ b/proxy/src/auth/backend/classic.rs @@ -51,7 +51,7 @@ pub(super) async fn authenticate( sasl::Outcome::Success(key) => key, sasl::Outcome::Failure(reason) => { info!("auth backend failed with an error: {reason}"); - return Err(auth::AuthError::auth_failed(&*creds.user)); + return Err(auth::AuthError::password_failed(&*creds.user)); } }; diff --git a/proxy/src/auth/backend/hacks.rs b/proxy/src/auth/backend/hacks.rs index 28bdacd76996..1411d908a5ee 100644 --- a/proxy/src/auth/backend/hacks.rs +++ b/proxy/src/auth/backend/hacks.rs @@ -46,7 +46,7 @@ pub(crate) async fn authenticate_cleartext( sasl::Outcome::Success(key) => key, sasl::Outcome::Failure(reason) => { info!("auth backend failed with an error: {reason}"); - return Err(auth::AuthError::auth_failed(&*info.user)); + return Err(auth::AuthError::password_failed(&*info.user)); } }; diff --git a/proxy/src/auth/backend/mod.rs b/proxy/src/auth/backend/mod.rs index 17334b9cbb8f..0eb68e64123a 100644 --- a/proxy/src/auth/backend/mod.rs +++ b/proxy/src/auth/backend/mod.rs @@ -349,7 +349,7 @@ async fn auth_quirks( { Ok(keys) => Ok(keys), Err(e) => { - if e.is_auth_failed() { + if e.is_password_failed() { // The password could have been changed, so we invalidate the cache. cached_entry.invalidate(); } @@ -376,7 +376,7 @@ async fn authenticate_with_secret( crate::sasl::Outcome::Success(key) => key, crate::sasl::Outcome::Failure(reason) => { info!("auth backend failed with an error: {reason}"); - return Err(auth::AuthError::auth_failed(&*info.user)); + return Err(auth::AuthError::password_failed(&*info.user)); } }; diff --git a/proxy/src/auth/mod.rs b/proxy/src/auth/mod.rs index 7a373dd8251a..2bd7a2da3d29 100644 --- a/proxy/src/auth/mod.rs +++ b/proxy/src/auth/mod.rs @@ -21,6 +21,7 @@ pub(crate) use flow::*; use thiserror::Error; use tokio::time::error::Elapsed; +use crate::auth::backend::jwt::JwtError; use crate::control_plane; use crate::error::{ReportableError, UserFacingError}; @@ -55,7 +56,7 @@ pub(crate) enum AuthError { MissingEndpointName, #[error("password authentication failed for user '{0}'")] - AuthFailed(Box), + PasswordFailed(Box), /// Errors produced by e.g. [`crate::stream::PqStream`]. #[error(transparent)] @@ -76,6 +77,9 @@ pub(crate) enum AuthError { #[error("Disconnected due to inactivity after {0}.")] ConfirmationTimeout(humantime::Duration), + + #[error(transparent)] + Jwt(#[from] JwtError), } impl AuthError { @@ -83,8 +87,8 @@ impl AuthError { AuthError::BadAuthMethod(name.into()) } - pub(crate) fn auth_failed(user: impl Into>) -> Self { - AuthError::AuthFailed(user.into()) + pub(crate) fn password_failed(user: impl Into>) -> Self { + AuthError::PasswordFailed(user.into()) } pub(crate) fn ip_address_not_allowed(ip: IpAddr) -> Self { @@ -95,8 +99,8 @@ impl AuthError { AuthError::TooManyConnections } - pub(crate) fn is_auth_failed(&self) -> bool { - matches!(self, AuthError::AuthFailed(_)) + pub(crate) fn is_password_failed(&self) -> bool { + matches!(self, AuthError::PasswordFailed(_)) } pub(crate) fn user_timeout(elapsed: Elapsed) -> Self { @@ -114,7 +118,7 @@ impl UserFacingError for AuthError { Self::Web(e) => e.to_string_client(), Self::GetAuthInfo(e) => e.to_string_client(), Self::Sasl(e) => e.to_string_client(), - Self::AuthFailed(_) => self.to_string(), + Self::PasswordFailed(_) => self.to_string(), Self::BadAuthMethod(_) => self.to_string(), Self::MalformedPassword(_) => self.to_string(), Self::MissingEndpointName => self.to_string(), @@ -123,6 +127,7 @@ impl UserFacingError for AuthError { Self::TooManyConnections => self.to_string(), Self::UserTimeout(_) => self.to_string(), Self::ConfirmationTimeout(_) => self.to_string(), + Self::Jwt(_) => self.to_string(), } } } @@ -133,7 +138,7 @@ impl ReportableError for AuthError { Self::Web(e) => e.get_error_kind(), Self::GetAuthInfo(e) => e.get_error_kind(), Self::Sasl(e) => e.get_error_kind(), - Self::AuthFailed(_) => crate::error::ErrorKind::User, + Self::PasswordFailed(_) => crate::error::ErrorKind::User, Self::BadAuthMethod(_) => crate::error::ErrorKind::User, Self::MalformedPassword(_) => crate::error::ErrorKind::User, Self::MissingEndpointName => crate::error::ErrorKind::User, @@ -142,6 +147,7 @@ impl ReportableError for AuthError { Self::TooManyConnections => crate::error::ErrorKind::RateLimit, Self::UserTimeout(_) => crate::error::ErrorKind::User, Self::ConfirmationTimeout(_) => crate::error::ErrorKind::User, + Self::Jwt(_) => crate::error::ErrorKind::User, } } } diff --git a/proxy/src/serverless/backend.rs b/proxy/src/serverless/backend.rs index 07e0e3014864..c89e0f0232d8 100644 --- a/proxy/src/serverless/backend.rs +++ b/proxy/src/serverless/backend.rs @@ -81,7 +81,7 @@ impl PoolingBackend { None => { // If we don't have an authentication secret, for the http flow we can just return an error. info!("authentication info not found"); - return Err(AuthError::auth_failed(&*user_info.user)); + return Err(AuthError::password_failed(&*user_info.user)); } }; let ep = EndpointIdInt::from(&user_info.endpoint); @@ -99,7 +99,7 @@ impl PoolingBackend { } crate::sasl::Outcome::Failure(reason) => { info!("auth backend failed with an error: {reason}"); - Err(AuthError::auth_failed(&*user_info.user)) + Err(AuthError::password_failed(&*user_info.user)) } }; res.map(|key| ComputeCredentials { @@ -126,8 +126,7 @@ impl PoolingBackend { &**console, &jwt, ) - .await - .map_err(|e| AuthError::auth_failed(e.to_string()))?; + .await?; Ok(ComputeCredentials { info: user_info.clone(), @@ -146,8 +145,7 @@ impl PoolingBackend { &StaticAuthRules, &jwt, ) - .await - .map_err(|e| AuthError::auth_failed(e.to_string()))?; + .await?; Ok(ComputeCredentials { info: user_info.clone(),