oauth 0.0.2

Universal OAuth 2.0 adapter for Rust web frameworks
Documentation
use http::StatusCode;
use thiserror::Error;

/// Errors encountered while building an [`OAuthConfig`](crate::OAuthConfig).
#[derive(Debug, Error)]
pub enum ConfigError {
    /// A required field was not supplied.
    #[error("missing value for `{0}`")]
    MissingField(&'static str),
    /// A field was supplied but validation failed.
    #[error("invalid value for `{field}`: {message}")]
    InvalidValue {
        /// The field name.
        field: &'static str,
        /// Validation error detail.
        message: String,
    },
}

/// Errors emitted by a [`TokenStore`](crate::TokenStore).
#[derive(Debug, Error)]
pub enum TokenStoreError {
    /// The requested token identifier could not be found.
    #[error("token `{0}` not found")]
    NotFound(String),
    /// Underlying storage failure.
    #[error("token storage failure: {0}")]
    Storage(String),
}

/// Top-level error type surfaced by the crate.
#[derive(Debug, Error)]
pub enum OAuthError {
    /// Propagated configuration error.
    #[error(transparent)]
    Config(#[from] ConfigError),
    /// Propagated token store error.
    #[error(transparent)]
    TokenStore(#[from] TokenStoreError),
    /// Supplied client credentials are invalid.
    #[error("invalid client credentials")]
    InvalidClient,
    /// Unsupported or disabled grant type.
    #[error("unsupported grant: {0}")]
    UnsupportedGrant(String),
    /// Grant validation failure.
    #[error("invalid grant: {0}")]
    InvalidGrant(String),
    /// Scope validation failure.
    #[error("invalid scope: {0}")]
    InvalidScope(String),
    /// Behaviour not yet implemented.
    #[error("{0} support is not implemented yet")]
    NotImplemented(&'static str),
    /// Internal error placeholder.
    #[error("internal error: {0}")]
    Internal(String),
}

impl OAuthError {
    /// Map the error to an HTTP status code suitable for token endpoints.
    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,
        }
    }
}

/// Convenience alias for results returned by crate APIs.
pub type Result<T> = std::result::Result<T, OAuthError>;