Skip to main content

simple_oauth/
types.rs

1use std::fmt::Debug;
2
3use serde::{Deserialize, Serialize};
4
5/// Redacted field for debug outputs
6const REDACTED: &str = "[redacted]";
7
8/// Type of the internal oauth2 client
9pub(crate) type OAuthClient = oauth2::Client<
10    oauth2::basic::BasicErrorResponse,
11    OAuthTokenResponse,
12    oauth2::basic::BasicTokenIntrospectionResponse,
13    oauth2::StandardRevocableToken,
14    oauth2::basic::BasicRevocationErrorResponse,
15    oauth2::EndpointSet,
16    oauth2::EndpointNotSet,
17    oauth2::EndpointNotSet,
18    oauth2::EndpointNotSet,
19    oauth2::EndpointSet,
20>;
21
22/// Type of the internal oauth2 token response
23pub(crate) type OAuthTokenResponse =
24    oauth2::StandardTokenResponse<OidcExtraTokenFields, oauth2::basic::BasicTokenType>;
25
26/// Struct to extract the ID token if it exists
27#[derive(Clone, Debug, Default, Deserialize, Serialize)]
28pub(crate) struct OidcExtraTokenFields {
29    pub id_token: Option<String>,
30}
31impl oauth2::ExtraTokenFields for OidcExtraTokenFields {}
32
33/// The token auth method (basic auth or request body)
34pub type TokenAuthMethod = oauth2::AuthType;
35
36/// OAuth2 authorization redirect URL, along with the state and PKCE verifier
37#[derive(Clone)]
38pub struct AuthorizeUrl {
39    pub url: oauth2::url::Url,
40    pub state: String,
41    pub pkce_verifier: String,
42}
43impl Debug for AuthorizeUrl {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        f.debug_struct("AuthorizeUrl")
46            .field("url", &REDACTED)
47            .field("state", &self.state)
48            .field("pkce_verifier", &REDACTED)
49            .finish()
50    }
51}
52
53/// Normalized user info returned by the OAuth provider
54#[derive(Debug, Default, Clone)]
55pub struct UserInfo {
56    /// The ID of the user at the OAuth provider
57    pub id: String,
58    /// The user's display name
59    pub name: Option<String>,
60    /// The user's username
61    pub username: Option<String>,
62    /// The user's email. Will likely not be included unless you add the proper email scope for the provider.
63    ///
64    /// ⚠️ Do not rely on this for identifying the user. Use the `id` and the name of the provider.
65    pub email: Option<String>,
66    /// Whether the user's email is verified. Not all providers return this in the user info.
67    pub email_verified: Option<bool>,
68    /// The URL of the user's picture/avatar
69    pub avatar_url: Option<String>,
70    /// The groups the user is a part of. Only included for certain OIDC providers.
71    pub groups: Option<Vec<String>>,
72}
73
74/// Standard OAuth2 token response
75#[derive(Clone)]
76pub struct StandardTokenResponse {
77    /// Access token
78    pub access_token: String,
79    /// Refresh token
80    pub refresh_token: Option<String>,
81    /// ID token ⚠️ The ID token is not validated by this crate. You must manually validate the token.
82    pub id_token: Option<String>,
83    /// The valid duration of the access token
84    pub expires_in: Option<std::time::Duration>,
85}
86impl Debug for StandardTokenResponse {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        f.debug_struct("StandardTokenResponse")
89            .field("access_token", &REDACTED)
90            .field("refresh_token", &REDACTED)
91            .field("id_token", &REDACTED)
92            .field("expires_in", &self.expires_in)
93            .finish()
94    }
95}
96
97/// OAuth2 client ID and secret
98#[derive(Clone)]
99pub struct OAuthCredentials {
100    pub client_id: String,
101    pub client_secret: String,
102}
103impl OAuthCredentials {
104    pub fn new(client_id: impl Into<String>, client_secret: impl Into<String>) -> Self {
105        Self {
106            client_id: client_id.into(),
107            client_secret: client_secret.into(),
108        }
109    }
110}
111impl<S> From<(S, S)> for OAuthCredentials
112where
113    S: Into<String>,
114{
115    fn from((id, secret): (S, S)) -> Self {
116        Self::new(id, secret)
117    }
118}
119impl Debug for OAuthCredentials {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        f.debug_struct("OAuthCredentials")
122            .field("client_id", &self.client_id)
123            .field("client_secret", &REDACTED)
124            .finish()
125    }
126}
127
128/// OIDC discovery document
129#[derive(Debug, Clone, Default, Deserialize)]
130pub struct OidcDiscovery {
131    pub issuer: String,
132    pub authorization_endpoint: String,
133    pub token_endpoint: String,
134    pub userinfo_endpoint: String,
135}
136
137/// Standard OIDC user info shape
138#[derive(Debug, Deserialize)]
139pub(crate) struct OidcUserInfo {
140    pub sub: String,
141    pub name: Option<String>,
142    pub preferred_username: Option<String>,
143    pub email: Option<String>,
144    pub email_verified: Option<bool>,
145    pub picture: Option<String>,
146    pub groups: Option<Vec<String>>,
147}