use std::error::Error;
use std::fmt;
use jsonwebtoken::errors::{Error as JWTError, ErrorKind};
use crate::rest_api::secrets::SecretManagerError;
#[derive(Debug)]
pub enum TokenIssuerError {
EncodingError(Box<dyn Error>),
SecretError(Box<dyn Error>),
}
impl Error for TokenIssuerError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
TokenIssuerError::EncodingError(err) => Some(&**err),
TokenIssuerError::SecretError(err) => Some(&**err),
}
}
}
impl fmt::Display for TokenIssuerError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TokenIssuerError::EncodingError(ref s) => write!(f, "failed to issue token: {}", s),
TokenIssuerError::SecretError(ref s) => write!(f, "failed to fetch secret: {}", s),
}
}
}
impl From<JWTError> for TokenIssuerError {
fn from(err: JWTError) -> TokenIssuerError {
TokenIssuerError::EncodingError(Box::new(err))
}
}
impl From<SecretManagerError> for TokenIssuerError {
fn from(err: SecretManagerError) -> TokenIssuerError {
TokenIssuerError::SecretError(Box::new(err))
}
}
#[derive(Debug)]
pub enum ClaimsBuildError {
MissingRequiredField(String),
InvalidValue(String),
}
impl Error for ClaimsBuildError {}
impl fmt::Display for ClaimsBuildError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ClaimsBuildError::MissingRequiredField(ref s) => {
write!(f, "failed to build claim: {}", s)
}
ClaimsBuildError::InvalidValue(ref s) => write!(f, "failed to build claim: {}", s),
}
}
}
#[derive(Debug)]
pub enum TokenValidationError {
ValidationError(Box<dyn Error>),
InvalidClaim(String),
}
impl Error for TokenValidationError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
TokenValidationError::ValidationError(err) => Some(&**err),
TokenValidationError::InvalidClaim(_) => None,
}
}
}
impl fmt::Display for TokenValidationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TokenValidationError::ValidationError(ref s) => {
write!(f, "failed to validate claim: {}", s)
}
TokenValidationError::InvalidClaim(ref s) => write!(f, "claim is invalid: {}", s),
}
}
}
impl From<JWTError> for TokenValidationError {
fn from(err: JWTError) -> TokenValidationError {
match err.kind() {
ErrorKind::InvalidToken => {
TokenValidationError::InvalidClaim("Token is not valid JWT".to_string())
}
ErrorKind::InvalidSignature => {
TokenValidationError::InvalidClaim("Token signature is not valid".to_string())
}
ErrorKind::InvalidAlgorithmName => {
TokenValidationError::InvalidClaim("Provided algorithm is not valid".to_string())
}
ErrorKind::ExpiredSignature => {
TokenValidationError::InvalidClaim("The token has expired".to_string())
}
ErrorKind::InvalidIssuer => {
TokenValidationError::InvalidClaim("The token has an invalid issuer".to_string())
}
ErrorKind::InvalidAudience => {
TokenValidationError::InvalidClaim("The token has an invalid audience".to_string())
}
ErrorKind::InvalidSubject => {
TokenValidationError::InvalidClaim("The token has an invalid subject".to_string())
}
ErrorKind::ImmatureSignature => {
TokenValidationError::InvalidClaim("The token is not valid yet".to_string())
}
ErrorKind::InvalidAlgorithm => {
TokenValidationError::InvalidClaim("Provided algorithm is not valid".to_string())
}
ErrorKind::InvalidEcdsaKey => TokenValidationError::ValidationError(Box::new(err)),
ErrorKind::InvalidRsaKey => TokenValidationError::ValidationError(Box::new(err)),
_ => TokenValidationError::ValidationError(Box::new(err)),
}
}
}