loco_oauth2/
error.rs

1use crate::oauth2_grant::OAuth2ClientGrantEnum;
2use oauth2::basic::BasicErrorResponseType;
3use oauth2::{url::ParseError, HttpClientError, RequestTokenError, StandardErrorResponse};
4use reqwest::Error;
5use std::fmt::{Debug, Display};
6
7#[allow(clippy::module_name_repetitions)]
8#[derive(thiserror::Error)]
9pub enum OAuth2StoreError {
10    /// Error for client not found within the store
11    ClientNotFound,
12    /// Error for client already exists but different `OAuth2ClientGrantEnum`
13    ClientTypeMismatch(String, OAuth2ClientGrantEnum),
14    /// Error parsing from configuration JSON to `OAuth2` configuration
15    ConfigJson(#[from] serde_json::Error),
16    /// Error for client creation
17    ClientCreation(#[from] OAuth2ClientError),
18    /// Error for converting key from `[u8]` to `Key`
19    KeyConversion(#[from] cookie::KeyError),
20}
21
22impl OAuth2StoreError {
23    /// Print the error message
24    fn message(&self) -> String {
25        match self {
26            Self::ClientNotFound => "Client not found".to_string(),
27            Self::ClientTypeMismatch(credential_identifier, client) => match client {
28                OAuth2ClientGrantEnum::AuthorizationCode(_) => {
29                    format!("Authorization Code client already exists with credential identifier: {credential_identifier}", )
30                }
31                OAuth2ClientGrantEnum::ClientCredentials => {
32                    format!("Client Credentials client already exists with credential identifier: {credential_identifier}", )
33                }
34                OAuth2ClientGrantEnum::DeviceCode => format!("Device Code client already exists with credential identifier: {credential_identifier}", ),
35                OAuth2ClientGrantEnum::Implicit => format!("Implicit client already exists with credential identifier: {credential_identifier}", ),
36                OAuth2ClientGrantEnum::ResourceOwnerPasswordCredentials => format!(
37                    "Resource Owner Password Credentials client already exists with credential identifier: {credential_identifier}", 
38                ),
39            },
40            Self::ConfigJson(err) => format!("Cannot parse JSON for OAuth2 configuration: {err}", ),
41            Self::ClientCreation(err) => format!("Error creating client: {err}", ),
42            Self::KeyConversion(err) => format!("Error converting key: {err}", ),
43        }
44    }
45}
46
47impl Debug for OAuth2StoreError {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        write!(f, "{}", self.message())
50    }
51}
52impl Display for OAuth2StoreError {
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54        write!(f, "{}", self.message())
55    }
56}
57#[allow(clippy::module_name_repetitions)]
58#[derive(thiserror::Error, Debug)]
59pub enum OAuth2ClientError {
60    #[error(transparent)]
61    UrlError(#[from] ParseError),
62    #[error(transparent)]
63    RequestError(#[from] reqwest::Error),
64    #[error(transparent)]
65    BasicTokenError(#[from] BasicTokenError),
66    #[error("CSRF token error")]
67    CsrfTokenError,
68    #[error("Profile error")]
69    ProfileError(reqwest::Error),
70    #[error("Configuration error")]
71    ConfigError(#[from] oauth2::ConfigurationError),
72}
73
74type BasicTokenError =
75    RequestTokenError<HttpClientError<Error>, StandardErrorResponse<BasicErrorResponseType>>;
76
77pub type OAuth2ClientResult<T> = std::result::Result<T, OAuth2ClientError>;
78pub type OAuth2StoreResult<T> = std::result::Result<T, OAuth2StoreError>;