use snafu::prelude::*;
use crate::{
TokenType,
error::{ToRfc6750Error, TokenErrorCode, TokenValidationError},
introspection::IntrospectionCallError,
validator::{error::TokenBindingError, extract::TokenExtractError},
};
#[derive(Debug, Snafu)]
#[snafu(visibility(pub(super)))]
#[non_exhaustive]
pub enum IntrospectionValidateError {
#[snafu(display("Token presentation error"))]
Extract {
source: TokenExtractError,
},
#[snafu(display("Token binding error"))]
Binding {
token_type: TokenType,
source: TokenBindingError,
},
#[snafu(display("Introspection call error"))]
Call {
token_type: TokenType,
source: IntrospectionCallError,
},
#[snafu(display(
"Token audience mismatch: expected {expected}, got [{}]",
actual.join(", ")
))]
Audience {
token_type: TokenType,
expected: String,
actual: Vec<String>,
},
}
impl ToRfc6750Error for IntrospectionValidateError {
fn attempted_scheme(&self) -> Option<TokenType> {
match self {
Self::Extract { source } => source.attempted_scheme(),
Self::Binding { token_type, .. }
| Self::Call { token_type, .. }
| Self::Audience { token_type, .. } => Some(*token_type),
}
}
fn token_error(&self) -> TokenValidationError {
match self {
Self::Extract { source } => source.token_error(),
Self::Binding { source, .. } => source.token_error(),
Self::Call { source, .. } => source.token_error(),
Self::Audience { .. } => TokenValidationError::Client(TokenErrorCode::InvalidToken),
}
}
fn error_description(&self) -> Option<String> {
match self {
Self::Extract { source } => source.error_description(),
Self::Binding { source, .. } => source.error_description(),
Self::Call { source, .. } => source.error_description(),
Self::Audience { .. } => {
Some("The access token is not intended for this resource".to_string())
}
}
}
}