use http::StatusCode;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("missing value for `{0}`")]
MissingField(&'static str),
#[error("invalid value for `{field}`: {message}")]
InvalidValue {
field: &'static str,
message: String,
},
}
#[derive(Debug, Error)]
pub enum TokenStoreError {
#[error("token `{0}` not found")]
NotFound(String),
#[error("token storage failure: {0}")]
Storage(String),
}
#[derive(Debug, Error)]
pub enum OAuthError {
#[error(transparent)]
Config(#[from] ConfigError),
#[error(transparent)]
TokenStore(#[from] TokenStoreError),
#[error("invalid client credentials")]
InvalidClient,
#[error("unsupported grant: {0}")]
UnsupportedGrant(String),
#[error("invalid grant: {0}")]
InvalidGrant(String),
#[error("invalid scope: {0}")]
InvalidScope(String),
#[error("{0} support is not implemented yet")]
NotImplemented(&'static str),
#[error("internal error: {0}")]
Internal(String),
}
impl OAuthError {
pub fn status_code(&self) -> StatusCode {
match self {
OAuthError::Config(_) | OAuthError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
OAuthError::TokenStore(_) => StatusCode::SERVICE_UNAVAILABLE,
OAuthError::InvalidClient => StatusCode::UNAUTHORIZED,
OAuthError::UnsupportedGrant(_) | OAuthError::NotImplemented(_) => {
StatusCode::BAD_REQUEST
}
OAuthError::InvalidGrant(_) | OAuthError::InvalidScope(_) => StatusCode::BAD_REQUEST,
}
}
}
pub type Result<T> = std::result::Result<T, OAuthError>;