use std::error::Error;
use std::fmt;
use base64::DecodeError;
use pem::PemError;
use serde_json::Error as SerdeError;
#[cfg(not(any(feature = "fips", fips)))]
use jwt_compact::{ParseError, ValidationError};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum JWTError {
AuthorizationHeaderNotPresent,
BearerMalformed,
BearerNotPresent,
ClaimAudValidationFailed,
ClaimAudNotPresent,
ClaimExpValidationFailed,
ClaimExpNotPresent,
ClaimNbValidationFailed,
ClaimNbNotPresent,
EsPublicKeyParseFailed(String),
ExpressionProcessingFailed(String),
InvalidKeyLength(String),
KeyProvisionMissingHeaderHandler,
KidNotPresent,
MandatoryCustomClaimMismatchOrNotPresent,
NonMandatoryCustomClaimMismatch,
RsaPublicKeyParseFailed(String),
SigningAlgorithmParseFailed,
SigningKeyLengthParseFailed,
TokenParseFailed(String),
ValidationFailed(String),
}
#[cfg(test)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum JWTErrorEnumKind {
AuthorizationHeaderNotPresent,
BearerMalformed,
BearerNotPresent,
ClaimAudValidationFailed,
ClaimAudNotPresent,
ClaimExpValidationFailed,
ClaimExpNotPresent,
ClaimNbValidationFailed,
ClaimNbNotPresent,
EsPublicKeyParseFailed,
ExpressionProcessingFailed,
InvalidKeyLength,
KeyProvisionMissingHeaderHandler,
KidNotPresent,
MandatoryCustomClaimMismatchOrNotPresent,
NonMandatoryCustomClaimMismatch,
RsaPublicKeyParseFailed,
SigningAlgorithmParseFailed,
SigningKeyLengthParseFailed,
TokenParseFailed,
ValidationFailed,
}
#[cfg(test)]
impl From<&JWTError> for JWTErrorEnumKind {
fn from(value: &JWTError) -> Self {
match value {
JWTError::AuthorizationHeaderNotPresent => {
JWTErrorEnumKind::AuthorizationHeaderNotPresent
}
JWTError::BearerMalformed => JWTErrorEnumKind::BearerMalformed,
JWTError::BearerNotPresent => JWTErrorEnumKind::BearerNotPresent,
JWTError::ClaimAudValidationFailed => JWTErrorEnumKind::ClaimAudValidationFailed,
JWTError::ClaimAudNotPresent => JWTErrorEnumKind::ClaimAudNotPresent,
JWTError::ClaimExpValidationFailed => JWTErrorEnumKind::ClaimExpValidationFailed,
JWTError::ClaimExpNotPresent => JWTErrorEnumKind::ClaimExpNotPresent,
JWTError::ClaimNbValidationFailed => JWTErrorEnumKind::ClaimNbValidationFailed,
JWTError::ClaimNbNotPresent => JWTErrorEnumKind::ClaimNbNotPresent,
JWTError::EsPublicKeyParseFailed(_) => JWTErrorEnumKind::EsPublicKeyParseFailed,
JWTError::ExpressionProcessingFailed(_) => JWTErrorEnumKind::ExpressionProcessingFailed,
JWTError::InvalidKeyLength(_) => JWTErrorEnumKind::InvalidKeyLength,
JWTError::KeyProvisionMissingHeaderHandler => {
JWTErrorEnumKind::KeyProvisionMissingHeaderHandler
}
JWTError::KidNotPresent => JWTErrorEnumKind::KidNotPresent,
JWTError::MandatoryCustomClaimMismatchOrNotPresent => {
JWTErrorEnumKind::MandatoryCustomClaimMismatchOrNotPresent
}
JWTError::NonMandatoryCustomClaimMismatch => {
JWTErrorEnumKind::NonMandatoryCustomClaimMismatch
}
JWTError::RsaPublicKeyParseFailed(_) => JWTErrorEnumKind::RsaPublicKeyParseFailed,
JWTError::SigningAlgorithmParseFailed => JWTErrorEnumKind::SigningAlgorithmParseFailed,
JWTError::SigningKeyLengthParseFailed => JWTErrorEnumKind::SigningKeyLengthParseFailed,
JWTError::TokenParseFailed(_) => JWTErrorEnumKind::TokenParseFailed,
JWTError::ValidationFailed(_) => JWTErrorEnumKind::ValidationFailed,
}
}
}
impl fmt::Display for JWTError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.get_message())
}
}
impl Error for JWTError {}
impl JWTError {
pub fn get_message(&self) -> &str {
match self {
JWTError::AuthorizationHeaderNotPresent => "JWT Token is required.",
JWTError::BearerMalformed => "Bearer malformed.",
JWTError::BearerNotPresent => "Invalid token. Not a bearer authorization header.",
JWTError::ClaimAudValidationFailed => "Invalid token. Aud claim validation error.",
JWTError::ClaimAudNotPresent => "Invalid token. Aud claim not present.",
JWTError::ClaimExpValidationFailed => "Invalid token. Exp claim validation error.",
JWTError::ClaimExpNotPresent => "Invalid token. Exp claim not present.",
JWTError::ClaimNbValidationFailed => "Invalid token. Nb claim validation error.",
JWTError::ClaimNbNotPresent => "Invalid token. Nb claim not present.",
JWTError::EsPublicKeyParseFailed(message) => message,
JWTError::ExpressionProcessingFailed(message) => message,
JWTError::InvalidKeyLength(message) => message,
JWTError::KeyProvisionMissingHeaderHandler => {
"Expected header handler for key provision."
}
JWTError::KidNotPresent => "Invalid token. Missing 'kid' header.",
JWTError::MandatoryCustomClaimMismatchOrNotPresent => {
"Invalid token. Mandatory custom claim mismatch or not present."
}
JWTError::NonMandatoryCustomClaimMismatch => {
"Invalid token. Non mandatory custom claim mismatch."
}
JWTError::RsaPublicKeyParseFailed(message) => message,
JWTError::TokenParseFailed(message) => message,
JWTError::SigningAlgorithmParseFailed => "Could not parse SigningAlgorithm from str",
JWTError::SigningKeyLengthParseFailed => "Could not parse SigningKeyLength from str",
JWTError::ValidationFailed(message) => message,
}
}
}
#[cfg(not(any(feature = "fips", fips)))]
impl From<ValidationError> for JWTError {
fn from(e: ValidationError) -> Self {
match e {
ValidationError::MalformedClaims(err) => {
JWTError::TokenParseFailed(format!("Token parsing error: {err}"))
}
_ => JWTError::ValidationFailed(format!(
"Invalid token. JWT Policy validation error: {e}"
)),
}
}
}
#[cfg(not(any(feature = "fips", fips)))]
impl From<jwt_simple::Error> for JWTError {
fn from(e: jwt_simple::Error) -> Self {
JWTError::ValidationFailed(format!("JWT Policy validation error: {e}"))
}
}
impl From<PemError> for JWTError {
fn from(e: PemError) -> Self {
JWTError::RsaPublicKeyParseFailed(format!("Public key parsing error: {e}"))
}
}
#[cfg(not(any(feature = "fips", fips)))]
impl From<ParseError> for JWTError {
fn from(e: ParseError) -> Self {
JWTError::TokenParseFailed(format!("Token parsing error: {e}"))
}
}
impl From<DecodeError> for JWTError {
fn from(e: DecodeError) -> Self {
JWTError::TokenParseFailed(format!("Token decoding error: {e}"))
}
}
impl From<SerdeError> for JWTError {
fn from(e: SerdeError) -> Self {
JWTError::TokenParseFailed(format!("Token parsing error: {e}"))
}
}