testcontainers_modules/dex/
config.rs

1use serde::Serialize;
2
3use crate::dex::HTTP_PORT;
4
5#[derive(Serialize)]
6pub struct Storage {
7    #[serde(rename = "type")]
8    storage_type: String,
9    config: StorageConfig,
10}
11
12impl Storage {
13    pub fn sqlite() -> Self {
14        Self {
15            storage_type: String::from("sqlite3"),
16            config: StorageConfig {
17                file: String::from("/etc/dex/dex.db"),
18            },
19        }
20    }
21}
22
23#[derive(Serialize)]
24pub struct StorageConfig {
25    file: String,
26}
27
28/// See https://dexidp.io/docs/configuration/
29#[derive(Serialize)]
30pub struct Config {
31    pub issuer: String,
32    pub storage: Storage,
33    pub web: Web,
34    #[serde(rename = "staticClients")]
35    pub static_clients: Vec<PrivateClient>,
36    #[serde(rename = "enablePasswordDB")]
37    pub enable_password_db: bool,
38    #[serde(rename = "staticPasswords")]
39    pub static_passwords: Vec<User>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub oauth2: Option<OAuth2>,
42}
43
44#[derive(Serialize)]
45pub struct Web {
46    pub http: String,
47}
48
49impl Web {
50    pub fn http() -> Self {
51        Self {
52            http: format!(":{HTTP_PORT}"),
53        }
54    }
55}
56
57#[derive(Serialize)]
58pub struct OAuth2 {
59    #[serde(rename = "passwordConnector")]
60    password_connector: String,
61}
62
63impl OAuth2 {
64    pub fn allow_password_grant() -> Self {
65        Self {
66            password_connector: String::from("local"),
67        }
68    }
69}
70
71/// Definition of an OpenID client application.
72#[derive(Serialize, Clone)]
73pub struct PrivateClient {
74    /// Unique identifier of the client.
75    pub id: String,
76    /// Display name of the client
77    pub name: String,
78    /// Allowed redirect
79    #[serde(rename = "redirectURIs")]
80    pub redirect_uris: Vec<String>,
81    /// Cleartext secret that the client application authenticates against Dex with.
82    pub secret: String,
83}
84
85impl PrivateClient {
86    /// Creates a preconfigured client.
87    pub fn simple_client() -> Self {
88        Self {
89            id: String::from("client"),
90            name: String::from("Client"),
91            redirect_uris: vec![String::from("http://localhost/oidc-callback")],
92            secret: String::from("secret"),
93        }
94    }
95}
96
97/// Definition of a user that can authenticate in dex.
98#[derive(Serialize, Clone)]
99pub struct User {
100    /// E-Mail address of the user. This is what the user enters into the login prompt.
101    ///
102    /// You can – i.e. – use example.org to avoid specifying a "real" address here. Dex will *not* send
103    /// e-mails.
104    pub email: String,
105
106    /// Generate the hash of "password" with
107    /// ```sh
108    /// echo password | htpasswd -BinC 10 admin | cut -d: -f2
109    /// ```
110    pub hash: String,
111
112    /// Display name of the user.
113    pub username: String,
114
115    /// Unique identifier (subject/sub) for the user.
116    #[serde(rename = "userID")]
117    pub user_id: String,
118}
119
120impl User {
121    /// Creates a user with the password "user"
122    pub fn simple_user() -> Self {
123        Self {
124            email: String::from("user@example.org"),
125            username: String::from("User"),
126            hash: String::from("$2y$10$l.yOBo5a8m1TnfVuvj/gX.y3vvnHiQs0G59rEwIVU2blgcqkUDLjS"),
127            user_id: String::from("user"),
128        }
129    }
130}