use std::fmt;
use jsonwebtoken as jwt;
use serde::Deserialize;
use crate::models;
#[derive(Debug, thiserror::Error)]
pub enum PassageError {
#[error("http error: {0}")]
Reqwest(#[from] reqwest::Error),
#[error("api error: {:?}", .0)]
ApiError(ApiError),
#[error("failed to serializing or deserializing api response: {0}")]
Serde(#[from] serde_json::Error),
#[error("invalid args: {0}")]
InvalidArgument(String),
#[error("failed to authenticate: {0}")]
AuthError(AuthError),
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
pub enum ApiError {
Status400(models::Model400Error),
Status401(models::Model401Error),
Status403(models::Model403Error),
Status404(models::Model404Error),
Status409(models::Model409Error),
Status500(models::Model500Error),
UnknownValue(serde_json::Value),
}
impl From<ApiError> for PassageError {
fn from(e: ApiError) -> Self {
PassageError::ApiError(e)
}
}
#[derive(Debug, PartialEq)]
pub enum AuthError {
TokenHeaderDecoding(jwt::errors::Error),
KidMismatch(Option<String>, Option<String>),
PubKeyMissing,
PubKeyParsing(String),
TokenDecoding(jwt::errors::Error),
}
impl fmt::Display for AuthError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AuthError::TokenHeaderDecoding(e) => {
write!(f, "Failed to decode the header of the Passage JWT: {}", e)
}
AuthError::KidMismatch(kid1, kid2) => write!(
f,
"Key IDs of public JWK and Passage JWT do not match: {} vs {}",
kid1.as_deref().unwrap_or("None"),
kid2.as_deref().unwrap_or("None")
),
AuthError::PubKeyMissing => write!(f, "Public JWK was not provided"),
AuthError::PubKeyParsing(e) => {
write!(f, "Failed to parse the provided public JWK: {}", e)
}
AuthError::TokenDecoding(e) => {
write!(f, "Failed to decode and validate the Passage JWT: {}", e)
}
}
}
}