1use std::collections::BTreeMap;
2use std::fmt;
3
4use serde::{Deserialize, Serialize};
5
6#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[serde(transparent)]
13pub struct SecretString(String);
14
15impl SecretString {
16 pub fn new(value: impl Into<String>) -> Self {
18 Self(value.into())
19 }
20
21 pub fn expose_secret(&self) -> &str {
23 &self.0
24 }
25
26 pub fn into_inner(self) -> String {
28 self.0
29 }
30}
31
32impl fmt::Debug for SecretString {
33 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
34 formatter.write_str("SecretString(REDACTED)")
35 }
36}
37
38impl From<String> for SecretString {
39 fn from(value: String) -> Self {
40 Self::new(value)
41 }
42}
43
44impl From<&str> for SecretString {
45 fn from(value: &str) -> Self {
46 Self::new(value)
47 }
48}
49
50impl AsRef<str> for SecretString {
51 fn as_ref(&self) -> &str {
52 self.expose_secret()
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
57#[serde(rename_all = "camelCase")]
58pub struct OidcProviderConfig {
60 pub issuer: String,
62 pub pkce: bool,
64 pub client_id: String,
66 pub client_secret: SecretString,
68 pub discovery_endpoint: String,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub authorization_endpoint: Option<String>,
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub token_endpoint: Option<String>,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub user_info_endpoint: Option<String>,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub jwks_endpoint: Option<String>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub revocation_endpoint: Option<String>,
85 #[serde(skip_serializing_if = "Option::is_none")]
86 pub end_session_endpoint: Option<String>,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub introspection_endpoint: Option<String>,
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub token_endpoint_authentication: Option<TokenEndpointAuthentication>,
94 #[serde(skip_serializing_if = "Option::is_none")]
95 pub scopes: Option<Vec<String>>,
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub mapping: Option<OidcProfileMapping>,
100 pub override_user_info: bool,
102}
103
104pub type OidcConfig = OidcProviderConfig;
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
108#[serde(rename_all = "snake_case")]
109pub enum TokenEndpointAuthentication {
111 ClientSecretBasic,
113 ClientSecretPost,
115}
116
117#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
118#[serde(rename_all = "camelCase")]
119pub struct OidcProfileMapping {
121 pub id: Option<String>,
123 pub email: Option<String>,
125 pub email_verified: Option<String>,
127 pub name: Option<String>,
129 pub image: Option<String>,
131 pub extra_fields: Option<BTreeMap<String, String>>,
133}
134
135pub type OidcMapping = OidcProfileMapping;