wekan_cli/command_result/admin/
login_providers.rs1use crate::client::admin::login_providers as wire;
2use serde::Serialize;
3
4#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
5pub struct ConfigSource<T> {
6 pub source: String,
7 pub value: Option<T>,
8}
9
10impl<T, U: From<T>> From<wire::ConfigSource<T>> for ConfigSource<U> {
11 fn from(source: wire::ConfigSource<T>) -> Self {
12 Self {
13 source: source.source,
14 value: source.value.map(Into::into),
15 }
16 }
17}
18
19#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
20#[serde(untagged)]
21pub enum BooleanConfigValue {
22 Text(String),
23 Boolean(bool),
24}
25
26impl From<wire::BooleanConfigValue> for BooleanConfigValue {
27 fn from(value: wire::BooleanConfigValue) -> Self {
28 match value {
29 wire::BooleanConfigValue::Text(value) => Self::Text(value),
30 wire::BooleanConfigValue::Boolean(value) => Self::Boolean(value),
31 }
32 }
33}
34
35#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
36pub struct SecretConfigSource {
37 pub source: String,
38 pub has_value: bool,
39}
40
41impl From<wire::SecretConfigSource> for SecretConfigSource {
42 fn from(source: wire::SecretConfigSource) -> Self {
43 Self {
44 source: source.source,
45 has_value: source.has_value,
46 }
47 }
48}
49
50#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
51pub struct OauthProviderSource {
52 pub enabled: ConfigSource<BooleanConfigValue>,
53 pub id: ConfigSource<String>,
54 pub secret: SecretConfigSource,
55}
56
57impl From<wire::OauthProviderSource> for OauthProviderSource {
58 fn from(provider: wire::OauthProviderSource) -> Self {
59 Self {
60 enabled: provider.enabled.into(),
61 id: provider.id.into(),
62 secret: provider.secret.into(),
63 }
64 }
65}
66
67#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
68pub struct OauthProviderSources {
69 pub google: OauthProviderSource,
70 pub github: OauthProviderSource,
71 pub facebook: OauthProviderSource,
72 pub twitter: OauthProviderSource,
73 #[serde(rename = "meteor-developer")]
74 pub meteor_developer: OauthProviderSource,
75 pub weibo: OauthProviderSource,
76 pub meetup: OauthProviderSource,
77}
78
79impl From<wire::OauthProviderSources> for OauthProviderSources {
80 fn from(providers: wire::OauthProviderSources) -> Self {
81 Self {
82 google: providers.google.into(),
83 github: providers.github.into(),
84 facebook: providers.facebook.into(),
85 twitter: providers.twitter.into(),
86 meteor_developer: providers.meteor_developer.into(),
87 weibo: providers.weibo.into(),
88 meetup: providers.meetup.into(),
89 }
90 }
91}
92
93#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
94pub struct OauthProviderSettings {
95 pub providers: OauthProviderSources,
96 pub login_style: ConfigSource<String>,
97 pub merge_existing_users: ConfigSource<BooleanConfigValue>,
98 pub allowed_email_domains: ConfigSource<String>,
99 pub passwordless: ConfigSource<BooleanConfigValue>,
100}
101
102impl From<wire::OauthProviderSettings> for OauthProviderSettings {
103 fn from(settings: wire::OauthProviderSettings) -> Self {
104 Self {
105 providers: settings.providers.into(),
106 login_style: settings.login_style.into(),
107 merge_existing_users: settings.merge_existing_users.into(),
108 allowed_email_domains: settings.allowed_email_domains.into(),
109 passwordless: settings.passwordless.into(),
110 }
111 }
112}
113
114#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
115pub struct PasswordlessSettings {
116 pub passwordless: ConfigSource<BooleanConfigValue>,
117}
118
119impl From<wire::PasswordlessSettings> for PasswordlessSettings {
120 fn from(settings: wire::PasswordlessSettings) -> Self {
121 Self {
122 passwordless: settings.passwordless.into(),
123 }
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use serde_json::json;
131
132 #[test]
133 fn provider_results_preserve_keys_sources_nulls_and_boolean_representations() {
134 let provider = json!({
135 "enabled":{"source":"env","value":"false"},
136 "id":{"source":"default"},
137 "secret":{"source":"database","hasValue":true}
138 });
139 let providers: serde_json::Map<_, _> = [
140 "google",
141 "github",
142 "facebook",
143 "twitter",
144 "meteor-developer",
145 "weibo",
146 "meetup",
147 ]
148 .into_iter()
149 .map(|key| (key.to_owned(), provider.clone()))
150 .collect();
151 let response: wire::OauthProviderSettings = serde_json::from_value(json!({
152 "providers":providers,
153 "loginStyle":{"source":"database","value":"popup"},
154 "mergeExistingUsers":{"source":"database","value":true},
155 "allowedEmailDomains":{"source":"default","value":null},
156 "passwordless":{"source":"env","value":"true"}
157 }))
158 .unwrap();
159 let stable_provider = json!({
160 "enabled":{"source":"env","value":"false"},
161 "id":{"source":"default","value":null},
162 "secret":{"source":"database","has_value":true}
163 });
164 let stable_providers: serde_json::Map<_, _> = [
165 "google",
166 "github",
167 "facebook",
168 "twitter",
169 "meteor-developer",
170 "weibo",
171 "meetup",
172 ]
173 .into_iter()
174 .map(|key| (key.to_owned(), stable_provider.clone()))
175 .collect();
176 assert_eq!(
177 serde_json::to_value(OauthProviderSettings::from(response)).unwrap(),
178 json!({
179 "providers":stable_providers,
180 "login_style":{"source":"database","value":"popup"},
181 "merge_existing_users":{"source":"database","value":true},
182 "allowed_email_domains":{"source":"default","value":null},
183 "passwordless":{"source":"env","value":"true"}
184 })
185 );
186 for value in [json!(false), json!("false"), json!(null)] {
187 let response: wire::PasswordlessSettings = serde_json::from_value(json!({
188 "passwordless":{"source":"default","value":value}
189 }))
190 .unwrap();
191 assert_eq!(
192 serde_json::to_value(PasswordlessSettings::from(response)).unwrap(),
193 json!({"passwordless":{"source":"default","value":value}})
194 );
195 }
196 }
197}