Skip to main content

modo/auth/oauth/
config.rs

1use serde::Deserialize;
2
3/// Top-level OAuth configuration, typically loaded from the application YAML config.
4///
5/// Each field corresponds to a provider. Set the field to `None` to disable that provider.
6///
7/// # Example (YAML)
8///
9/// ```yaml
10/// oauth:
11///   google:
12///     client_id: "${GOOGLE_CLIENT_ID}"
13///     client_secret: "${GOOGLE_CLIENT_SECRET}"
14///     redirect_uri: "https://example.com/auth/google/callback"
15///   github:
16///     client_id: "${GITHUB_CLIENT_ID}"
17///     client_secret: "${GITHUB_CLIENT_SECRET}"
18///     redirect_uri: "https://example.com/auth/github/callback"
19/// ```
20#[non_exhaustive]
21#[derive(Debug, Clone, Deserialize, Default)]
22#[serde(default)]
23pub struct OAuthConfig {
24    /// Google OAuth 2.0 provider configuration. `None` disables Google login.
25    pub google: Option<OAuthProviderConfig>,
26    /// GitHub OAuth 2.0 provider configuration. `None` disables GitHub login.
27    pub github: Option<OAuthProviderConfig>,
28}
29
30/// Per-provider OAuth 2.0 credentials and settings.
31#[non_exhaustive]
32#[derive(Debug, Clone, Deserialize)]
33pub struct OAuthProviderConfig {
34    /// OAuth application client ID.
35    pub client_id: String,
36    /// OAuth application client secret.
37    pub client_secret: String,
38    /// Redirect URI registered with the OAuth provider.
39    pub redirect_uri: String,
40    /// Optional list of scopes to request. Falls back to sensible provider defaults when empty.
41    #[serde(default)]
42    pub scopes: Vec<String>,
43}
44
45impl OAuthProviderConfig {
46    /// Create a provider configuration with the given credentials.
47    pub fn new(
48        client_id: impl Into<String>,
49        client_secret: impl Into<String>,
50        redirect_uri: impl Into<String>,
51    ) -> Self {
52        Self {
53            client_id: client_id.into(),
54            client_secret: client_secret.into(),
55            redirect_uri: redirect_uri.into(),
56            scopes: Vec::new(),
57        }
58    }
59}
60
61/// Query parameters delivered by the OAuth provider to the callback route.
62///
63/// Deserialize this from the request query string with axum's `Query<CallbackParams>`.
64#[non_exhaustive]
65#[derive(Debug, Clone, Deserialize)]
66pub struct CallbackParams {
67    /// Authorization code returned by the provider.
68    pub code: String,
69    /// Opaque state value — must match the nonce stored in the OAuth cookie.
70    pub state: String,
71}