openstack_sdk_identity/v4/federation/identity_provider/
set.rs1use derive_builder::Builder;
21use http::{HeaderMap, HeaderName, HeaderValue};
22
23use openstack_sdk_core::api::rest_endpoint_prelude::*;
24
25use serde::Deserialize;
26use serde::Serialize;
27use serde_json::Value;
28use std::borrow::Cow;
29use std::collections::BTreeMap;
30
31#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
33#[builder(setter(strip_option))]
34pub struct IdentityProvider<'a> {
35 #[serde(skip_serializing_if = "Option::is_none")]
37 #[builder(default, setter(into))]
38 pub(crate) bound_issuer: Option<Option<Cow<'a, str>>>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
44 #[builder(default, setter(into))]
45 pub(crate) default_mapping_name: Option<Option<Cow<'a, str>>>,
46
47 #[serde(skip_serializing_if = "Option::is_none")]
50 #[builder(default, setter(into))]
51 pub(crate) enabled: Option<Option<bool>>,
52
53 #[serde(skip_serializing_if = "Option::is_none")]
57 #[builder(default, setter(into))]
58 pub(crate) jwks_url: Option<Option<Cow<'a, str>>>,
59
60 #[serde(skip_serializing_if = "Option::is_none")]
62 #[builder(default, setter(into))]
63 pub(crate) jwt_validation_pubkeys: Option<Vec<Cow<'a, str>>>,
64
65 #[serde(skip_serializing_if = "Option::is_none")]
67 #[builder(default, setter(into))]
68 pub(crate) name: Option<Option<Cow<'a, str>>>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
72 #[builder(default, setter(into))]
73 pub(crate) oidc_client_id: Option<Option<Cow<'a, str>>>,
74
75 #[serde(skip_serializing_if = "Option::is_none")]
77 #[builder(default, setter(into))]
78 pub(crate) oidc_client_secret: Option<Option<Cow<'a, str>>>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
82 #[builder(default, setter(into))]
83 pub(crate) oidc_discovery_url: Option<Option<Cow<'a, str>>>,
84
85 #[serde(skip_serializing_if = "Option::is_none")]
87 #[builder(default, setter(into))]
88 pub(crate) oidc_response_mode: Option<Option<Cow<'a, str>>>,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
92 #[builder(default, setter(into))]
93 pub(crate) oidc_response_types: Option<Vec<Cow<'a, str>>>,
94
95 #[serde()]
97 #[builder(private, setter(into, name = "_provider_config"))]
98 pub(crate) provider_config: BTreeMap<Cow<'a, str>, Value>,
99}
100
101impl<'a> IdentityProviderBuilder<'a> {
102 pub fn provider_config<I, K, V>(&mut self, iter: I) -> &mut Self
104 where
105 I: Iterator<Item = (K, V)>,
106 K: Into<Cow<'a, str>>,
107 V: Into<Value>,
108 {
109 self.provider_config
110 .get_or_insert_with(BTreeMap::new)
111 .extend(iter.map(|(k, v)| (k.into(), v.into())));
112 self
113 }
114}
115
116#[derive(Builder, Debug, Clone)]
117#[builder(setter(strip_option))]
118pub struct Request<'a> {
119 #[builder(setter(into))]
121 pub(crate) identity_provider: IdentityProvider<'a>,
122
123 #[builder(default, setter(into))]
125 idp_id: Cow<'a, str>,
126
127 #[builder(setter(name = "_headers"), default, private)]
128 _headers: Option<HeaderMap>,
129}
130impl<'a> Request<'a> {
131 pub fn builder() -> RequestBuilder<'a> {
133 RequestBuilder::default()
134 }
135}
136
137impl<'a> RequestBuilder<'a> {
138 pub fn header<K, V>(&mut self, header_name: K, header_value: V) -> &mut Self
140 where
141 K: Into<HeaderName>,
142 V: Into<HeaderValue>,
143 {
144 self._headers
145 .get_or_insert(None)
146 .get_or_insert_with(HeaderMap::new)
147 .insert(header_name.into(), header_value.into());
148 self
149 }
150
151 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
153 where
154 I: Iterator<Item = T>,
155 T: Into<(Option<HeaderName>, HeaderValue)>,
156 {
157 self._headers
158 .get_or_insert(None)
159 .get_or_insert_with(HeaderMap::new)
160 .extend(iter.map(Into::into));
161 self
162 }
163}
164
165impl RestEndpoint for Request<'_> {
166 fn method(&self) -> http::Method {
167 http::Method::PUT
168 }
169
170 fn endpoint(&self) -> Cow<'static, str> {
171 format!(
172 "federation/identity_providers/{idp_id}",
173 idp_id = self.idp_id.as_ref(),
174 )
175 .into()
176 }
177
178 fn parameters(&self) -> QueryParams<'_> {
179 QueryParams::default()
180 }
181
182 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
183 let mut params = JsonBodyParams::default();
184
185 params.push(
186 "identity_provider",
187 serde_json::to_value(&self.identity_provider)?,
188 );
189
190 params.into_body()
191 }
192
193 fn service_type(&self) -> ServiceType {
194 ServiceType::Identity
195 }
196
197 fn response_key(&self) -> Option<Cow<'static, str>> {
198 Some("identity_provider".into())
199 }
200
201 fn request_headers(&self) -> Option<&HeaderMap> {
203 self._headers.as_ref()
204 }
205
206 fn api_version(&self) -> Option<ApiVersion> {
208 Some(ApiVersion::new(4, 0))
209 }
210}
211
212#[cfg(test)]
213mod tests {
214 use super::*;
215 use http::{HeaderName, HeaderValue};
216 use httpmock::MockServer;
217 #[cfg(feature = "sync")]
218 use openstack_sdk_core::api::Query;
219 use openstack_sdk_core::test::client::FakeOpenStackClient;
220 use openstack_sdk_core::types::ServiceType;
221 use serde_json::json;
222
223 #[test]
224 fn test_service_type() {
225 assert_eq!(
226 Request::builder()
227 .identity_provider(
228 IdentityProviderBuilder::default()
229 .provider_config(BTreeMap::<String, Value>::new().into_iter())
230 .build()
231 .unwrap()
232 )
233 .build()
234 .unwrap()
235 .service_type(),
236 ServiceType::Identity
237 );
238 }
239
240 #[test]
241 fn test_response_key() {
242 assert_eq!(
243 Request::builder()
244 .identity_provider(
245 IdentityProviderBuilder::default()
246 .provider_config(BTreeMap::<String, Value>::new().into_iter())
247 .build()
248 .unwrap()
249 )
250 .build()
251 .unwrap()
252 .response_key()
253 .unwrap(),
254 "identity_provider"
255 );
256 }
257
258 #[cfg(feature = "sync")]
259 #[test]
260 fn endpoint() {
261 let server = MockServer::start();
262 let client = FakeOpenStackClient::new(server.base_url());
263 let mock = server.mock(|when, then| {
264 when.method(httpmock::Method::PUT).path(format!(
265 "/federation/identity_providers/{idp_id}",
266 idp_id = "idp_id",
267 ));
268
269 then.status(200)
270 .header("content-type", "application/json")
271 .json_body(json!({ "identity_provider": {} }));
272 });
273
274 let endpoint = Request::builder()
275 .idp_id("idp_id")
276 .identity_provider(
277 IdentityProviderBuilder::default()
278 .provider_config(BTreeMap::<String, Value>::new().into_iter())
279 .build()
280 .unwrap(),
281 )
282 .build()
283 .unwrap();
284 let _: serde_json::Value = endpoint.query(&client).unwrap();
285 mock.assert();
286 }
287
288 #[cfg(feature = "sync")]
289 #[test]
290 fn endpoint_headers() {
291 let server = MockServer::start();
292 let client = FakeOpenStackClient::new(server.base_url());
293 let mock = server.mock(|when, then| {
294 when.method(httpmock::Method::PUT)
295 .path(format!(
296 "/federation/identity_providers/{idp_id}",
297 idp_id = "idp_id",
298 ))
299 .header("foo", "bar")
300 .header("not_foo", "not_bar");
301 then.status(200)
302 .header("content-type", "application/json")
303 .json_body(json!({ "identity_provider": {} }));
304 });
305
306 let endpoint = Request::builder()
307 .idp_id("idp_id")
308 .identity_provider(
309 IdentityProviderBuilder::default()
310 .provider_config(BTreeMap::<String, Value>::new().into_iter())
311 .build()
312 .unwrap(),
313 )
314 .headers(
315 [(
316 Some(HeaderName::from_static("foo")),
317 HeaderValue::from_static("bar"),
318 )]
319 .into_iter(),
320 )
321 .header(
322 HeaderName::from_static("not_foo"),
323 HeaderValue::from_static("not_bar"),
324 )
325 .build()
326 .unwrap();
327 let _: serde_json::Value = endpoint.query(&client).unwrap();
328 mock.assert();
329 }
330}