Skip to main content

openstack_sdk_identity/v4/federation/identity_provider/
set.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5//     http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// SPDX-License-Identifier: Apache-2.0
14//
15// WARNING: This file is automatically generated from OpenAPI schema using
16// `openstack-codegenerator`.
17
18//! Updates the existing identity provider.
19//!
20use 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/// New identity provider data.
32#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
33#[builder(setter(strip_option))]
34pub struct IdentityProvider<'a> {
35    /// The new bound issuer that is verified when using the identity provider.
36    #[serde(skip_serializing_if = "Option::is_none")]
37    #[builder(default, setter(into))]
38    pub(crate) bound_issuer: Option<Option<Cow<'a, str>>>,
39
40    /// New default attribute mapping name which is automatically used when no
41    /// mapping is explicitly requested. The referred attribute mapping must
42    /// exist.
43    #[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    /// Identity provider `enabled` property. Inactive Identity Providers can
48    /// not be used for login.
49    #[serde(skip_serializing_if = "Option::is_none")]
50    #[builder(default, setter(into))]
51    pub(crate) enabled: Option<Option<bool>>,
52
53    /// New URL to fetch JsonWebKeySet. This must be set for "jwt" mapping when
54    /// the provider does not provide discovery endpoint or when it is not
55    /// standard compliant.
56    #[serde(skip_serializing_if = "Option::is_none")]
57    #[builder(default, setter(into))]
58    pub(crate) jwks_url: Option<Option<Cow<'a, str>>>,
59
60    /// The list of the jwt validation public keys.
61    #[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    /// The new name of the federated identity provider.
66    #[serde(skip_serializing_if = "Option::is_none")]
67    #[builder(default, setter(into))]
68    pub(crate) name: Option<Option<Cow<'a, str>>>,
69
70    /// The new oidc `client_id` to use for the private client.
71    #[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    /// The new oidc `client_secret` to use for the private client.
76    #[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    /// The new OIDC discovery endpoint for the identity provider.
81    #[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    /// The new oidc response mode.
86    #[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    /// The new oidc response mode.
91    #[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    /// New additional provider configuration.
96    #[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    /// New additional provider configuration.
103    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    /// New identity provider data.
120    #[builder(setter(into))]
121    pub(crate) identity_provider: IdentityProvider<'a>,
122
123    /// The ID of the identity provider
124    #[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    /// Create a builder for the endpoint.
132    pub fn builder() -> RequestBuilder<'a> {
133        RequestBuilder::default()
134    }
135}
136
137impl<'a> RequestBuilder<'a> {
138    /// Add a single header to the Identity_Provider.
139    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    /// Add multiple headers.
152    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    /// Returns headers to be set into the request
202    fn request_headers(&self) -> Option<&HeaderMap> {
203        self._headers.as_ref()
204    }
205
206    /// Returns required API version
207    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}