Skip to main content

swarmhive_api_types/
oauth.rs

1//! OAuth provider configuration DTOs (admin Settings > Authentication) +
2//! the public provider list consumed by the /login page.
3//!
4//! `client_secret` is write-only: requests accept it, responses never echo it
5//! (`OAuthProviderView` exposes only `secret_set: bool`). Same pattern as the
6//! mail provider password.
7
8use chrono::{DateTime, Utc};
9use serde::{Deserialize, Serialize};
10use utoipa::ToSchema;
11use uuid::Uuid;
12
13/// Kind of OAuth provider. MVP ships GitHub only; the enum + server-side
14/// `IdentityProvider` adapter grow together for Google / GitLab / OIDC.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
16#[serde(rename_all = "lowercase")]
17pub enum OAuthProviderKind {
18    Github,
19}
20
21/// Admin CRUD view — full config minus the secret.
22#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
23pub struct OAuthProviderView {
24    pub id: Uuid,
25    pub kind: OAuthProviderKind,
26    pub name: String,
27    pub enabled: bool,
28    pub client_id: String,
29    /// `true` once a client_secret has been stored. The secret itself never
30    /// round-trips through any response.
31    pub secret_set: bool,
32    pub scopes: Vec<String>,
33    pub authorize_url: String,
34    pub token_url: String,
35    pub userinfo_url: String,
36    pub email_field: String,
37    pub created_at: DateTime<Utc>,
38    pub updated_at: DateTime<Utc>,
39}
40
41/// Public list item for the /login sign-in buttons. No secrets, no client_id.
42#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
43pub struct PublicOAuthProvider {
44    pub name: String,
45    pub kind: OAuthProviderKind,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
49pub struct CreateOAuthProviderReq {
50    pub kind: OAuthProviderKind,
51    pub name: String,
52    pub client_id: String,
53    pub client_secret: String,
54    /// Defaults to the GitHub scopes when omitted for `kind=github`.
55    #[serde(default)]
56    pub scopes: Option<Vec<String>>,
57    /// authorize/token/userinfo URLs auto-fill to GitHub defaults when omitted
58    /// for `kind=github`.
59    #[serde(default)]
60    pub authorize_url: Option<String>,
61    #[serde(default)]
62    pub token_url: Option<String>,
63    #[serde(default)]
64    pub userinfo_url: Option<String>,
65    #[serde(default)]
66    pub email_field: Option<String>,
67    #[serde(default)]
68    pub enabled: Option<bool>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
72pub struct UpdateOAuthProviderReq {
73    #[serde(default)]
74    pub name: Option<String>,
75    #[serde(default)]
76    pub client_id: Option<String>,
77    /// Empty / omitted = keep the existing secret (mirrors mail / storage).
78    #[serde(default)]
79    pub client_secret: Option<String>,
80    #[serde(default)]
81    pub scopes: Option<Vec<String>>,
82    #[serde(default)]
83    pub authorize_url: Option<String>,
84    #[serde(default)]
85    pub token_url: Option<String>,
86    #[serde(default)]
87    pub userinfo_url: Option<String>,
88    #[serde(default)]
89    pub email_field: Option<String>,
90    #[serde(default)]
91    pub enabled: Option<bool>,
92}
93
94/// Result of `POST /api/v1/auth/providers/:id/test`. `ok=false` carries a
95/// human-readable reason (mirrors storage `/test`).
96#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
97pub struct OAuthTestResult {
98    pub ok: bool,
99    pub detail: String,
100}